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 #include "IrrCompileConfig.h"
\r
9 #ifdef _IRR_COMPILE_WITH_OPENGL_
\r
11 #include "IMaterialRenderer.h"
\r
13 #include "COpenGLDriver.h"
\r
14 #include "COpenGLCacheHandler.h"
\r
21 //! Solid material renderer
\r
22 class COpenGLMaterialRenderer_SOLID : public IMaterialRenderer
\r
26 COpenGLMaterialRenderer_SOLID(video::COpenGLDriver* d) : Driver(d) {}
\r
28 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
29 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
31 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
32 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
34 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
36 Driver->disableTextures(1);
\r
37 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
42 video::COpenGLDriver* Driver;
\r
46 //! Generic Texture Blend
\r
47 class COpenGLMaterialRenderer_ONETEXTURE_BLEND : public IMaterialRenderer
\r
51 COpenGLMaterialRenderer_ONETEXTURE_BLEND(video::COpenGLDriver* d) : Driver(d) {}
\r
53 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
54 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
56 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
57 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
59 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
61 Driver->disableTextures(1);
\r
62 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
64 // if (material.MaterialType != lastMaterial.MaterialType ||
\r
65 // material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
\r
66 // resetAllRenderstates)
\r
68 E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
\r
69 E_MODULATE_FUNC modulate;
\r
71 unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
\r
73 Driver->getCacheHandler()->setBlend(true);
\r
75 if (Driver->queryFeature(EVDF_BLEND_SEPARATE))
\r
77 Driver->getCacheHandler()->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
\r
78 Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
\r
82 Driver->getCacheHandler()->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
\r
85 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
87 #ifdef GL_ARB_texture_env_combine
\r
88 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
89 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
90 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
91 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
92 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (f32) modulate );
\r
94 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
95 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
96 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
97 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
98 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate );
\r
101 if (textureBlendFunc_hasAlpha(srcRGBFact) || textureBlendFunc_hasAlpha(dstRGBFact) ||
\r
102 textureBlendFunc_hasAlpha(srcAlphaFact) || textureBlendFunc_hasAlpha(dstAlphaFact))
\r
104 if (alphaSource==EAS_VERTEX_COLOR)
\r
106 #ifdef GL_ARB_texture_env_combine
\r
107 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
108 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
\r
110 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
111 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
\r
114 else if (alphaSource==EAS_TEXTURE)
\r
116 #ifdef GL_ARB_texture_env_combine
\r
117 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
118 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
\r
120 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
121 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
\r
126 #ifdef GL_ARB_texture_env_combine
\r
127 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
\r
128 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
\r
129 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
\r
131 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
\r
132 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
\r
133 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE);
\r
140 void OnUnsetMaterial() override
\r
142 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
144 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
146 #ifdef GL_ARB_texture_env_combine
\r
147 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
\r
148 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f );
\r
149 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
151 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
\r
152 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
\r
153 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
156 Driver->getCacheHandler()->setBlend(false);
\r
159 //! Returns if the material is transparent.
\r
160 /** Is not always transparent, but mostly. */
\r
161 bool isTransparent() const override
\r
168 video::COpenGLDriver* Driver;
\r
172 //! Solid 2 layer material renderer
\r
173 class COpenGLMaterialRenderer_SOLID_2_LAYER : public IMaterialRenderer
\r
177 COpenGLMaterialRenderer_SOLID_2_LAYER(video::COpenGLDriver* d) : Driver(d) {}
\r
179 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
180 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
182 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
183 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
185 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
187 Driver->disableTextures(2);
\r
188 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
190 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
192 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
194 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
195 #ifdef GL_ARB_texture_env_combine
\r
196 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
197 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
198 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
\r
199 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE);
\r
200 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
201 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
202 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR);
\r
203 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
\r
205 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
206 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
207 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
\r
208 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE);
\r
209 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
210 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
211 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR);
\r
212 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
\r
218 void OnUnsetMaterial() override
\r
220 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
222 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
224 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
226 #ifdef GL_ARB_texture_env_combine
\r
227 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
\r
229 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
\r
236 video::COpenGLDriver* Driver;
\r
240 //! Transparent add color material renderer
\r
241 class COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR : public IMaterialRenderer
\r
245 COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(video::COpenGLDriver* d) : Driver(d) {}
\r
247 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
248 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
250 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
251 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
253 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
255 Driver->disableTextures(1);
\r
256 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
258 Driver->getCacheHandler()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
\r
259 Driver->getCacheHandler()->setBlend(true);
\r
262 void OnUnsetMaterial() override
\r
264 Driver->getCacheHandler()->setBlend(false);
\r
267 //! Returns if the material is transparent.
\r
268 bool isTransparent() const override
\r
275 video::COpenGLDriver* Driver;
\r
279 //! Transparent vertex alpha material renderer
\r
280 class COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public IMaterialRenderer
\r
284 COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(video::COpenGLDriver* d) : Driver(d) {}
\r
286 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
287 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
289 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
290 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
292 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
294 Driver->disableTextures(1);
\r
295 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
297 Driver->getCacheHandler()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
\r
298 Driver->getCacheHandler()->setBlend(true);
\r
300 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
302 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
304 #ifdef GL_ARB_texture_env_combine
\r
305 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
306 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
307 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
\r
308 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
309 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
310 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
312 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
313 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
314 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT );
\r
315 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
316 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
317 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
322 void OnUnsetMaterial() override
\r
324 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
326 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
327 #ifdef GL_ARB_texture_env_combine
\r
328 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
\r
329 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE );
\r
331 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
\r
332 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
\r
335 Driver->getCacheHandler()->setBlend(false);
\r
338 //! Returns if the material is transparent.
\r
339 bool isTransparent() const override
\r
346 video::COpenGLDriver* Driver;
\r
350 //! Transparent alpha channel material renderer
\r
351 class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public IMaterialRenderer
\r
355 COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(video::COpenGLDriver* d) : Driver(d) {}
\r
357 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
358 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
360 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
361 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
363 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
365 Driver->disableTextures(1);
\r
366 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
368 Driver->getCacheHandler()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
\r
369 Driver->getCacheHandler()->setBlend(true);
\r
370 Driver->getCacheHandler()->setAlphaTest(true);
\r
371 Driver->getCacheHandler()->setAlphaFunc(GL_GREATER, material.MaterialTypeParam);
\r
373 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates || material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
\r
375 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
377 #ifdef GL_ARB_texture_env_combine
\r
378 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
379 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
380 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
381 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
382 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
383 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
\r
385 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
386 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
387 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
388 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
389 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
390 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
\r
395 void OnUnsetMaterial() override
\r
397 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
399 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
400 #ifdef GL_ARB_texture_env_combine
\r
401 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
\r
403 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
\r
405 Driver->getCacheHandler()->setAlphaTest(false);
\r
406 Driver->getCacheHandler()->setBlend(false);
\r
409 //! Returns if the material is transparent.
\r
410 bool isTransparent() const override
\r
417 video::COpenGLDriver* Driver;
\r
421 //! Transparent alpha channel material renderer
\r
422 class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public IMaterialRenderer
\r
426 COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(video::COpenGLDriver* d) : Driver(d) {}
\r
428 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
429 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
431 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
432 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
434 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
436 Driver->disableTextures(1);
\r
437 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
439 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
441 Driver->getCacheHandler()->setAlphaTest(true);
\r
442 Driver->getCacheHandler()->setAlphaFunc(GL_GREATER, 0.5f);
\r
446 void OnUnsetMaterial() override
\r
448 Driver->getCacheHandler()->setAlphaTest(false);
\r
451 //! Returns if the material is transparent.
\r
452 bool isTransparent() const override
\r
454 return false; // this material is not really transparent because it does no blending.
\r
459 video::COpenGLDriver* Driver;
\r
463 //! material renderer for all kinds of lightmaps
\r
464 class COpenGLMaterialRenderer_LIGHTMAP : public IMaterialRenderer
\r
468 COpenGLMaterialRenderer_LIGHTMAP(video::COpenGLDriver* d) : Driver(d) {}
\r
470 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
471 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
473 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
474 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
476 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
478 Driver->disableTextures(2);
\r
479 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
481 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
483 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
487 switch (material.MaterialType)
\r
489 case EMT_LIGHTMAP_LIGHTING:
\r
490 case EMT_LIGHTMAP_LIGHTING_M2:
\r
491 case EMT_LIGHTMAP_LIGHTING_M4:
\r
492 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
494 case EMT_LIGHTMAP_ADD:
\r
496 case EMT_LIGHTMAP_M2:
\r
497 case EMT_LIGHTMAP_M4:
\r
499 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
\r
503 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
507 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
508 #ifdef GL_ARB_texture_env_combine
\r
509 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
511 if (material.MaterialType == EMT_LIGHTMAP_ADD)
\r
512 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
\r
514 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
516 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
517 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
518 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
\r
519 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
\r
520 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);
\r
522 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
524 if (material.MaterialType == EMT_LIGHTMAP_ADD)
\r
525 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
\r
527 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
529 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
530 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
531 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
\r
532 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
\r
533 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT);
\r
536 switch (material.MaterialType)
\r
538 case EMT_LIGHTMAP_M4:
\r
539 case EMT_LIGHTMAP_LIGHTING_M4:
\r
540 #ifdef GL_ARB_texture_env_combine
\r
541 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 4.0f);
\r
543 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 4.0f);
\r
546 case EMT_LIGHTMAP_M2:
\r
547 case EMT_LIGHTMAP_LIGHTING_M2:
\r
548 #ifdef GL_ARB_texture_env_combine
\r
549 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2.0f);
\r
551 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f);
\r
555 #ifdef GL_ARB_texture_env_combine
\r
556 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0f);
\r
558 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f);
\r
565 void OnUnsetMaterial() override
\r
567 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
569 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
571 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
572 #ifdef GL_ARB_texture_env_combine
\r
573 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f );
\r
575 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f );
\r
579 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
580 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
585 video::COpenGLDriver* Driver;
\r
590 //! detail map material renderer
\r
591 class COpenGLMaterialRenderer_DETAIL_MAP : public IMaterialRenderer
\r
595 COpenGLMaterialRenderer_DETAIL_MAP(video::COpenGLDriver* d) : Driver(d) {}
\r
597 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
598 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
600 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
601 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
603 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
605 Driver->disableTextures(2);
\r
606 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
608 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
610 // detail map on second layer
\r
611 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
613 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
615 #ifdef GL_ARB_texture_env_combine
\r
616 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
617 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
\r
618 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
619 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
621 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
622 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_EXT);
\r
623 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
624 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
630 void OnUnsetMaterial() override
\r
632 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
634 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
636 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
642 video::COpenGLDriver* Driver;
\r
646 //! sphere map material renderer
\r
647 class COpenGLMaterialRenderer_SPHERE_MAP : public IMaterialRenderer
\r
651 COpenGLMaterialRenderer_SPHERE_MAP(video::COpenGLDriver* d) : Driver(d) {}
\r
653 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
654 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
656 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
657 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
659 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
661 Driver->disableTextures(1);
\r
662 // texture needs to be flipped for OpenGL
\r
663 core::matrix4 tmp = Driver->getTransform(ETS_TEXTURE_0);
\r
665 Driver->setTransform(ETS_TEXTURE_0, tmp);
\r
666 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
668 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
670 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
672 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
\r
673 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
\r
675 glEnable(GL_TEXTURE_GEN_S);
\r
676 glEnable(GL_TEXTURE_GEN_T);
\r
680 void OnUnsetMaterial() override
\r
682 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
684 glDisable(GL_TEXTURE_GEN_S);
\r
685 glDisable(GL_TEXTURE_GEN_T);
\r
690 video::COpenGLDriver* Driver;
\r
694 //! reflection 2 layer material renderer
\r
695 class COpenGLMaterialRenderer_REFLECTION_2_LAYER : public IMaterialRenderer
\r
699 COpenGLMaterialRenderer_REFLECTION_2_LAYER(video::COpenGLDriver* d) : Driver(d) {}
\r
701 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
702 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
704 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
705 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
707 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
709 Driver->disableTextures(2);
\r
710 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
712 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
714 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
716 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
718 #ifdef GL_ARB_texture_env_combine
\r
719 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
720 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
721 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
722 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
724 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
725 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
726 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
727 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
730 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
\r
731 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
\r
732 glEnable(GL_TEXTURE_GEN_S);
\r
733 glEnable(GL_TEXTURE_GEN_T);
\r
738 void OnUnsetMaterial() override
\r
740 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
742 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
744 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
745 glDisable(GL_TEXTURE_GEN_S);
\r
746 glDisable(GL_TEXTURE_GEN_T);
\r
752 video::COpenGLDriver* Driver;
\r
756 //! reflection 2 layer material renderer
\r
757 class COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public IMaterialRenderer
\r
761 COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(video::COpenGLDriver* d) : Driver(d) {}
\r
763 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
\r
764 bool resetAllRenderstates, IMaterialRendererServices* services) override
\r
766 if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_DISABLE)
\r
767 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE_TO_ENABLE);
\r
769 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE);
\r
771 Driver->disableTextures(2);
\r
772 Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
\r
774 Driver->getCacheHandler()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
\r
775 Driver->getCacheHandler()->setBlend(true);
\r
777 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
\r
779 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
781 #ifdef GL_ARB_texture_env_combine
\r
782 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
783 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
784 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
785 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
786 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
787 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
\r
789 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
790 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
791 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
792 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
793 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
794 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
\r
796 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
798 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
799 #ifdef GL_ARB_texture_env_combine
\r
800 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
\r
801 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
\r
802 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
\r
803 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
\r
804 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
\r
805 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
\r
807 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
\r
808 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
\r
809 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
\r
810 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
\r
811 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
\r
812 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB);
\r
815 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
\r
816 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
\r
817 glEnable(GL_TEXTURE_GEN_S);
\r
818 glEnable(GL_TEXTURE_GEN_T);
\r
823 void OnUnsetMaterial() override
\r
825 if (Driver->queryFeature(EVDF_MULTITEXTURE))
\r
827 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE1_ARB);
\r
829 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
831 glDisable(GL_TEXTURE_GEN_S);
\r
832 glDisable(GL_TEXTURE_GEN_T);
\r
835 Driver->getCacheHandler()->setActiveTexture(GL_TEXTURE0_ARB);
\r
837 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
839 Driver->getCacheHandler()->setBlend(false);
\r
842 //! Returns if the material is transparent.
\r
843 bool isTransparent() const override
\r
850 video::COpenGLDriver* Driver;
\r
853 } // end namespace video
\r
854 } // end namespace irr
\r