1 /* 2 Copyright (c) 2013 yvt 3 4 This file is part of OpenSpades. 5 6 OpenSpades is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 OpenSpades is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with OpenSpades. If not, see <http://www.gnu.org/licenses/>. 18 19 */ 20 21 #include "GLDynamicLightShader.h" 22 #include <Core/Settings.h> 23 #include "GLImage.h" 24 #include "GLProgramManager.h" 25 #include "GLRenderer.h" 26 27 namespace spades { 28 namespace draw { GLDynamicLightShader()29 GLDynamicLightShader::GLDynamicLightShader() 30 : dynamicLightOrigin("dynamicLightOrigin"), 31 dynamicLightColor("dynamicLightColor"), 32 dynamicLightRadius("dynamicLightRadius"), 33 dynamicLightRadiusInversed("dynamicLightRadiusInversed"), 34 dynamicLightSpotMatrix("dynamicLightSpotMatrix"), 35 dynamicLightProjectionTexture("dynamicLightProjectionTexture") 36 37 { 38 lastRenderer = NULL; 39 } 40 41 std::vector<GLShader *> RegisterShader(spades::draw::GLProgramManager * r)42 GLDynamicLightShader::RegisterShader(spades::draw::GLProgramManager *r) { 43 std::vector<GLShader *> shaders; 44 45 shaders.push_back(r->RegisterShader("Shaders/DynamicLight/Common.fs")); 46 shaders.push_back(r->RegisterShader("Shaders/DynamicLight/Common.vs")); 47 48 shaders.push_back(r->RegisterShader("Shaders/DynamicLight/MapNull.fs")); 49 shaders.push_back(r->RegisterShader("Shaders/DynamicLight/MapNull.vs")); 50 51 return shaders; 52 } 53 operator ()(GLRenderer * renderer,spades::draw::GLProgram * program,const GLDynamicLight & light,int texStage)54 int GLDynamicLightShader::operator()(GLRenderer *renderer, spades::draw::GLProgram *program, 55 const GLDynamicLight &light, int texStage) { 56 if (lastRenderer != renderer) { 57 whiteImage = static_cast<GLImage *>(renderer->RegisterImage("Gfx/White.tga")); 58 lastRenderer = renderer; 59 } 60 61 const client::DynamicLightParam ¶m = light.GetParam(); 62 63 IGLDevice *device = renderer->GetGLDevice(); 64 dynamicLightOrigin(program); 65 dynamicLightColor(program); 66 dynamicLightRadius(program); 67 dynamicLightRadiusInversed(program); 68 dynamicLightSpotMatrix(program); 69 dynamicLightProjectionTexture(program); 70 71 dynamicLightOrigin.SetValue(param.origin.x, param.origin.y, param.origin.z); 72 dynamicLightColor.SetValue(param.color.x, param.color.y, param.color.z); 73 dynamicLightRadius.SetValue(param.radius); 74 dynamicLightRadiusInversed.SetValue(1.f / param.radius); 75 76 if (param.type == client::DynamicLightTypeSpotlight) { 77 device->ActiveTexture(texStage); 78 static_cast<GLImage *>(param.image)->Bind(IGLDevice::Texture2D); 79 dynamicLightProjectionTexture.SetValue(texStage); 80 texStage++; 81 82 dynamicLightSpotMatrix.SetValue(light.GetProjectionMatrix()); 83 84 // bad hack to make texture clamped to edge 85 device->TexParamater(IGLDevice::Texture2D, IGLDevice::TextureWrapS, 86 IGLDevice::ClampToEdge); 87 device->TexParamater(IGLDevice::Texture2D, IGLDevice::TextureWrapT, 88 IGLDevice::ClampToEdge); 89 90 } else { 91 device->ActiveTexture(texStage); 92 whiteImage->Bind(IGLDevice::Texture2D); 93 dynamicLightProjectionTexture.SetValue(texStage); 94 texStage++; 95 96 dynamicLightSpotMatrix.SetValue(Matrix4::Identity()); 97 } 98 99 device->ActiveTexture(texStage); 100 101 return texStage; 102 } 103 Cull(const GLDynamicLight & light,const spades::AABB3 & box)104 bool GLDynamicLightShader::Cull(const GLDynamicLight &light, const spades::AABB3 &box) { 105 // TOOD: more tighter check? 106 // TODO: spotlight check? 107 // TODO: move this function to GLDynamicLight? 108 const client::DynamicLightParam ¶m = light.GetParam(); 109 return box.Inflate(param.radius) && param.origin; 110 } 111 SphereCull(const GLDynamicLight & light,const spades::Vector3 & center,float radius)112 bool GLDynamicLightShader::SphereCull(const GLDynamicLight &light, 113 const spades::Vector3 ¢er, float radius) { 114 const client::DynamicLightParam ¶m = light.GetParam(); 115 float maxDistance = radius + param.radius; 116 return (center - param.origin).GetPoweredLength() < maxDistance * maxDistance; 117 } 118 } 119 } 120