1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #ifndef __C_OPENGL_MATERIAL_RENDERER_H_INCLUDED__
\r
6 #define __C_OPENGL_MATERIAL_RENDERER_H_INCLUDED__
\r
8 #ifdef _IRR_COMPILE_WITH_OPENGL_
\r
10 #include "IMaterialRenderer.h"
\r
12 #include "COpenGLDriver.h"
\r
13 #include "COpenGLCacheHandler.h"
\r
20 //! Solid material renderer
\r
21 class COpenGLMaterialRenderer_SOLID : public IMaterialRenderer
\r
25 COpenGLMaterialRenderer_SOLID(video::COpenGLDriver* d) : Driver(d) {}
\r
27 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
28 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
30 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
31 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
33 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
35 Driver->disableTextures(1);
\r
36 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
41 video::COpenGLDriver* Driver;
\r
45 //! Generic Texture Blend
\r
46 class COpenGLMaterialRenderer_ONETEXTURE_BLEND : public IMaterialRenderer
\r
50 COpenGLMaterialRenderer_ONETEXTURE_BLEND(video::COpenGLDriver* d) : Driver(d) {}
\r
52 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
53 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
55 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
56 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
58 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
60 Driver->disableTextures(1);
\r
61 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
63 // if (material.MaterialType != lastMaterial.MaterialType ||
\r
64 // material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
\r
65 // resetAllRenderstates)
\r
67 E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
\r
68 E_MODULATE_FUNC modulate;
\r
70 unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
\r
72 Driver->getCacheHandler()->setBlend(true);
\r
74 if (Driver->queryFeature(EVDF_BLEND_SEPARATE))
\r
76 Driver->getCacheHandler()->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
\r
77 Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
\r
81 Driver->getCacheHandler()->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
\r
84 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
86 #ifdef GL_ARB_texture_env_combine
\r
87 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
88 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
89 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
90 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
91 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (f32) modulate );
\r
93 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
94 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
95 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
96 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
97 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
\r
100 if (textureBlendFunc_hasAlpha(srcRGBFact) || textureBlendFunc_hasAlpha(dstRGBFact) ||
\r
101 textureBlendFunc_hasAlpha(srcAlphaFact) || textureBlendFunc_hasAlpha(dstAlphaFact))
\r
103 if (alphaSource==EAS_VERTEX_COLOR)
\r
105 #ifdef GL_ARB_texture_env_combine
\r
106 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
107 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
\r
109 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
110 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
\r
113 else if (alphaSource==EAS_TEXTURE)
\r
115 #ifdef GL_ARB_texture_env_combine
\r
116 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
117 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
\r
119 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
120 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
\r
125 #ifdef GL_ARB_texture_env_combine
\r
126 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
\r
127 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
\r
128 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
\r
130 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
\r
131 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
\r
132 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE);
\r
139 void OnUnsetMaterial() override
\r
141 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
143 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
145 #ifdef GL_ARB_texture_env_combine
\r
146 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
\r
147 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f );
\r
148 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
150 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
\r
151 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
\r
152 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
155 Driver->getCacheHandler()->setBlend(false);
\r
158 //! Returns if the material is transparent.
\r
159 /** Is not always transparent, but mostly. */
\r
160 bool isTransparent() const override
\r
167 video::COpenGLDriver* Driver;
\r
171 //! Solid 2 layer material renderer
\r
172 class COpenGLMaterialRenderer_SOLID_2_LAYER : public IMaterialRenderer
\r
176 COpenGLMaterialRenderer_SOLID_2_LAYER(video::COpenGLDriver* d) : Driver(d) {}
\r
178 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
179 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
181 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
182 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
184 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
186 Driver->disableTextures(2);
\r
187 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
189 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
191 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
193 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
194 #ifdef GL_ARB_texture_env_combine
\r
195 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
196 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
197 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
\r
198 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE);
\r
199 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
200 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
201 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR);
\r
202 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
\r
204 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
205 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
206 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
\r
207 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE);
\r
208 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
209 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
210 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR);
\r
211 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
\r
217 void OnUnsetMaterial() override
\r
219 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
221 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
223 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
225 #ifdef GL_ARB_texture_env_combine
\r
226 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
\r
228 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
\r
235 video::COpenGLDriver* Driver;
\r
239 //! Transparent add color material renderer
\r
240 class COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR : public IMaterialRenderer
\r
244 COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(video::COpenGLDriver* d) : Driver(d) {}
\r
246 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
247 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
249 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
250 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
252 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
254 Driver->disableTextures(1);
\r
255 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
257 Driver->getCacheHandler()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
\r
258 Driver->getCacheHandler()->setBlend(true);
\r
261 void OnUnsetMaterial() override
\r
263 Driver->getCacheHandler()->setBlend(false);
\r
266 //! Returns if the material is transparent.
\r
267 bool isTransparent() const override
\r
274 video::COpenGLDriver* Driver;
\r
278 //! Transparent vertex alpha material renderer
\r
279 class COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public IMaterialRenderer
\r
283 COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(video::COpenGLDriver* d) : Driver(d) {}
\r
285 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
286 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
288 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
289 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
291 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
293 Driver->disableTextures(1);
\r
294 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
296 Driver->getCacheHandler()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
\r
297 Driver->getCacheHandler()->setBlend(true);
\r
299 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
301 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
303 #ifdef GL_ARB_texture_env_combine
\r
304 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
305 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
306 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
\r
307 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
308 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
309 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
311 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
312 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
313 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT );
\r
314 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
315 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
316 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
321 void OnUnsetMaterial() override
\r
323 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
325 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
326 #ifdef GL_ARB_texture_env_combine
\r
327 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
\r
328 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE );
\r
330 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
\r
331 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
\r
334 Driver->getCacheHandler()->setBlend(false);
\r
337 //! Returns if the material is transparent.
\r
338 bool isTransparent() const override
\r
345 video::COpenGLDriver* Driver;
\r
349 //! Transparent alpha channel material renderer
\r
350 class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public IMaterialRenderer
\r
354 COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(video::COpenGLDriver* d) : Driver(d) {}
\r
356 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
357 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
359 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
360 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
362 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
364 Driver->disableTextures(1);
\r
365 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
367 Driver->getCacheHandler()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
\r
368 Driver->getCacheHandler()->setBlend(true);
\r
369 Driver->getCacheHandler()->setAlphaTest(true);
\r
370 Driver->getCacheHandler()->setAlphaFunc(GL_GREATER, material.MaterialTypeParam);
\r
372 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates || material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
\r
374 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
376 #ifdef GL_ARB_texture_env_combine
\r
377 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
378 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
379 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
380 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
381 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
382 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
\r
384 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
385 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
386 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
387 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
388 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
389 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
\r
394 void OnUnsetMaterial() override
\r
396 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
398 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
399 #ifdef GL_ARB_texture_env_combine
\r
400 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
\r
402 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
\r
404 Driver->getCacheHandler()->setAlphaTest(false);
\r
405 Driver->getCacheHandler()->setBlend(false);
\r
408 //! Returns if the material is transparent.
\r
409 bool isTransparent() const override
\r
416 video::COpenGLDriver* Driver;
\r
420 //! Transparent alpha channel material renderer
\r
421 class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public IMaterialRenderer
\r
425 COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(video::COpenGLDriver* d) : Driver(d) {}
\r
427 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
428 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
430 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
431 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
433 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
435 Driver->disableTextures(1);
\r
436 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
438 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
440 Driver->getCacheHandler()->setAlphaTest(true);
\r
441 Driver->getCacheHandler()->setAlphaFunc(GL_GREATER, 0.5f);
\r
445 void OnUnsetMaterial() override
\r
447 Driver->getCacheHandler()->setAlphaTest(false);
\r
450 //! Returns if the material is transparent.
\r
451 bool isTransparent() const override
\r
453 return false; // this material is not really transparent because it does no blending.
\r
458 video::COpenGLDriver* Driver;
\r
462 //! material renderer for all kinds of lightmaps
\r
463 class COpenGLMaterialRenderer_LIGHTMAP : public IMaterialRenderer
\r
467 COpenGLMaterialRenderer_LIGHTMAP(video::COpenGLDriver* d) : Driver(d) {}
\r
469 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
470 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
472 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
473 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
475 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
477 Driver->disableTextures(2);
\r
478 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
480 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
482 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
486 switch (material.MaterialType)
\r
488 case EMT_LIGHTMAP_LIGHTING:
\r
489 case EMT_LIGHTMAP_LIGHTING_M2:
\r
490 case EMT_LIGHTMAP_LIGHTING_M4:
\r
491 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
493 case EMT_LIGHTMAP_ADD:
\r
495 case EMT_LIGHTMAP_M2:
\r
496 case EMT_LIGHTMAP_M4:
\r
498 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
\r
502 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
506 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
507 #ifdef GL_ARB_texture_env_combine
\r
508 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
510 if (material.MaterialType == EMT_LIGHTMAP_ADD)
\r
511 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
\r
513 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
515 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
516 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
517 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
\r
518 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
\r
519 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);
\r
521 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
523 if (material.MaterialType == EMT_LIGHTMAP_ADD)
\r
524 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
\r
526 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
528 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
529 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
530 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
\r
531 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
\r
532 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT);
\r
535 switch (material.MaterialType)
\r
537 case EMT_LIGHTMAP_M4:
\r
538 case EMT_LIGHTMAP_LIGHTING_M4:
\r
539 #ifdef GL_ARB_texture_env_combine
\r
540 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 4.0f);
\r
542 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 4.0f);
\r
545 case EMT_LIGHTMAP_M2:
\r
546 case EMT_LIGHTMAP_LIGHTING_M2:
\r
547 #ifdef GL_ARB_texture_env_combine
\r
548 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2.0f);
\r
550 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f);
\r
554 #ifdef GL_ARB_texture_env_combine
\r
555 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0f);
\r
557 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f);
\r
564 void OnUnsetMaterial() override
\r
566 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
568 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
570 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
571 #ifdef GL_ARB_texture_env_combine
\r
572 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f );
\r
574 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
\r
578 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
579 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
584 video::COpenGLDriver* Driver;
\r
589 //! detail map material renderer
\r
590 class COpenGLMaterialRenderer_DETAIL_MAP : public IMaterialRenderer
\r
594 COpenGLMaterialRenderer_DETAIL_MAP(video::COpenGLDriver* d) : Driver(d) {}
\r
596 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
597 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
599 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
600 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
602 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
604 Driver->disableTextures(2);
\r
605 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
607 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
609 // detail map on second layer
\r
610 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
612 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
614 #ifdef GL_ARB_texture_env_combine
\r
615 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
616 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
\r
617 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
618 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
620 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
621 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_EXT);
\r
622 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
623 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
629 void OnUnsetMaterial() override
\r
631 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
633 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
635 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
641 video::COpenGLDriver* Driver;
\r
645 //! sphere map material renderer
\r
646 class COpenGLMaterialRenderer_SPHERE_MAP : public IMaterialRenderer
\r
650 COpenGLMaterialRenderer_SPHERE_MAP(video::COpenGLDriver* d) : Driver(d) {}
\r
652 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
653 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
655 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
656 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
658 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
660 Driver->disableTextures(1);
\r
661 // texture needs to be flipped for OpenGL
\r
662 core::matrix4 tmp = Driver->getTransform(ETS_TEXTURE_0);
\r
664 Driver->setTransform(ETS_TEXTURE_0, tmp);
\r
665 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
667 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
669 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
671 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
\r
672 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
\r
674 glEnable(GL_TEXTURE_GEN_S);
\r
675 glEnable(GL_TEXTURE_GEN_T);
\r
679 void OnUnsetMaterial() override
\r
681 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
683 glDisable(GL_TEXTURE_GEN_S);
\r
684 glDisable(GL_TEXTURE_GEN_T);
\r
689 video::COpenGLDriver* Driver;
\r
693 //! reflection 2 layer material renderer
\r
694 class COpenGLMaterialRenderer_REFLECTION_2_LAYER : public IMaterialRenderer
\r
698 COpenGLMaterialRenderer_REFLECTION_2_LAYER(video::COpenGLDriver* d) : Driver(d) {}
\r
700 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
701 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
703 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
704 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
706 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
708 Driver->disableTextures(2);
\r
709 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
711 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
713 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
715 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
717 #ifdef GL_ARB_texture_env_combine
\r
718 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
719 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
720 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
721 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
723 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
724 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
725 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
726 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
729 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
\r
730 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
\r
731 glEnable(GL_TEXTURE_GEN_S);
\r
732 glEnable(GL_TEXTURE_GEN_T);
\r
737 void OnUnsetMaterial() override
\r
739 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
741 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
743 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
744 glDisable(GL_TEXTURE_GEN_S);
\r
745 glDisable(GL_TEXTURE_GEN_T);
\r
751 video::COpenGLDriver* Driver;
\r
755 //! reflection 2 layer material renderer
\r
756 class COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public IMaterialRenderer
\r
760 COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(video::COpenGLDriver* d) : Driver(d) {}
\r
762 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
763 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
765 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
766 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
768 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
770 Driver->disableTextures(2);
\r
771 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
773 Driver->getCacheHandler()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
\r
774 Driver->getCacheHandler()->setBlend(true);
\r
776 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
778 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
780 #ifdef GL_ARB_texture_env_combine
\r
781 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
782 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
783 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
784 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
785 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
786 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
\r
788 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
789 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
790 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
791 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
792 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
793 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
\r
795 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
797 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
798 #ifdef GL_ARB_texture_env_combine
\r
799 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
800 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
801 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
802 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
803 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
804 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
\r
806 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
807 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
808 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
809 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
810 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
811 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
\r
814 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
\r
815 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
\r
816 glEnable(GL_TEXTURE_GEN_S);
\r
817 glEnable(GL_TEXTURE_GEN_T);
\r
822 void OnUnsetMaterial() override
\r
824 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
826 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
828 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
830 glDisable(GL_TEXTURE_GEN_S);
\r
831 glDisable(GL_TEXTURE_GEN_T);
\r
834 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
836 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
838 Driver->getCacheHandler()->setBlend(false);
\r
841 //! Returns if the material is transparent.
\r
842 bool isTransparent() const override
\r
849 video::COpenGLDriver* Driver;
\r
852 } // end namespace video
\r
853 } // end namespace irr
\r