00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdlib.h>
00018 #include <GL/glut.h>
00019 #include <wx/stopwatch.h>
00020 #include "RenderGlModule.h"
00021 #include "scene.h"
00022 #include "camera.h"
00023
00024 using namespace VRUT;
00025
00026 const GLenum LIGHTID[] = { GL_LIGHT1, GL_LIGHT2, GL_LIGHT3, GL_LIGHT4, GL_LIGHT5, GL_LIGHT6, GL_LIGHT7 };
00027
00028 RenderGlModule::RenderGlModule(MODULE_ID _id, const wxString & _name, EventHandler * msgSink)
00029 : RenderModule(_id, _name, 0, msgSink),
00030 scene((Scene *)NULL)
00031 {
00032 wxASSERT_MSG(paramsMutex.IsOk(), wxT("<RenderGlModule>Failed to create mutex"));
00033 useVBO = false;
00034 REGISTER_PARAM_GUI_CHECKBOX(useVBOParamID, wxT("useVBO"), wxT("0"), wxT("Use VBO instead of display lists."));
00035 wireframe = false;
00036 REGISTER_PARAM_GUI_CHECKBOX(wireframeParamID, wxT("wireframe"), wxT("0"), wxT("Display scene in wireframe."));
00037 lighting = true;
00038 REGISTER_PARAM_GUI_CHECKBOX(lightingParamID, wxT("lighting"), wxT("1"), wxT("Enable lighting."));
00039 headlight = true;
00040 REGISTER_PARAM_GUI_CHECKBOX(headlightParamID, wxT("headlight"), wxT("1"), wxT("Enable headlight."));
00041 drawBVH = false;
00042 REGISTER_PARAM_GUI_CHECKBOX(drawBVHParamID, wxT("drawBVH"), wxT("0"), wxT("Draw BVH into the model"));
00043 allowRedundantDeletes = true;
00044 REGISTER_PARAM_GUI_CHECKBOX(allowRedundantDeletesParamID, wxT("allowRedundantDeletes"), wxT("1"), wxT("Allow redundant deletes when importing scene."));
00045
00046 initialized = vboSupported = shaderSupported = sceneInitialized
00047 = sceneImportMode = reset = vboRenderUpdated = false;
00048 texturesUsedLast = 0;
00049 glGenBuffersARB = NULL;
00050 glBindBufferARB = NULL;
00051 glBufferDataARB = NULL;
00052 glDeleteBuffersARB = NULL;
00053 glCreateProgramObjectARB = NULL;
00054 glCreateShaderObjectARB = NULL;
00055 glShaderSourceARB = NULL;
00056 glCompileShaderARB = NULL;
00057 glAttachObjectARB = NULL;
00058 glLinkProgramARB = NULL;
00059 glUseProgramObjectARB = NULL;
00060 glDeleteObjectARB = NULL;
00061 glGetInfoLogARB = NULL;
00062 glGetObjectParameterivARB = NULL;
00063 glGetUniformLocationARB = NULL;
00064 glUniform1fvARB = NULL;
00065 glUniform2fvARB = NULL;
00066 glUniform3fvARB = NULL;
00067 glUniform4fvARB = NULL;
00068 glUniform1ivARB = NULL;
00069 glUniform2ivARB = NULL;
00070 glUniform3ivARB = NULL;
00071 glUniform4ivARB = NULL;
00072 glUniformMatrix2fvARB = NULL;
00073 glUniformMatrix3fvARB = NULL;
00074 glUniformMatrix4fvARB = NULL;
00075 glActiveTexture = NULL;
00076 glUniform1iARB = NULL;
00078 REGISTER_LISTENER(Event::EVT_SCENE_NODE_INSERTED);
00079 REGISTER_LISTENER(Event::EVT_SCENE_NODE_REMOVED);
00080 REGISTER_LISTENER(Event::EVT_SCENE_NODE_MATERIAL_CHANGED);
00081 REGISTER_LISTENER(Event::EVT_SCENE_NODE_GEOMETRY_CHANGED);
00082 REGISTER_LISTENER(Event::EVT_RENDER_CACHE_START);
00083 REGISTER_LISTENER(Event::EVT_RENDER_CACHE_STOP);
00084 }
00085
00086
00087 RenderGlModule::~RenderGlModule()
00088 {
00089 Deinitialize();
00090 }
00091
00092
00093 void RenderGlModule::clearCachedGeometry()
00094 {
00095 for (GLIDList::iterator it = dispListIDs.begin();
00096 it != dispListIDs.end(); it++)
00097 {
00098 if (*it != GL_ID_NONE)
00099 {
00100 glDeleteLists(*it, 1);
00101 *it = GL_ID_NONE;
00102 }
00103 }
00104 dispListIDs.clear();
00105 VBOIDs.clear();
00106 textureIDs.clear();
00107
00108 for (VBOIDMap::iterator it = vboIDMap.begin();
00109 it != vboIDMap.end(); it++)
00110 {
00111 if (it->second.verticesID != GL_ID_NONE)
00112 glDeleteBuffersARB(1, &it->second.verticesID);
00113 if (it->second.indicesID != GL_ID_NONE)
00114 glDeleteBuffersARB(1, &it->second.indicesID);
00115 if (it->second.normalsID != GL_ID_NONE)
00116 glDeleteBuffersARB(1, &it->second.normalsID);
00117 if (it->second.texCoordsID != GL_ID_NONE)
00118 glDeleteBuffersARB(1, &it->second.texCoordsID);
00119 }
00120 vboIDMap.clear();
00121
00122 for (TextureIDMap::iterator it = textureIDMap.begin();
00123 it != textureIDMap.end(); it++)
00124 {
00125 if (it->second != GL_ID_NONE)
00126 glDeleteTextures(1, &(it->second));
00127 }
00128 textureIDMap.clear();
00129
00130 for (ShaderIDMap::iterator it = shaderIDMap.begin();
00131 it != shaderIDMap.end(); it++)
00132 {
00133 ShaderHandler * handler = &it->second;
00134 if (handler->program != GL_ID_NONE)
00135 glDeleteObjectARB(handler->program);
00136 if (handler->fragmentShader != GL_ID_NONE)
00137 glDeleteObjectARB(handler->fragmentShader);
00138 if (handler->vertexShader != GL_ID_NONE)
00139 glDeleteObjectARB(handler->vertexShader);
00140 for (std::vector<ShaderParamID>::iterator parIt = handler->paramList.begin();
00141 parIt != handler->paramList.end(); parIt++)
00142 {
00143 if (parIt->textureID != GL_ID_NONE)
00144 glDeleteTextures(1, &parIt->textureID);
00145 }
00146 }
00147 shaderIDMap.clear();
00148 sceneInitialized = false;
00149 }
00150
00151
00152 void RenderGlModule::checkExtSupport()
00153 {
00154 if (!glGenBuffersARB)
00155 glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) GLGETPROC("glGenBuffersARB");
00156 if (!glBindBufferARB)
00157 glBindBufferARB = (PFNGLBINDBUFFERARBPROC) GLGETPROC("glBindBufferARB");
00158 if (!glBufferDataARB)
00159 glBufferDataARB = (PFNGLBUFFERDATAARBPROC) GLGETPROC("glBufferDataARB");
00160 if (!glDeleteBuffersARB)
00161 glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) GLGETPROC("glDeleteBuffersARB");
00162 if (!glCreateProgramObjectARB)
00163 glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLGETPROC("glCreateProgramObjectARB");
00164 if (!glCreateShaderObjectARB)
00165 glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLGETPROC("glCreateShaderObjectARB");
00166 if (!glShaderSourceARB)
00167 glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLGETPROC("glShaderSourceARB");
00168 if (!glCompileShaderARB)
00169 glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLGETPROC("glCompileShaderARB");
00170 if (!glAttachObjectARB)
00171 glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLGETPROC("glAttachObjectARB");
00172 if (!glLinkProgramARB)
00173 glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLGETPROC("glLinkProgramARB");
00174 if (!glUseProgramObjectARB)
00175 glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GLGETPROC("glUseProgramObjectARB");
00176 if (!glDeleteObjectARB)
00177 glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLGETPROC("glDeleteObjectARB");
00178 if (!glGetInfoLogARB)
00179 glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) GLGETPROC("glGetInfoLogARB");
00180 if (!glGetObjectParameterivARB)
00181 glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLGETPROC("glGetObjectParameterivARB");
00182 if (!glGetUniformLocationARB)
00183 glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLGETPROC("glGetUniformLocationARB");
00184 if (!glUniform1fvARB)
00185 glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLGETPROC("glUniform1fvARB");
00186 if (!glUniform2fvARB)
00187 glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLGETPROC("glUniform2fvARB");
00188 if (!glUniform3fvARB)
00189 glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLGETPROC("glUniform3fvARB");
00190 if (!glUniform4fvARB)
00191 glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLGETPROC("glUniform4fvARB");
00192 if (!glUniform1ivARB)
00193 glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLGETPROC("glUniform1ivARB");
00194 if (!glUniform2ivARB)
00195 glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLGETPROC("glUniform2ivARB");
00196 if (!glUniform3ivARB)
00197 glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLGETPROC("glUniform3ivARB");
00198 if (!glUniform4ivARB)
00199 glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLGETPROC("glUniform4ivARB");
00200 if (!glUniformMatrix2fvARB)
00201 glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLGETPROC("glUniformMatrix2fvARB");
00202 if (!glUniformMatrix3fvARB)
00203 glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLGETPROC("glUniformMatrix3fvARB");
00204 if (!glUniformMatrix4fvARB)
00205 glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLGETPROC("glUniformMatrix4fvARB");
00206 if (!glActiveTexture)
00207 glActiveTexture = (PFNGLACTIVETEXTUREPROC) GLGETPROC("glActiveTexture");
00208 if (!glUniform1iARB)
00209 glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLGETPROC("glUniform1iARB");
00210
00211 if ( ( glGenBuffersARB != NULL ) &&
00212 ( glBindBufferARB != NULL ) &&
00213 ( glBufferDataARB != NULL ) &&
00214 ( glDeleteBuffersARB != NULL ) &&
00215 IsExtensionSupported("GL_ARB_vertex_buffer_object") )
00216 {
00217 vboSupported = true;
00218 LOG(wxT("<RenderGlModule>VBO supported"));
00219 }
00220 else
00221 {
00222 useVBO = vboSupported = false;
00223 LOGWARNING(wxT("<RenderGlModule>VBO not supported, switching to display lists"));
00224 }
00225
00226 if (IsExtensionSupported("GL_ARB_shader_objects") &&
00227 IsExtensionSupported("GL_ARB_shading_language_100") &&
00228 IsExtensionSupported("GL_ARB_vertex_shader") &&
00229 IsExtensionSupported("GL_ARB_fragment_shader") &&
00230 (glCreateProgramObjectARB != NULL) &&
00231 (glCreateShaderObjectARB != NULL) &&
00232 (glShaderSourceARB != NULL) &&
00233 (glCompileShaderARB != NULL) &&
00234 (glAttachObjectARB != NULL) &&
00235 (glLinkProgramARB != NULL) &&
00236 (glUseProgramObjectARB != NULL) &&
00237 (glDeleteObjectARB != NULL) &&
00238 (glGetInfoLogARB != NULL) )
00239 {
00240 shaderSupported = true;
00241 LOG(wxT("<RenderGlModule>Shaders supported"));
00242 }
00243 else
00244 {
00245 shaderSupported = false;
00246 LOGWARNING(wxT("<RenderGlModule>Shaders not supported"));
00247 }
00248
00249 if (glActiveTexture == NULL)
00250 LOGWARNING(wxT("<RenderGlModule>Multiple textures not supported"));
00251 }
00252
00253
00254 void RenderGlModule::drawShader(const GeometryNode * node)
00255 {
00256 if (!shaderSupported)
00257 return;
00258
00259 const Material * material = scene->GetMaterial(node->GetMaterialID());
00260 if (material && material->shader && (material->shader->type==ShaderProgram::LANG_GLSL))
00261 {
00262 ShaderIDMap::const_iterator shdIt = shaderIDMap.find(material->name);
00263 if (shdIt != shaderIDMap.end())
00264 glUseProgramObjectARB(shdIt->second.program);
00265 else
00266 {
00267 ShaderHandler handler;
00268 const ShaderProgram * shader = material->shader;
00269
00270 handler.program = glCreateProgramObjectARB();
00271 handler.fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
00272 handler.vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
00273
00274
00275 wxCharBuffer buff = shader->fsSource.ToAscii();
00276 const char * fss = buff.data();
00277 wxCharBuffer buff2 = shader->vsSource.ToAscii();
00278 const char * vss = buff2.data();
00279 glShaderSourceARB(handler.fragmentShader, 1, (const GLcharARB **)(&fss), NULL);
00280 glShaderSourceARB(handler.vertexShader, 1, (const GLcharARB **)(&vss), NULL);
00281
00282 glCompileShaderARB(handler.fragmentShader);
00283 glCompileShaderARB(handler.vertexShader);
00284
00285 glAttachObjectARB(handler.program, handler.fragmentShader);
00286 glAttachObjectARB(handler.program, handler.vertexShader);
00287
00288 glLinkProgramARB(handler.program);
00289 glUseProgramObjectARB(handler.program);
00290
00292 int infoLogLength = 0;
00293 glGetObjectParameterivARB(handler.program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infoLogLength);
00294 char * buffer = new char[infoLogLength];
00295 glGetInfoLogARB(handler.program, infoLogLength, 0, buffer);
00296 wxString info(buffer, wxConvUTF8);
00297 delete [] buffer;
00298 LOG(wxT("<RenderGlModule>Shader program message:\n") + info);
00299
00301 for (std::vector<ShaderParam>::const_iterator it = shader->paramList.begin();
00302 it != shader->paramList.end(); it++)
00303 {
00304 ShaderParamID param;
00305 param.paramLocation = glGetUniformLocationARB(handler.program, it->name.ToAscii());
00306 if (!it->imageName.IsEmpty())
00307 {
00308 const Image * image = scene->GetImage(it->imageName);
00309 if (image)
00310 param.textureID = image->BuildOglTexture();
00311 }
00312 handler.paramList.push_back(param);
00313 }
00314
00316
00317 texturesUsedLast = 0;
00318 glUseProgramObjectARB(handler.program);
00319 GLuint samplerID = 0;
00320 for (size_t pID = 0; pID < handler.paramList.size(); pID++)
00321 {
00322 const ShaderParam * param = &shader->paramList[pID];
00323 const ShaderParamID * paramID = &handler.paramList[pID];
00324 switch (param->type)
00325 {
00326 case ShaderParam::FLOAT1:
00327 glUniform1fvARB(paramID->paramLocation, 1, param->fVals);
00328 break;
00329 case ShaderParam::FLOAT2:
00330 glUniform2fvARB(paramID->paramLocation, 1, param->fVals);
00331 break;
00332 case ShaderParam::FLOAT3:
00333 glUniform3fvARB(paramID->paramLocation, 1, param->fVals);
00334 break;
00335 case ShaderParam::FLOAT4:
00336 glUniform4fvARB(paramID->paramLocation, 1, param->fVals);
00337 break;
00338 case ShaderParam::SAMPLER:
00339 if (glActiveTexture != NULL)
00340 {
00341 glActiveTexture(GL_TEXTURE0 + samplerID);
00342 glBindTexture(GL_TEXTURE_2D, paramID->textureID);
00343 glUniform1iARB(paramID->paramLocation, samplerID++);
00344 texturesUsedLast++;
00345 }
00346 break;
00347 }
00348 }
00349
00350 ShaderIDMap::Insert_Result res = shaderIDMap.insert(ShaderIDMap::value_type(material->name, handler));
00351 if (!res.second)
00352 LOGERROR(wxString::Format(wxT("<RenderGlModule>Failed to insert shader handler '%s' to hashmap"), material->name.c_str()));
00353 }
00354 }
00355 else
00356 glUseProgramObjectARB(0);
00357 }
00358
00359
00360 void RenderGlModule::drawLights() const
00361 {
00362 unsigned lID = 0;
00363 const Scene::LightNodeIDList * lights = scene->GetLightIDs();
00364 for (Scene::LightNodeIDList::const_iterator lightIt = lights->begin();
00365 (lID < 7) && (lightIt != lights->end());
00366 lightIt++, lID++)
00367 {
00368 const LightNode * lightNode = (const LightNode *)scene->GetNode(*lightIt);
00369 if (lightNode && lightNode->GetLight())
00370 {
00371 const Light * light = lightNode->GetLight();
00372 glLightfv(LIGHTID[lID], GL_DIFFUSE, light->diffuse._v);
00373
00374 scene->UpdateTransformation(*lightIt);
00375 glPushMatrix();
00376 glMultMatrixf(lightNode->GetWorldTransMatrix()->_m);
00377 if (light->type == Light::OMNI)
00378 {
00379 GLfloat lpos[4] = { light->position.x, light->position.y, light->position.z, 1 };
00380 glLightfv(LIGHTID[lID], GL_POSITION, lpos);
00381 glEnable(LIGHTID[lID]);
00382 }
00383 else if (light->type == Light::DIRECTIONAL)
00384 {
00385 GLfloat lpos[4] = { light->direction.x, light->direction.y, light->direction.z, 0 };
00386 glLightfv(LIGHTID[lID], GL_POSITION, lpos);
00387 glEnable(LIGHTID[lID]);
00388 }
00389 else if (light->type == Light::SPOTLIGHT)
00390 {
00391 GLfloat lpos[4] = { light->position.x, light->position.y, light->position.z, 1 };
00392 glLightfv(LIGHTID[lID], GL_POSITION, lpos);
00393 glLightfv(LIGHTID[lID], GL_SPOT_DIRECTION, light->direction._v);
00394 glLightf(LIGHTID[lID], GL_SPOT_EXPONENT, light->exponent);
00395 glLightf(LIGHTID[lID], GL_SPOT_CUTOFF, light->angle);
00396 glEnable(LIGHTID[lID]);
00397 }
00398 else
00399 LOGWARNING(wxString::Format(wxT("<RenderGlModule>Light node '%s' has invalid light type"), lightNode->GetName().c_str()));
00400 glPopMatrix();
00401 }
00402 else
00403 glDisable(LIGHTID[lID]);
00404 }
00405 }
00406
00407
00408 void RenderGlModule::drawMaterial(const GeometryNode * node)
00409 {
00410 const Material * material = scene->GetMaterial(node->GetMaterialID());
00411 bool tex = false;
00412 if (material)
00413 {
00414 unsigned texFlags = material->texFlags;
00415 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse._v);
00416 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient._v);
00417 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, material->emission._v);
00418 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material->specular._v);
00419 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material->shininess);
00420 if (!lighting)
00421 glColor3fv(material->diffuse._v);
00422
00423 if (!material->imageName.IsEmpty() && node->GetID() < textureIDs.size())
00424 {
00425 tex = true;
00426 if (glActiveTexture != NULL)
00427 {
00428 for (size_t texUsed = 1; texUsed < texturesUsedLast; texUsed++)
00429 {
00430 glActiveTexture(GLenum(GL_TEXTURE0 + texUsed));
00431 glBindTexture(GL_TEXTURE_2D, 0);
00432 }
00433 texturesUsedLast = 0;
00434 glActiveTexture(GL_TEXTURE0);
00435 }
00436 glBindTexture( GL_TEXTURE_2D, textureIDs[node->GetID()] );
00437 if (texFlags & Material::TEX_GEN_ENABLED)
00438 {
00439 glEnable(GL_TEXTURE_GEN_S);
00440 glEnable(GL_TEXTURE_GEN_T);
00441 }
00442 else
00443 {
00444 glDisable(GL_TEXTURE_GEN_S);
00445 glDisable(GL_TEXTURE_GEN_T);
00446 }
00447
00448 if (material->flags & Material::BLENDED)
00449 {
00450 if (material->texBlendSrc != GL_ID_NONE && material->texBlendDst != GL_ID_NONE)
00451
00452 glBlendFunc(material->texBlendSrc, material->texBlendDst);
00453 }
00454
00455 if (texFlags & Material::TEX_ENV_REPLACE)
00456 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00457 else if (texFlags & Material::TEX_ENV_DECAL)
00458 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
00459 else if (texFlags & Material::TEX_ENV_BLEND)
00460 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
00461 else if (texFlags & Material::TEX_ENV_ADD)
00462 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
00463 else
00464 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00465 }
00466 }
00467 else
00468 {
00470 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, VECTOR4(1,1,1,1)._v);
00471 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, VECTOR4(0,0,0,0)._v);
00472 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, VECTOR4(0,0,0,0)._v);
00473 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, VECTOR4(1,1,1,1)._v);
00474 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 1);
00475 if (!lighting)
00476 glColor3fv(VECTOR4(1,1,1,1)._v);
00477 }
00478
00479 if (tex)
00480 glEnable(GL_TEXTURE_2D);
00481 else
00482 glDisable(GL_TEXTURE_2D);
00483
00484 if ( lighting && (!material || (material->flags & Material::UNLIT) == 0) )
00485 {
00486 glEnable(GL_LIGHTING);
00487
00488 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00489
00490
00491 }
00492 else
00493 glDisable(GL_LIGHTING);
00494 }
00495
00496
00497 void RenderGlModule::buildTexture(const GeometryNode * node)
00498 {
00499 unsigned id = node->GetID();
00500 if (id >= textureIDs.size() || textureIDs[id] == GL_ID_NONE)
00501 {
00502 const Material * material = scene->GetMaterial(node->GetMaterialID());
00503 if (!material || material->imageName.IsEmpty())
00504 {
00505 glDisable(GL_TEXTURE_2D);
00506 return;
00507 }
00508 const Image * img = scene->GetImage(material->imageName);
00509 if (!img || !img->IsOk())
00510 {
00511 glDisable(GL_TEXTURE_2D);
00512 return;
00513 }
00514
00516 if (id >= textureIDs.size())
00517 textureIDs.resize(id + 1, GL_ID_NONE);
00518
00519 wxString texKey = material->name;
00520 TextureIDMap::const_iterator texIt = textureIDMap.find(texKey);
00521 if (texIt != textureIDMap.end())
00522 {
00523 glEnable(GL_TEXTURE_2D);
00524 glBindTexture( GL_TEXTURE_2D, texIt->second );
00525 textureIDs[id] = texIt->second;
00526 }
00527 else
00528 {
00529 GLuint texID = img->BuildOglTexture();
00530 textureIDs[id] = texID;
00531 TextureIDMap::Insert_Result res = textureIDMap.insert(TextureIDMap::value_type(texKey, texID));
00532 if (!res.second)
00533 LOGERROR(wxString::Format(wxT("<RenderGlModule>Failed to insert texture '%s' to hashmap"), img->GetFilename()->GetFullPath().c_str()));
00534
00535 unsigned texFlags = material->texFlags;
00536
00537 if (texFlags & Material::TEX_UWRAP_CLAMP)
00538 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00539 else
00540 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00541 if (texFlags & Material::TEX_VWRAP_CLAMP)
00542 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00543 else
00544 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00545
00546 if (texFlags & Material::TEX_MIN_FILTER_POINT)
00547 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00548 else if (texFlags & Material::TEX_MIN_FILTER_LINEAR)
00549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00550 else
00551 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00552 if (texFlags & Material::TEX_MAG_FILTER_POINT)
00553 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00554 else
00555 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00556 }
00557 }
00558 }
00559
00560
00561 void RenderGlModule::drawVBO(const GeometryNode * node)
00562 {
00563 const Geometry * geom = scene->GetGeometry(node->GetGeometryID());
00564 const GeometryTriangles * geometry = (GeometryTriangles *)NULL;
00565 if (geom && geom->type == Geometry::GEOMETRY_TRIANGLE)
00566 geometry = (const GeometryTriangles *)geom;
00567 else
00568 return;
00569
00570 unsigned id = node->GetID();
00571 if (id >= VBOIDs.size())
00572 return;
00573
00574 if (VBOIDs[id].verticesID != GL_ID_NONE)
00575 {
00576 drawMaterial(node);
00577 drawShader(node);
00578
00579 VBOID cachedIDgroup = VBOIDs[id];
00580
00581
00582 glEnableClientState(GL_VERTEX_ARRAY);
00583 glEnableClientState(GL_INDEX_ARRAY);
00584 glBindBufferARB(GL_ARRAY_BUFFER_ARB, cachedIDgroup.verticesID);
00585 glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);
00586 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, cachedIDgroup.indicesID);
00587 glIndexPointer(GL_INT, 0, (GLvoid *) NULL);
00588 if (cachedIDgroup.normalsID != GL_ID_NONE)
00589 {
00590 glEnableClientState(GL_NORMAL_ARRAY);
00591 glBindBufferARB(GL_ARRAY_BUFFER_ARB, cachedIDgroup.normalsID);
00592 glNormalPointer(GL_FLOAT, 0, (char *) NULL);
00593 }
00594 if (cachedIDgroup.texCoordsID != GL_ID_NONE)
00595 {
00596 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00597 glBindBufferARB(GL_ARRAY_BUFFER_ARB, cachedIDgroup.texCoordsID);
00598 glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL);
00599 }
00600
00601 for (GeometryTriangles::TriDescList::const_iterator indPrimType = geometry->triDescList.begin();
00602 indPrimType != geometry->triDescList.end(); indPrimType++)
00603 {
00604 unsigned nextInd = ( (indPrimType+1) == geometry->triDescList.end() ? unsigned(geometry->indices.size()) : (indPrimType+1)->first );
00605 #ifdef __WINDOWS__
00606 #pragma warning(push)
00607 #pragma warning(disable:4312)
00608 #endif
00610 glDrawElements(GetOglPrimitiveType(indPrimType->second),
00611 GLsizei(nextInd - indPrimType->first),
00612 GL_UNSIGNED_INT,
00613 (const GLvoid *)(indPrimType->first * sizeof(GeometryTriangles::Indice)));
00614 #ifdef __WINDOWS__
00615 #pragma warning(pop)
00616 #endif
00617 }
00618 glDisableClientState(GL_VERTEX_ARRAY);
00619 glDisableClientState(GL_INDEX_ARRAY);
00620 glDisableClientState(GL_NORMAL_ARRAY);
00621 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00622 }
00623 else
00624 {
00625 VBOID cachedIDgroup;
00626 VBOIDMap::const_iterator vboIt = vboIDMap.find(geometry->GetName());
00627 if (vboIt != vboIDMap.end())
00628 VBOIDs[id] = vboIt->second;
00629 else
00630 {
00631 glGenBuffersARB(1, &cachedIDgroup.verticesID);
00632 glBindBufferARB(GL_ARRAY_BUFFER_ARB, cachedIDgroup.verticesID);
00633
00634 glBufferDataARB(GL_ARRAY_BUFFER_ARB, geometry->vertices.size() * sizeof(VECTOR3), &(*geometry->vertices.begin()), GL_STATIC_DRAW_ARB);
00635
00636 glGenBuffersARB(1, &cachedIDgroup.indicesID);
00637 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, cachedIDgroup.indicesID);
00638
00639 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, geometry->indices.size() * sizeof(GLuint), &(*geometry->indices.begin()), GL_STATIC_DRAW_ARB);
00640
00641 if (geometry->normals.size())
00642 {
00643 glGenBuffersARB(1, &cachedIDgroup.normalsID);
00644 glBindBufferARB(GL_ARRAY_BUFFER_ARB, cachedIDgroup.normalsID);
00645
00646 glBufferDataARB(GL_ARRAY_BUFFER_ARB, geometry->normals.size() * sizeof(VECTOR3), &(*geometry->normals.begin()), GL_STATIC_DRAW_ARB);
00647 }
00648
00649 if (geometry->texCoords.size())
00650 {
00651 glGenBuffersARB(1, &cachedIDgroup.texCoordsID);
00652 glBindBufferARB(GL_ARRAY_BUFFER_ARB, cachedIDgroup.texCoordsID);
00653
00654 glBufferDataARB(GL_ARRAY_BUFFER_ARB, geometry->texCoords.size() * sizeof(GeometryTriangles::TexCoord), &(*geometry->texCoords.begin()), GL_STATIC_DRAW_ARB);
00655 }
00656
00657 VBOIDs[id] = cachedIDgroup;
00658 VBOIDMap::Insert_Result res = vboIDMap.insert(VBOIDMap::value_type(geometry->GetName(), cachedIDgroup));
00659 if (!res.second)
00660 LOGERROR(wxString::Format(wxT("<RenderGlModule>Failed to insert VBO for geometry '%s' to hashmap"), geometry->GetName().c_str()));
00661 if (!vboRenderUpdated)
00662 {
00663 vboRenderUpdated = true;
00664 wxCommandEvent rndEvt = Event::GET_EVT_RENDER_UPDATE(scene->GetID());
00665 PostToKernel(rndEvt);
00666 }
00667 }
00668 }
00669 }
00670
00671
00672 void RenderGlModule::drawDispList(const GeometryNode * node)
00673 {
00674 const Geometry * geom = scene->GetGeometry(node->GetGeometryID());
00675 const GeometryTriangles * geometry = (GeometryTriangles *)NULL;
00676 if (geom && geom->type == Geometry::GEOMETRY_TRIANGLE)
00677 geometry = (const GeometryTriangles *)geom;
00678 else
00679 return;
00680
00681 unsigned id = node->GetID();
00682 if (id >= dispListIDs.size())
00683 return;
00684
00685 if (dispListIDs[id] != GL_ID_NONE)
00686 glCallList(dispListIDs[id]);
00687 else
00688 {
00689 GLuint cachedID = dispListIDs[id] = glGenLists(1);
00690 glNewList(cachedID, GL_COMPILE_AND_EXECUTE);
00691 {
00692 drawMaterial(node);
00693 drawShader(node);
00694
00695 if (geometry)
00696 {
00697 size_t indiceIndex = 0;
00698 size_t maxInd = geometry->indices.size();
00699 const std::vector<VECTOR3> * vertices = &geometry->vertices;
00700 const std::vector<VECTOR3> * normals = &geometry->normals;
00701 size_t normalsCount = normals->size();
00702 const std::vector<GeometryTriangles::TexCoord> * texCoords = &geometry->texCoords;
00703 size_t texCoordsCount = texCoords->size();
00704 const std::vector<GeometryTriangles::Indice> * indices = &geometry->indices;
00705
00706 for (GeometryTriangles::TriDescList::const_iterator indPrimType = geometry->triDescList.begin();
00707 indPrimType != geometry->triDescList.end(); indPrimType++)
00708 {
00709 GeometryTriangles::TriDescList::const_iterator endIndPrimType = indPrimType + 1;
00710 size_t endInd = ( endIndPrimType == geometry->triDescList.end() ? maxInd : endIndPrimType->first );
00711 endInd = __min( endInd, maxInd );
00712
00714 VECTOR3 autonormal;
00715 if (normals->empty() && (indiceIndex + 2 < endInd) )
00716 {
00717 std::vector<GeometryTriangles::Indice>::const_iterator indIt = indices->begin() + indiceIndex;
00718 VECTOR3 v1 = vertices->at(*indIt++);
00719 VECTOR3 v2 = vertices->at(*indIt++);
00720 VECTOR3 v3 = vertices->at(*indIt);
00721 autonormal = ((v2 - v1).Cross(v3 - v1)).Normalize();
00722 }
00723
00724 glBegin(GetOglPrimitiveType(indPrimType->second));
00725
00726 for ( ; indiceIndex < endInd; indiceIndex++)
00727 {
00728 GeometryTriangles::Indice indice = indices->at(indiceIndex);
00729 if (indice < normalsCount)
00730 glNormal3fv(normals->at(indice)._v);
00731 else
00732 glNormal3fv(autonormal._v);
00733 if (indice < texCoordsCount)
00734 glTexCoord2fv(texCoords->at(indice)._v);
00735 glVertex3fv(vertices->at(indice)._v);
00736 }
00737
00738 glEnd();
00739 }
00740 }
00741 }
00742 glEndList();
00743 }
00744 }
00745
00746
00747 wxString RenderGlModule::GetDesc() const
00748 {
00749 return wxT("Create window and render given scene to it using BVH interface");
00750 }
00751
00752
00753 bool RenderGlModule::IsExtensionSupported(const char * szTargetExtension)
00754 {
00755 const unsigned char *pszExtensions = NULL;
00756 const unsigned char *pszStart;
00757 unsigned char *pszWhere, *pszTerminator;
00758
00759
00760 pszWhere = (unsigned char *) strchr( szTargetExtension, ' ' );
00761 if ( pszWhere || *szTargetExtension == '\0' )
00762 return false;
00763
00764
00765 pszExtensions = glGetString( GL_EXTENSIONS );
00766 if (!pszExtensions)
00768 return false;
00769
00770
00771 pszStart = pszExtensions;
00772 for (;;)
00773 {
00774 pszWhere = (unsigned char *) strstr( (const char *) pszStart, szTargetExtension );
00775 if ( !pszWhere )
00776 break;
00777 pszTerminator = pszWhere + strlen( szTargetExtension );
00778 if ( pszWhere == pszStart || *( pszWhere - 1 ) == ' ' )
00779 if ( *pszTerminator == ' ' || *pszTerminator == '\0' )
00780 return true;
00781 pszStart = pszTerminator;
00782 }
00783 return false;
00784 }
00785
00786
00787 bool
00788 RenderGlModule::Initialize()
00789 {
00790 if (!initialized)
00791 {
00792 glClearDepth(1.0f);
00793 glEnable(GL_DEPTH_TEST);
00794 glDepthFunc(GL_LEQUAL);
00795 glShadeModel(GL_SMOOTH);
00796 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00797
00798 glEnable(GL_NORMALIZE);
00799 if (wireframe)
00800 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00801 else
00802 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00803
00804 if (lighting)
00805 glEnable(GL_LIGHTING);
00806 else
00807 glDisable(GL_LIGHTING);
00808
00809
00810 float ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
00811 float diffuse[] = { 0.5f, 0.5f, 0.5f, 1.0f };
00812 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
00813 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
00814 glMatrixMode(GL_MODELVIEW);
00815 glLoadIdentity();
00816 VECTOR3 position(0,0,1);
00817 glLightfv(GL_LIGHT0, GL_POSITION, position._v);
00818 if (headlight)
00819 glEnable(GL_LIGHT0);
00820 else
00821 glDisable(GL_LIGHT0);
00822
00823 checkExtSupport();
00824
00826 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
00827 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
00828
00829 initialized = true;
00830 }
00831
00832 if (!sceneInitialized && scene)
00833 {
00834 wxStopWatch sw;
00835 clearCachedGeometry();
00836 size_t nodesCount = 0;
00837 BVH * bvh = scene->GetBVH();
00838 if (bvh)
00839 {
00840 std::deque<NODE_ID> nodes;
00841 bvh->GetGeometryNodeIDs(&nodes, bvh->GetRoot());
00842 nodesCount = nodes.size();
00843 size_t maxID = scene->GetNodeMaxID();
00844 resetNodes.resize(maxID, false);
00845 reset = true;
00846
00847 for (std::deque<NODE_ID>::const_iterator nodeIt = nodes.begin();
00848 nodeIt != nodes.end(); nodeIt++)
00849 {
00850 const GeometryNode * node = (const GeometryNode *)scene->GetNode(*nodeIt);
00852 buildTexture(node);
00854 drawShader(node);
00855 }
00857 if (maxID > VBOIDs.size())
00858 VBOIDs.resize(maxID);
00859 if (maxID > dispListIDs.size())
00860 dispListIDs.resize(maxID, GL_ID_NONE);
00861 sceneInitialized = true;
00862 }
00863 LOGDEBUG(wxString::Format(wxT("<RenderGlModule>%i geometry nodes cached in %.3f secs"), nodesCount, 0.001f * sw.Time()));
00864 }
00865
00866 return initialized && sceneInitialized;
00867 }
00868
00869
00870 void RenderGlModule::Draw()
00871 {
00873 glClearColor(0.4, 0.3, 0.6, 0.0);
00874 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00875
00876 wxMutexLocker paramsLocker(paramsMutex);
00877 scene = GetSceneMgr()->GetScene(GetSceneID());
00878 if (!scene)
00879 return;
00880
00881 Camera * camera = (Camera *)scene->GetNode(cameraID);
00882
00883
00884 BVH * bvh = scene->GetBVH();
00885 if (!camera || !bvh || !Initialize())
00886 {
00887 scene = (Scene *)NULL;
00888 return;
00889 }
00890
00891 vboRenderUpdated = false;
00893 ResetNodes();
00894
00896 glMatrixMode(GL_PROJECTION);
00897
00899
00900
00901
00902
00903
00905 bool wrLockNeeded = !camera->IsValid();
00906 if (wrLockNeeded)
00907 camera->WriteLock();
00908 else
00909 camera->ReadLock();
00910 scene->UpdateTransformation(camera->GetID());
00911 unsigned w, h;
00912 camera->GetWidthHeight(&w, &h);
00913 glViewport(0, 0, w, h);
00914 glLoadMatrixf(camera->GetProjectionMatrix()->_m);
00916 glMatrixMode(GL_MODELVIEW);
00917 glLoadMatrixf(camera->GetWorldTransMatrix()->Inverse()._m);
00918
00920 BVH::ItemsList itemsList;
00921 BVH::BlendedList itemsListBlended;
00922 bvh->Cull(camera, &itemsList, &itemsListBlended);
00923 if (wrLockNeeded)
00924 camera->WriteUnlock();
00925 else
00926 camera->ReadUnlock();
00927
00928 if (drawBVH)
00929 drawBVHHierarchy();
00930
00931
00932 drawLights();
00933
00934
00935 for (BVH::ItemsList::const_iterator nodeIt = itemsList.begin();
00936 nodeIt != itemsList.end(); nodeIt++)
00937 {
00938 const GeometryNode * node = (const GeometryNode *)scene->GetNode(*nodeIt);
00939 if (!node->IsActive())
00940 continue;
00941
00942 glPushMatrix();
00943 glMultMatrixf(node->GetWorldTransMatrix()->_m);
00944
00946 if (useVBO && vboSupported)
00947 drawVBO(node);
00948 else
00949 drawDispList(node);
00950
00951 glPopMatrix();
00952 }
00953
00954
00955 glEnable(GL_BLEND);
00956 for (BVH::BlendedList::const_reverse_iterator nodeIt = itemsListBlended.rbegin();
00957 nodeIt != itemsListBlended.rend(); nodeIt++)
00958 {
00959 const GeometryNode * node = (const GeometryNode *)scene->GetNode(nodeIt->second);
00960 if (!node->IsActive())
00961 continue;
00962
00963 glPushMatrix();
00964 glMultMatrixf(node->GetWorldTransMatrix()->_m);
00965
00967 if (useVBO && vboSupported)
00968 drawVBO(node);
00969 else
00970 drawDispList(node);
00971
00972 glPopMatrix();
00973 }
00974 glDisable(GL_BLEND);
00975 scene = (Scene *)NULL;
00976 }
00977
00978
00979 void RenderGlModule::Deinitialize()
00980 {
00981 clearCachedGeometry();
00982 initialized = false;
00983 }
00984
00985
00986 int RenderGlModule::GetOglPrimitiveType(GeometryTriangles::PRIMITIVE_TYPE primType)
00987 {
00988 switch (primType)
00989 {
00990 case GeometryTriangles::TRI_LIST:
00991 return GL_TRIANGLES;
00992 case GeometryTriangles::TRI_FAN:
00993 return GL_TRIANGLE_FAN;
00994 case GeometryTriangles::TRI_STRIP:
00995 return GL_TRIANGLE_STRIP;
00996 case GeometryTriangles::POLYGON:
00997 return GL_POLYGON;
00998 case GeometryTriangles::LINES:
00999 return GL_LINES;
01000 case GeometryTriangles::LINE_STRIP:
01001 return GL_LINE_STRIP;
01002 case GeometryTriangles::POINTS:
01003 return GL_POINTS;
01004 case GeometryTriangles::QUADS:
01005 return GL_QUADS;
01006 default:
01007 return 0xffffffff;
01008 };
01009 }
01010
01011
01012 void RenderGlModule::ResetNodes()
01013 {
01014 size_t ncount = 0;
01015 if (reset)
01016 {
01017 for (size_t i = 0; i < resetNodes.size(); i++)
01018 {
01019 if (resetNodes[i])
01020 {
01021 NODE_ID id = NODE_ID(i);
01022 wxASSERT_MSG(scene->GetNode(id), wxT("<RenderGlModule>Trying to reinitialize invalid scene node"));
01023 wxASSERT_MSG(scene->GetNode(id)->IsOfType(SceneNode::GEOMETRY), wxT("<RenderGlModule>Trying to reinitialize scene node of invalid type"));
01024 const GeometryNode * node = (const GeometryNode *)scene->GetNode(id);
01025 if ((!sceneImportMode || allowRedundantDeletes)
01026 && id < dispListIDs.size()
01027 && dispListIDs[id] != GL_ID_NONE)
01028 {
01029 glDeleteLists(dispListIDs[id], 1);
01030 dispListIDs[id] = GL_ID_NONE;
01031 }
01032 if (id < VBOIDs.size() && (!sceneImportMode || allowRedundantDeletes))
01033 VBOIDs[id] = VBOID();
01034 if (id < textureIDs.size() && (!sceneImportMode || allowRedundantDeletes))
01035 textureIDs[id] = GL_ID_NONE;
01036
01038 buildTexture(node);
01040 drawShader(node);
01041
01043 if (id >= VBOIDs.size())
01044 VBOIDs.resize(id + 1);
01045 if (id >= dispListIDs.size())
01046 dispListIDs.resize(id + 1, GL_ID_NONE);
01047
01048 resetNodes[i] = false;
01049 ncount++;
01050 }
01051 }
01052 reset = false;
01053 if (ncount)
01054 LOGDEBUG(wxString::Format(wxT("<RenderGLMoudle>%i nodes reset"), ncount));
01055 }
01056 }
01057
01058
01059 void RenderGlModule::drawBVHHierarchy() const
01060 {
01061 if (!scene || !scene->GetBVH())
01062 return;
01063
01064
01065
01066 BVH * bvh = scene->GetBVH();
01067 std::deque<const BVHNode *> queue;
01068 queue.push_back(bvh->GetRoot());
01069
01070 VECTOR3 color(1,1,1);
01071 glDisable(GL_LIGHTING);
01072 glDisable(GL_TEXTURE_2D);
01073 while (queue.size())
01074 {
01075 const BVHNode * node = queue.front();
01076 queue.pop_front();
01077
01078 if (node)
01079 {
01080 glColor3fv(color._v);
01081 VECTOR3 v0(node->GetAABB()->MinBound);
01082 VECTOR3 v7(node->GetAABB()->MaxBound);
01083 VECTOR3 v1(v7.x, v0.y, v0.z);
01084 VECTOR3 v2(v0.x, v7.y, v0.z);
01085 VECTOR3 v3(v7.x, v7.y, v0.z);
01086 VECTOR3 v4(v0.x, v0.y, v7.z);
01087 VECTOR3 v5(v7.x, v0.y, v7.z);
01088 VECTOR3 v6(v0.x, v7.y, v7.z);
01089 glBegin(GL_LINE_STRIP);
01090 glVertex3fv(v0._v);
01091 glVertex3fv(v1._v);
01092 glVertex3fv(v3._v);
01093 glVertex3fv(v2._v);
01094 glVertex3fv(v0._v);
01095 glVertex3fv(v4._v);
01096 glVertex3fv(v6._v);
01097 glVertex3fv(v7._v);
01098 glVertex3fv(v5._v);
01099 glVertex3fv(v4._v);
01100 glVertex3fv(v6._v);
01101 glVertex3fv(v2._v);
01102 glVertex3fv(v3._v);
01103 glVertex3fv(v7._v);
01104 glVertex3fv(v5._v);
01105 glVertex3fv(v1._v);
01106 glEnd();
01107
01108 queue.push_back(node->GetLChild());
01109 queue.push_back(node->GetRChild());
01110 }
01111 }
01112 }
01113
01114
01115 void RenderGlModule::processEvent(wxCommandEvent & evt)
01116 {
01117 RenderModule::processEvent(evt);
01118 switch (evt.GetEventType())
01119 {
01120 case Event::EVT_PARAM_SET:
01121 {
01122 wxMutexLocker paramsLocker(paramsMutex);
01123 Parameter::ParameterIdentificator pi = Parameter::ParameterIdentificator::FromEvent(evt);
01124 if (pi == cameraIDParamID)
01125 {
01126 resetNodes.clear();
01127 reset = false;
01128 }
01129 else if (pi == useVBOParamID ||
01130 pi == wireframeParamID ||
01131 pi == lightingParamID ||
01132 pi == headlightParamID ||
01133 pi == drawBVHParamID ||
01134 pi == allowRedundantDeletesParamID)
01135 {
01136 UPDATE_PARAM_FROM_EVENT_BOOL(useVBOParamID, useVBO, evt);
01137 UPDATE_PARAM_FROM_EVENT_BOOL(wireframeParamID, wireframe, evt);
01138 UPDATE_PARAM_FROM_EVENT_BOOL(lightingParamID, lighting, evt);
01139 UPDATE_PARAM_FROM_EVENT_BOOL(headlightParamID, headlight, evt);
01140 UPDATE_PARAM_FROM_EVENT_BOOL(drawBVHParamID, drawBVH, evt);
01141 UPDATE_PARAM_FROM_EVENT_BOOL(allowRedundantDeletesParamID, allowRedundantDeletes, evt);
01142 initialized = false;
01143 if (pi == lightingParamID)
01144 sceneInitialized = false;
01145 if (GetSceneID() != SCENE_ID_NONE)
01146 {
01147 wxCommandEvent evtRnd = Event::GET_EVT_RENDER_UPDATE(GetSceneID());
01148 PostToKernel(evtRnd);
01149 }
01150 }
01151 }
01152 break;
01153 default:
01154 break;
01155 }
01156
01158 if (evt.GetId() == int(GetSceneID()))
01159 {
01160 wxMutexLocker paramsLocker(paramsMutex);
01161 switch (evt.GetEventType())
01162 {
01163 case Event::EVT_SCENE_NODE_INSERTED:
01164 case Event::EVT_SCENE_NODE_REMOVED:
01165 case Event::EVT_SCENE_NODE_MATERIAL_CHANGED:
01166 case Event::EVT_SCENE_NODE_GEOMETRY_CHANGED:
01167 case Event::EVT_SCENE_NODE_TRANSFORMED:
01168 {
01169 scene = GetSceneMgr()->GetScene(GetSceneID());
01170 if (scene)
01171 {
01172 NODE_ID nodeID = NODE_ID(evt.GetInt());
01173 const SceneNode * node = scene->GetNode(nodeID);
01174 if (node && node->IsOfType(SceneNode::GEOMETRY))
01175 {
01176 if (nodeID >= resetNodes.size())
01177 resetNodes.resize(nodeID + 1, false);
01178 reset = resetNodes[nodeID] = true;
01179 }
01180 scene = (Scene *)NULL;
01181 }
01182 }
01183 break;
01184 case Event::EVT_RENDER_CACHE_START:
01185 sceneImportMode = true;
01186 break;
01187 case Event::EVT_RENDER_CACHE_STOP:
01188 {
01189 sceneImportMode = false;
01190 LOG(wxString::Format(wxT("<EventHandler>Scene render data cached, ID %i"), evt.GetId()));
01191 }
01192 break;
01193 default:
01194 break;
01195 }
01196 }
01197 }