00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "rendcontext.h"
00011 #include "texmanager.h"
00012 #include "gl.h"
00013 #include "glext.h"
00014 #include "vecgl.h"
00015
00016
00017 static Mesh::Material defaultMaterial;
00018
00019 static GLenum GLPrimitiveModes[Mesh::PrimitiveTypeMax] =
00020 {
00021 GL_TRIANGLES,
00022 GL_TRIANGLE_STRIP,
00023 GL_TRIANGLE_FAN,
00024 GL_LINES,
00025 GL_LINE_STRIP,
00026 GL_POINTS
00027 };
00028
00029 static GLenum GLComponentTypes[Mesh::FormatMax] =
00030 {
00031 GL_FLOAT,
00032 GL_FLOAT,
00033 GL_FLOAT,
00034 GL_FLOAT,
00035 GL_UNSIGNED_BYTE,
00036 };
00037
00038 static int GLComponentCounts[Mesh::FormatMax] =
00039 {
00040 1,
00041 2,
00042 3,
00043 4,
00044 4,
00045 };
00046
00047
00048 enum {
00049 TangentAttributeIndex = 6,
00050 };
00051
00052
00053 static void
00054 setStandardVertexArrays(const Mesh::VertexDescription& desc,
00055 void* vertexData);
00056 static void
00057 setExtendedVertexArrays(const Mesh::VertexDescription& desc,
00058 const void* vertexData);
00059
00060
00061 RenderContext::RenderContext() :
00062 material(&defaultMaterial),
00063 locked(false),
00064 renderPass(PrimaryPass)
00065 {
00066 }
00067
00068
00069 RenderContext::RenderContext(const Mesh::Material* _material)
00070 {
00071 if (_material == NULL)
00072 material = &defaultMaterial;
00073 else
00074 material = _material;
00075 }
00076
00077
00078 static void setVertexArrays(const Mesh::VertexDescription& desc)
00079 {
00080 }
00081
00082
00083 void
00084 RenderContext::setMaterial(const Mesh::Material* newMaterial)
00085 {
00086 if (!locked)
00087 {
00088 if (newMaterial == NULL)
00089 newMaterial = &defaultMaterial;
00090
00091 if (renderPass == PrimaryPass)
00092 {
00093 if (newMaterial != material)
00094 {
00095 material = newMaterial;
00096 makeCurrent(*material);
00097 }
00098 }
00099 else if (renderPass == EmissivePass)
00100 {
00101 if (material->maps[Mesh::EmissiveMap] !=
00102 newMaterial->maps[Mesh::EmissiveMap])
00103 {
00104 material = newMaterial;
00105 makeCurrent(*material);
00106 }
00107 }
00108 }
00109 }
00110
00111
00112 void
00113 RenderContext::drawGroup(const Mesh::PrimitiveGroup& group)
00114 {
00115
00116
00117 if (renderPass == EmissivePass &&
00118 material->maps[Mesh::EmissiveMap] == InvalidResource)
00119 {
00120 return;
00121 }
00122
00123 glDrawElements(GLPrimitiveModes[(int) group.prim],
00124 group.nIndices,
00125 GL_UNSIGNED_INT,
00126 group.indices);
00127 }
00128
00129
00130 FixedFunctionRenderContext::FixedFunctionRenderContext() :
00131 RenderContext(),
00132 blendOn(false),
00133 specularOn(false)
00134 {
00135 }
00136
00137
00138 FixedFunctionRenderContext::FixedFunctionRenderContext(const Mesh::Material* _material) :
00139 RenderContext(_material),
00140 blendOn(false),
00141 specularOn(false)
00142 {
00143 }
00144
00145
00146 void
00147 FixedFunctionRenderContext::makeCurrent(const Mesh::Material& m)
00148 {
00149 if (getRenderPass() == PrimaryPass)
00150 {
00151 Texture* t = NULL;
00152 if (m.maps[Mesh::DiffuseMap] != InvalidResource)
00153 t = GetTextureManager()->find(m.maps[Mesh::DiffuseMap]);
00154
00155 if (t == NULL)
00156 {
00157 glDisable(GL_TEXTURE_2D);
00158 }
00159 else
00160 {
00161 glEnable(GL_TEXTURE_2D);
00162 t->bind();
00163 }
00164
00165 glColor4f(m.diffuse.red(),
00166 m.diffuse.green(),
00167 m.diffuse.blue(),
00168 m.opacity);
00169
00170 bool blendOnNow = false;
00171 if (m.opacity != 1.0f || (t != NULL && t->hasAlpha()))
00172 blendOnNow = true;
00173
00174 if (blendOnNow != blendOn)
00175 {
00176 blendOn = blendOnNow;
00177 if (blendOn)
00178 {
00179 glEnable(GL_BLEND);
00180 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00181 glDepthMask(GL_FALSE);
00182 }
00183 else
00184 {
00185 glDisable(GL_BLEND);
00186 glDepthMask(GL_TRUE);
00187 }
00188 }
00189
00190 if (m.specular == Color::Black)
00191 {
00192 float matSpecular[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
00193 float zero = 0.0f;
00194 glMaterialfv(GL_FRONT, GL_SPECULAR, matSpecular);
00195 glMaterialfv(GL_FRONT, GL_SHININESS, &zero);
00196 specularOn = false;
00197 }
00198 else
00199 {
00200 float matSpecular[4] = { m.specular.red(),
00201 m.specular.green(),
00202 m.specular.blue(),
00203 0.0f };
00204 glMaterialfv(GL_FRONT, GL_SPECULAR, matSpecular);
00205 glMaterialfv(GL_FRONT, GL_SHININESS, &m.specularPower);
00206 specularOn = true;
00207 }
00208
00209 {
00210 float matEmissive[4] = { m.emissive.red(),
00211 m.emissive.green(),
00212 m.emissive.blue(),
00213 0.0f };
00214 glMaterialfv(GL_FRONT, GL_EMISSION, matEmissive);
00215 }
00216 }
00217 else if (getRenderPass() == EmissivePass)
00218 {
00219 Texture* t = NULL;
00220 if (m.maps[Mesh::EmissiveMap] != InvalidResource)
00221 t = GetTextureManager()->find(m.maps[Mesh::EmissiveMap]);
00222
00223 if (t == NULL)
00224 {
00225 glDisable(GL_TEXTURE_2D);
00226 }
00227 else
00228 {
00229 glEnable(GL_TEXTURE_2D);
00230 t->bind();
00231 }
00232 }
00233 }
00234
00235
00236 void
00237 FixedFunctionRenderContext::setVertexArrays(const Mesh::VertexDescription& desc, void* vertexData)
00238 {
00239 setStandardVertexArrays(desc, vertexData);
00240 }
00241
00242
00243 void
00244 VP_Combiner_RenderContext::setVertexArrays(const Mesh::VertexDescription& desc, void* vertexData)
00245 {
00246 setStandardVertexArrays(desc, vertexData);
00247 setExtendedVertexArrays(desc, vertexData);
00248 }
00249
00250
00251 void
00252 VP_FP_RenderContext::setVertexArrays(const Mesh::VertexDescription& desc, void* vertexData)
00253 {
00254 setStandardVertexArrays(desc, vertexData);
00255 setExtendedVertexArrays(desc, vertexData);
00256 }
00257
00258
00259
00260
00261 void
00262 setStandardVertexArrays(const Mesh::VertexDescription& desc,
00263 void* vertexData)
00264 {
00265 const Mesh::VertexAttribute& position = desc.getAttribute(Mesh::Position);
00266 const Mesh::VertexAttribute& normal = desc.getAttribute(Mesh::Normal);
00267 const Mesh::VertexAttribute& color0 = desc.getAttribute(Mesh::Color0);
00268 const Mesh::VertexAttribute& texCoord0 = desc.getAttribute(Mesh::Texture0);
00269
00270
00271 if (position.format != Mesh::Float3)
00272 return;
00273
00274
00275 glEnableClientState(GL_VERTEX_ARRAY);
00276 glVertexPointer(3, GL_FLOAT, desc.stride,
00277 reinterpret_cast<char*>(vertexData) + position.offset);
00278
00279
00280 switch (normal.format)
00281 {
00282 case Mesh::Float3:
00283 glEnableClientState(GL_NORMAL_ARRAY);
00284 glNormalPointer(GLComponentTypes[(int) normal.format],
00285 desc.stride,
00286 reinterpret_cast<char*>(vertexData) + normal.offset);
00287 break;
00288 default:
00289 glDisableClientState(GL_NORMAL_ARRAY);
00290 break;
00291 }
00292
00293
00294 switch (color0.format)
00295 {
00296 case Mesh::Float3:
00297 case Mesh::Float4:
00298 case Mesh::UByte4:
00299 glEnableClientState(GL_COLOR_ARRAY);
00300 glColorPointer(GLComponentCounts[color0.format],
00301 GLComponentTypes[color0.format],
00302 desc.stride,
00303 reinterpret_cast<char*>(vertexData) + color0.offset);
00304 break;
00305 default:
00306 glDisableClientState(GL_COLOR_ARRAY);
00307 break;
00308 }
00309
00310
00311 switch (texCoord0.format)
00312 {
00313 case Mesh::Float1:
00314 case Mesh::Float2:
00315 case Mesh::Float3:
00316 case Mesh::Float4:
00317 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00318 glTexCoordPointer(GLComponentCounts[(int) texCoord0.format],
00319 GLComponentTypes[(int) texCoord0.format],
00320 desc.stride,
00321 reinterpret_cast<char*>(vertexData) + texCoord0.offset);
00322 break;
00323 default:
00324 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00325 break;
00326 }
00327 }
00328
00329
00330 void
00331 setExtendedVertexArrays(const Mesh::VertexDescription& desc,
00332 const void* vertexData)
00333 {
00334 const Mesh::VertexAttribute& tangent = desc.getAttribute(Mesh::Tangent);
00335 const char* vertices = reinterpret_cast<const char*>(vertexData);
00336
00337 switch (tangent.format)
00338 {
00339 case Mesh::Float3:
00340 glx::glEnableVertexAttribArrayARB(TangentAttributeIndex);
00341 glEnableClientState(GL_NORMAL_ARRAY);
00342 glx::glVertexAttribPointerARB(TangentAttributeIndex,
00343 GLComponentCounts[(int) tangent.format],
00344 GLComponentTypes[(int) tangent.format],
00345 GL_FALSE,
00346 desc.stride,
00347 vertices + tangent.offset);
00348 break;
00349 default:
00350 glx::glDisableVertexAttribArrayARB(TangentAttributeIndex);
00351 break;
00352 }
00353 }
00354
00355
00356 GLSL_RenderContext::GLSL_RenderContext(const LightingState& ls) :
00357 lightingState(ls)
00358 {
00359 }
00360
00361
00362 GLSL_RenderContext::GLSL_RenderContext(const LightingState& ls,
00363 const Mesh::Material* material) :
00364 lightingState(ls)
00365 {
00366 }
00367
00368
00369
00370 void
00371 GLSL_RenderContext::makeCurrent(const Mesh::Material& m)
00372 {
00373 #if 0
00374 ShaderProperties shadprop;
00375
00376 Texture* textures[4] = { NULL, NULL, NULL, NULL };
00377 unsigned int nTextures = 0;
00378
00379 shadprop.nLights = min(ls.nLights, MaxShaderLights);
00380
00381
00382 Texture* baseTex = NULL;
00383 Texture* bumpTex = NULL;
00384 Texture* specTex = NULL;
00385 Texture* emissiveTex = NULL;
00386
00387 if (m.maps[Mesh::DiffuseMap] != InvalidResource)
00388 {
00389 baseTex = GetTextureManager()->find(m.maps[Mesh::DiffuseMap]);
00390 if (baseTex != NULL)
00391 {
00392 shadprop.texUsage = ShaderProperties::DiffuseTexture;
00393 textures[nTextures++] = baseTex;
00394 }
00395 }
00396
00397 if (m.maps[Mesh::NormalMap] != InvalidResource)
00398 {
00399 bumpTex = GetTextureManger()->find(m.maps[Mesh::NormalMap]);
00400 if (bumpTex != NULL)
00401 {
00402 shadprop.texUsage |= ShaderProperties::NormalTexture;
00403 textures[nTextures++] = bumpTex;
00404 }
00405 }
00406
00407 if (m.specular != Color::Black)
00408 {
00409 shadprop.lightModel = ShaderProperties::SpecularModel;
00410 specTex = GetTextureManager()->find(m.maps[Mesh::SpecularMap]);
00411 if (specTex == NULL)
00412 {
00413 shadprop.texUsage |= ShaderProperties::SpecularInDiffuseAlpha;
00414 }
00415 else
00416 {
00417 shadprop.texUsage |= ShaderProperties::SpecularTexture;
00418 textures[nTextures++] = specTex;
00419 }
00420 }
00421
00422 if (m.maps[Mesh::EmissiveMap] != InvalidResource)
00423 {
00424 emissiveTex = GetTextureManager()->find(m.maps[Mesh::EmissiveMap]);
00425 if (emissiveTex != NULL)
00426 {
00427 shadprop.texUsage |= ShaderProperties::NightTexture;
00428 textures[nTextures++] = emissiveTex;
00429 }
00430 }
00431
00432 #if 0
00433
00434
00435
00436 unsigned int totalShadows = 0;
00437 for (unsigned int li = 0; li < ls.nLights; li++)
00438 {
00439 if (ls.shadows[li] && !ls.shadows[li]->empty())
00440 {
00441 unsigned int nShadows = (unsigned int) min((size_t) MaxShaderShadows, ls.shadows[li]->size());
00442 shadprop.setShadowCountForLight(li, nShadows);
00443 totalShadows += nShadows;
00444 }
00445 }
00446 #endif
00447
00448
00449 CelestiaGLProgram* prog = GetShaderManager().getShader(shadprop);
00450 if (prog == NULL)
00451 return;
00452
00453 prog->use();
00454
00455 setLightParameters_GLSL(*prog, shadprop, ls,
00456 ri.color, ri.specularColor);
00457
00458 prog->shininess = m.specularPower;
00459 prog->ambientColor = Vec3f(ri.ambientColor.red(), ri.ambientColor.green(),
00460 ri.ambientColor.blue());
00461
00462 if (shadprop.texUsage & ShaderProperties::RingShadowTexture)
00463 {
00464 float ringWidth = rings->outerRadius - rings->innerRadius;
00465 prog->ringRadius = rings->innerRadius / radius;
00466 prog->ringWidth = 1.0f / (ringWidth / radius);
00467 }
00468
00469 if (shadprop.shadowCounts != 0)
00470 setEclipseShadowShaderConstants(ls, radius, planetMat, *prog);
00471
00472 glColor(ri.color);
00473
00474 unsigned int attributes = LODSphereMesh::Normals;
00475 if (ri.bumpTex != NULL)
00476 attributes |= LODSphereMesh::Tangents;
00477 lodSphere->render(context,
00478 attributes,
00479 frustum, ri.pixWidth,
00480 textures[0], textures[1], textures[2], textures[3]);
00481
00482 glx::glUseProgramObjectARB(0);
00483
00484 #if 0
00485 Texture* t = NULL;
00486 if (m.maps[Mesh::DiffuseMap] != InvalidResource)
00487 t = GetTextureManager()->find(m.maps[Mesh::DiffuseMap]);
00488
00489 if (t == NULL)
00490 {
00491 glDisable(GL_TEXTURE_2D);
00492 }
00493 else
00494 {
00495 glEnable(GL_TEXTURE_2D);
00496 t->bind();
00497 }
00498
00499 glColor4f(m.diffuse.red(),
00500 m.diffuse.green(),
00501 m.diffuse.blue(),
00502 m.opacity);
00503
00504 bool blendOnNow = false;
00505 if (m.opacity != 1.0f || (t != NULL && t->hasAlpha()))
00506 blendOnNow = true;
00507
00508 if (blendOnNow != blendOn)
00509 {
00510 blendOn = blendOnNow;
00511 if (blendOn)
00512 {
00513 glEnable(GL_BLEND);
00514 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00515 glDepthMask(GL_FALSE);
00516 }
00517 else
00518 {
00519 glDisable(GL_BLEND);
00520 glDepthMask(GL_TRUE);
00521 }
00522 }
00523
00524 if (m.specular == Color::Black)
00525 {
00526 float matSpecular[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
00527 float zero = 0.0f;
00528 glMaterialfv(GL_FRONT, GL_SPECULAR, matSpecular);
00529 glMaterialfv(GL_FRONT, GL_SHININESS, &zero);
00530 specularOn = false;
00531 }
00532 else
00533 {
00534 float matSpecular[4] = { m.specular.red(),
00535 m.specular.green(),
00536 m.specular.blue(),
00537 0.0f };
00538 glMaterialfv(GL_FRONT, GL_SPECULAR, matSpecular);
00539 glMaterialfv(GL_FRONT, GL_SHININESS, &m.specularPower);
00540 specularOn = true;
00541 }
00542
00543 {
00544 float matEmissive[4] = { m.emissive.red(),
00545 m.emissive.green(),
00546 m.emissive.blue(),
00547 0.0f };
00548 glMaterialfv(GL_FRONT, GL_EMISSION, matEmissive);
00549 }
00550 #endif
00551 #endif
00552 }
00553
00554
00555 void
00556 GLSL_RenderContext::setVertexArrays(const Mesh::VertexDescription& desc,
00557 void* vertexData)
00558 {
00559 }