1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013-2014 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdopengl.h"
22 #include "driver_opengl.h"
23 #include "nel/3d/texture_cube.h"
24 #include "nel/3d/texture_bloom.h"
25 #include "nel/misc/rect.h"
26 #include "nel/misc/file.h" // temp
28 // Define this to force nearest filter (debug)
29 // #define NEL_FORCE_NEAREST
31 using namespace NLMISC
;
38 //#define NEL_DUMP_UPLOAD_TIME
41 #ifdef NEL_DUMP_UPLOAD_TIME
42 #define NEL_MEASURE_UPLOAD_TIME_START NLMISC::TTicks startTick = CTime::getPerformanceTime();
43 #define NEL_MEASURE_UPLOAD_TIME_END NLMISC::TTicks endTick = CTime::getPerformanceTime(); \
44 nlinfo("3D: upload time = %.2f ms", (float) (1000 * (CTime::ticksToSecond(endTick) - CTime::ticksToSecond(startTick))));
46 #define NEL_MEASURE_UPLOAD_TIME_START
47 #define NEL_MEASURE_UPLOAD_TIME_END
54 namespace NLDRIVERGLES
{
56 namespace NLDRIVERGL
{
60 // ***************************************************************************
61 CTextureDrvInfosGL::CTextureDrvInfosGL(IDriver
*drv
, ItTexDrvInfoPtrMap it
, CDriverGL
*drvGl
, bool isRectangleTexture
) : ITextureDrvInfos(drv
, it
)
63 H_AUTO_OGL(CTextureDrvInfosGL_CTextureDrvInfosGL
)
64 //nldebug("3D: CTextureDrvInfosGL::ctor()");
65 // The id is auto created here.
72 // Nb: at Driver dtor, all tex infos are deleted, so _Driver is always valid.
76 TextureMode
= GL_TEXTURE_2D
;
78 TextureMode
= isRectangleTexture
?GL_TEXTURE_RECTANGLE_NV
:GL_TEXTURE_2D
;
83 AttachDepthStencil
= true;
87 // ***************************************************************************
88 CTextureDrvInfosGL::~CTextureDrvInfosGL()
90 H_AUTO_OGL(CTextureDrvInfosGL_CTextureDrvInfosGLDtor
)
91 // The id is auto deleted here.
92 glDeleteTextures(1,&ID
);
94 // release profiling texture mem.
95 _Driver
->_AllocatedTextureMemory
-= TextureMemory
;
97 // release in TextureUsed.
98 if (TextureUsedIdx
< _Driver
->_TextureUsed
.size() && _Driver
->_TextureUsed
[TextureUsedIdx
] == this)
100 _Driver
->_TextureUsed
[TextureUsedIdx
] = NULL
;
104 CDepthStencilFBO::CDepthStencilFBO(CDriverGL
*driver
, uint width
, uint height
)
106 //nldebug("3D: Init shared FBO");
112 bool packedDepthStencil
= driver
->supportPackedDepthStencil();
113 nglGenRenderbuffersEXT(1, &DepthFBOId
);
114 if (packedDepthStencil
)
115 StencilFBOId
= DepthFBOId
;
117 nglGenRenderbuffersEXT(1, &StencilFBOId
);
119 if (packedDepthStencil
)
121 //nldebug("3D: using packed depth stencil");
122 nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT
, StencilFBOId
);
123 nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT
, GL_DEPTH24_STENCIL8_EXT
, width
, height
);
127 nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT
, DepthFBOId
);
128 nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT
, GL_DEPTH_COMPONENT24
, width
, height
);
130 nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId);
131 nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, width, height);
135 nlassert(DepthFBOId
);
136 nlassert(StencilFBOId
);
138 driver
->_DepthStencilFBOs
.push_back(this);
141 CDepthStencilFBO::~CDepthStencilFBO()
144 m_Driver
->_DepthStencilFBOs
.erase(std::find(m_Driver
->_DepthStencilFBOs
.begin(), m_Driver
->_DepthStencilFBOs
.end(), this));
148 //nldebug("3D: Release shared FBO");
149 nglDeleteRenderbuffersEXT(1, &DepthFBOId
);
150 if (StencilFBOId
== DepthFBOId
)
156 nglDeleteRenderbuffersEXT(1, &StencilFBOId
);
161 // ***************************************************************************
162 bool CTextureDrvInfosGL::initFrameBufferObject(ITexture
* tex
)
166 if (tex
->isBloomTexture())
168 AttachDepthStencil
= !((CTextureBloom
*)tex
)->isMode2D();
172 nglGenFramebuffersEXT(1, &FBOId
);
174 //nldebug("3D: using depth %d and stencil %d", DepthFBOId, StencilFBOId);
177 nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, FBOId
);
178 nglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT
, GL_COLOR_ATTACHMENT0_EXT
, TextureMode
, ID
, 0);
180 // attach depth stencil
181 if (AttachDepthStencil
)
183 for (std::vector
<CDepthStencilFBO
*>::iterator
it(_Driver
->_DepthStencilFBOs
.begin()), end(_Driver
->_DepthStencilFBOs
.end()); it
!= end
; ++it
)
185 if ((*it
)->Width
== tex
->getWidth() && (*it
)->Height
== tex
->getHeight())
187 DepthStencilFBO
= (*it
);
191 if (!DepthStencilFBO
)
193 DepthStencilFBO
= new CDepthStencilFBO(_Driver
, tex
->getWidth(), tex
->getHeight());
195 nglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
, GL_DEPTH_ATTACHMENT_EXT
,
196 GL_RENDERBUFFER_EXT
, DepthStencilFBO
->DepthFBOId
);
197 //nldebug("3D: glFramebufferRenderbufferExt(depth:24) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
198 nglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
, GL_STENCIL_ATTACHMENT_EXT
,
199 GL_RENDERBUFFER_EXT
, DepthStencilFBO
->StencilFBOId
);
200 //nldebug("3D: glFramebufferRenderbufferExt(stencil:8) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
204 GLenum status
= (GLenum
) nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT
);
207 #ifdef GL_FRAMEBUFFER_COMPLETE_EXT
208 case GL_FRAMEBUFFER_COMPLETE_EXT
:
212 #ifdef GL_FRAMEBUFFER_COMPLETE_OES
213 case GL_FRAMEBUFFER_COMPLETE_OES
:
217 #ifdef GL_FRAMEBUFFER_UNSUPPORTED_EXT
218 case GL_FRAMEBUFFER_UNSUPPORTED_EXT
:
219 nlwarning("Unsupported framebuffer format");
222 #ifdef GL_FRAMEBUFFER_UNSUPPORTED_OES
223 case GL_FRAMEBUFFER_UNSUPPORTED_OES
:
224 nlwarning("Unsupported framebuffer format");
227 #ifdef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
228 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
:
229 nlwarning("Framebuffer incomplete attachment");
232 #ifdef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES
233 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES
:
234 nlwarning("Framebuffer incomplete attachment");
237 #ifdef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
238 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
:
239 nlwarning("Framebuffer incomplete, missing attachment");
242 #ifdef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES
243 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES
:
244 nlwarning("Framebuffer incomplete, missing attachment");
247 #ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
248 case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
:
249 nlwarning("Framebuffer incomplete, duplicate attachment");
252 #ifdef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
253 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
:
254 nlwarning("Framebuffer incomplete, attached images must have same dimensions");
257 #ifdef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES
258 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES
:
259 nlwarning("Framebuffer incomplete, attached images must have same dimensions");
262 #ifdef GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
263 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
:
264 nlwarning("Framebuffer incomplete, attached images must have same format");
267 #ifdef GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES
268 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES
:
269 nlwarning("Framebuffer incomplete, attached images must have same format");
272 #ifdef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
273 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
:
274 nlwarning("Framebuffer incomplete, missing draw buffer");
277 #ifdef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
278 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
:
279 nlwarning("Framebuffer incomplete, missing read buffer");
282 #ifdef GL_FRAMEBUFFER_BINDING_EXT
283 case GL_FRAMEBUFFER_BINDING_EXT
:
284 nlwarning("Framebuffer BINDING_EXT");
287 #ifdef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
288 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
:
289 nlwarning("Framebuffer incomplete multisample");
292 #ifdef GL_FRAMEBUFFER_BINDING_OES
293 case GL_FRAMEBUFFER_BINDING_OES
:
294 nlwarning("Framebuffer BINDING_EXT");
298 nlwarning("Framebuffer incomplete status %d", (sint
)status
);
302 // clean up resources if allocation failed
305 nglDeleteFramebuffersEXT(1, &FBOId
);
307 if (AttachDepthStencil
)
309 DepthStencilFBO
= NULL
;
318 // ***************************************************************************
319 bool CTextureDrvInfosGL::activeFrameBufferObject(ITexture
* tex
)
323 if(initFrameBufferObject(tex
))
325 glBindTexture(TextureMode
, 0);
326 nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, FBOId
);
333 nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, 0);
339 // ***************************************************************************
340 // Get the glText mirror of an existing setuped texture.
341 static inline CTextureDrvInfosGL
* getTextureGl(ITexture
& tex
)
343 H_AUTO_OGL(getTextureGl
)
344 CTextureDrvInfosGL
* gltex
;
345 gltex
= (CTextureDrvInfosGL
*)(ITextureDrvInfos
*)(tex
.TextureDrvShare
->DrvTexture
);
349 // ***************************************************************************
350 // Translation of TexFmt mode.
351 GLint
CDriverGL::getGlTextureFormat(ITexture
& tex
, bool &compressed
)
353 H_AUTO_OGL(CDriverGL_getGlTextureFormat
)
354 ITexture::TUploadFormat texfmt
= tex
.getUploadFormat();
356 // If auto, retrieve the pixel format of the bitmap.
357 if(texfmt
== ITexture::Auto
)
359 switch(tex
.getPixelFormat())
362 if(_ForceDXTCCompression
&& tex
.allowDegradation() )
363 texfmt
= ITexture::DXTC5
;
365 texfmt
= ITexture::RGBA8888
;
367 case CBitmap::DXTC1
: texfmt
= ITexture::DXTC1
; break;
368 case CBitmap::DXTC1Alpha
: texfmt
= ITexture::DXTC1Alpha
; break;
369 case CBitmap::DXTC3
: texfmt
= ITexture::DXTC3
; break;
370 case CBitmap::DXTC5
: texfmt
= ITexture::DXTC5
; break;
371 case CBitmap::Luminance
: texfmt
= ITexture::Luminance
; break;
372 case CBitmap::Alpha
: texfmt
= ITexture::Alpha
; break;
373 case CBitmap::AlphaLuminance
: texfmt
= ITexture::AlphaLuminance
; break;
374 case CBitmap::DsDt
: texfmt
= ITexture::DsDt
; break;
375 default: texfmt
= ITexture::RGBA8888
; break;
379 // Get gl tex format, try S3TC compressed ones.
380 if(_Extensions
.EXTTextureCompressionS3TC
)
383 // Try Compressed ones.
386 #ifdef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
387 case ITexture::DXTC1
: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT
;
389 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
390 case ITexture::DXTC1Alpha
: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
;
392 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
393 case ITexture::DXTC3
: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
;
395 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
396 case ITexture::DXTC5
: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
;
402 // Get standard gl tex format.
407 case ITexture::RGBA8888
: return GL_RGBA
;
408 // case ITexture::RGBA4444: return GL_RGBA4_OES;
409 // case ITexture::RGBA5551: return GL_RGB5_A1_OES;
410 case ITexture::RGB888
: return GL_RGB
;
411 // case ITexture::RGB565: return GL_RGB5_OES;
412 case ITexture::Luminance
: return GL_LUMINANCE
;
413 case ITexture::Alpha
: return GL_ALPHA
;
414 case ITexture::AlphaLuminance
: return GL_LUMINANCE_ALPHA
;
416 case ITexture::RGBA8888
: return GL_RGBA8
;
417 case ITexture::RGBA4444
: return GL_RGBA4
;
418 case ITexture::RGBA5551
: return GL_RGB5_A1
;
419 case ITexture::RGB888
: return GL_RGB8
;
420 case ITexture::RGB565
: return GL_RGB5
;
421 case ITexture::Luminance
: return GL_LUMINANCE8
;
422 case ITexture::Alpha
: return GL_ALPHA8
;
423 case ITexture::AlphaLuminance
: return GL_LUMINANCE8_ALPHA8
;
425 if (_Extensions
.NVTextureShader
) return GL_DSDT_NV
;
426 else if (_Extensions
.ATIEnvMapBumpMap
|| _Extensions
.ATIFragmentShader
)
428 return GL_DU8DV8_ATI
;
444 // ***************************************************************************
445 static GLint
getGlSrcTextureFormat(ITexture
&tex
, GLint glfmt
)
447 H_AUTO_OGL(getGlSrcTextureFormat
)
449 // Is destination format is alpha or lumiance ?
450 if ((glfmt
==GL_ALPHA8
)||(glfmt
==GL_LUMINANCE8_ALPHA8
)||(glfmt
==GL_LUMINANCE8
))
452 switch(tex
.getPixelFormat())
454 case CBitmap::Alpha
: return GL_ALPHA
;
455 case CBitmap::AlphaLuminance
: return GL_LUMINANCE_ALPHA
;
456 case CBitmap::Luminance
: return GL_LUMINANCE
;
462 if (glfmt
== GL_DSDT_NV
)
467 if (glfmt
== GL_DU8DV8_ATI
)
473 // Else, not a Src format for upload, or RGBA.
477 // ***************************************************************************
478 static GLenum
getGlSrcTextureComponentType(GLint texSrcFormat
)
480 H_AUTO_OGL(getGlSrcTextureComponentType
);
483 switch (texSrcFormat
)
487 return GL_BYTE
; // these are signed format
494 return GL_UNSIGNED_BYTE
;
497 // ***************************************************************************
498 uint
CDriverGL::computeMipMapMemoryUsage(uint w
, uint h
, GLint glfmt
) const
500 H_AUTO_OGL(CDriverGL_computeMipMapMemoryUsage
)
503 case GL_RGBA8
: return w
*h
* 4;
504 // Well this is ugly, but simple :). GeForce 888 is stored as 32 bits.
505 case GL_RGB8
: return w
*h
* 4;
507 case GL_RGBA4
: return w
*h
* 2;
510 case GL_RGB5_A1
: return w
*h
* 2;
513 case GL_RGB5
: return w
*h
* 2;
515 case GL_LUMINANCE8
: return w
*h
* 1;
516 case GL_ALPHA8
: return w
*h
* 1;
517 case GL_LUMINANCE8_ALPHA8
: return w
*h
* 2;
518 #ifdef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
519 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
: return w
*h
/2;
521 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
522 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
: return w
*h
/2;
524 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
525 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
: return w
*h
* 1;
527 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
528 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
: return w
*h
* 1;
534 case GL_DSDT_NV
: return w
*h
* 2;
538 // One format has not been coded.
545 // ***************************************************************************
546 // Translation of Wrap mode.
547 static inline GLenum
translateWrapToGl(ITexture::TWrapMode mode
, const CGlExtensions
&extensions
)
549 H_AUTO_OGL(translateWrapToGl
)
550 if(mode
== ITexture::Repeat
)
554 return GL_CLAMP_TO_EDGE
;
556 if(extensions
.Version1_2
)
557 return GL_CLAMP_TO_EDGE
;
563 // ***************************************************************************
564 static inline GLenum
translateMagFilterToGl(CTextureDrvInfosGL
*glText
)
566 H_AUTO_OGL(translateMagFilterToGl
)
567 #ifdef NEL_FORCE_NEAREST
569 #else // NEL_FORCE_NEAREST
570 switch(glText
->MagFilter
)
572 case ITexture::Linear
: return GL_LINEAR
;
573 case ITexture::Nearest
: return GL_NEAREST
;
579 #endif // NEL_FORCE_NEAREST
583 // ***************************************************************************
584 static inline GLenum
translateMinFilterToGl(CTextureDrvInfosGL
*glText
)
586 H_AUTO_OGL(translateMinFilterToGl
)
587 #ifdef NEL_FORCE_NEAREST
589 #else // NEL_FORCE_NEAREST
593 switch(glText
->MinFilter
)
595 case ITexture::NearestMipMapOff
: return GL_NEAREST
;
596 case ITexture::NearestMipMapNearest
: return GL_NEAREST_MIPMAP_NEAREST
;
597 case ITexture::NearestMipMapLinear
: return GL_NEAREST_MIPMAP_LINEAR
;
598 case ITexture::LinearMipMapOff
: return GL_LINEAR
;
599 case ITexture::LinearMipMapNearest
: return GL_LINEAR_MIPMAP_NEAREST
;
600 case ITexture::LinearMipMapLinear
: return GL_LINEAR_MIPMAP_LINEAR
;
606 switch(glText
->MinFilter
)
608 case ITexture::NearestMipMapOff
:
609 case ITexture::NearestMipMapNearest
:
610 case ITexture::NearestMipMapLinear
:
612 case ITexture::LinearMipMapOff
:
613 case ITexture::LinearMipMapNearest
:
614 case ITexture::LinearMipMapLinear
:
622 #endif // NEL_FORCE_NEAREST
625 // ***************************************************************************
626 static inline bool sameDXTCFormat(ITexture
&tex
, GLint glfmt
)
628 H_AUTO_OGL(sameDXTCFormat
);
630 #ifdef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
631 if(glfmt
==GL_COMPRESSED_RGB_S3TC_DXT1_EXT
&& tex
.PixelFormat
==CBitmap::DXTC1
)
635 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
636 if(glfmt
==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
&& tex
.PixelFormat
==CBitmap::DXTC1Alpha
)
640 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
641 if(glfmt
==GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
&& tex
.PixelFormat
==CBitmap::DXTC3
)
645 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
646 if(glfmt
==GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
&& tex
.PixelFormat
==CBitmap::DXTC5
)
653 // ***************************************************************************
654 static inline bool isDXTCFormat(GLint glfmt
)
656 H_AUTO_OGL(isDXTCFormat
);
658 #ifdef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
659 if(glfmt
==GL_COMPRESSED_RGB_S3TC_DXT1_EXT
)
663 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
664 if(glfmt
==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
)
668 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
669 if(glfmt
==GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
)
673 #ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
674 if(glfmt
==GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
)
681 // ***************************************************************************
682 bool CDriverGL::setupTexture (ITexture
& tex
)
684 H_AUTO_OGL(setupTexture
)
686 return setupTextureEx (tex
, true, nTmp
);
689 // ***************************************************************************
693 void CDriverGL::bindTextureWithMode(ITexture
&tex
)
695 CTextureDrvInfosGL
* gltext
;
696 gltext
= getTextureGl(tex
);
697 // system of "backup the previous binded texture" seems to not work with some drivers....
698 _DriverGLStates
.activeTextureARB(0);
699 if(tex
.isTextureCube())
701 if (_Extensions
.ARBTextureCubeMap
)
703 _DriverGLStates
.setTextureMode(CDriverGLStates::TextureCubeMap
);
705 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB
, gltext
->ID
);
710 CDriverGLStates::TTextureMode textureMode
= CDriverGLStates::Texture2D
;
712 if(gltext
->TextureMode
== GL_TEXTURE_RECTANGLE_NV
)
713 textureMode
= CDriverGLStates::TextureRect
;
716 _DriverGLStates
.setTextureMode(textureMode
);
718 glBindTexture(gltext
->TextureMode
, gltext
->ID
);
722 // ***************************************************************************
726 void CDriverGL::setupTextureBasicParameters(ITexture
&tex
)
728 CTextureDrvInfosGL
* gltext
;
729 gltext
= getTextureGl(tex
);
730 // TODO: possible cache here, but beware, this is called just after texture creation as well, so these fields
731 // haven't ever been filled.
732 gltext
->WrapS
= tex
.getWrapS();
733 gltext
->WrapT
= tex
.getWrapT();
734 gltext
->MagFilter
= tex
.getMagFilter();
735 gltext
->MinFilter
= tex
.getMinFilter();
736 if(tex
.isTextureCube())
738 if (_Extensions
.ARBTextureCubeMap
)
740 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,GL_TEXTURE_WRAP_S
, translateWrapToGl(ITexture::Clamp
, _Extensions
));
741 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,GL_TEXTURE_WRAP_T
, translateWrapToGl(ITexture::Clamp
, _Extensions
));
743 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,GL_TEXTURE_WRAP_R
, translateWrapToGl(ITexture::Clamp
, _Extensions
));
745 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,GL_TEXTURE_MAG_FILTER
, translateMagFilterToGl(gltext
));
746 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,GL_TEXTURE_MIN_FILTER
, translateMinFilterToGl(gltext
));
748 if (_AnisotropicFilter
> 1.f
&& gltext
->MinFilter
> ITexture::NearestMipMapLinear
)
749 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
, GL_TEXTURE_MAX_ANISOTROPY_EXT
, _AnisotropicFilter
);
754 glTexParameteri(gltext
->TextureMode
,GL_TEXTURE_WRAP_S
, translateWrapToGl(gltext
->WrapS
, _Extensions
));
755 glTexParameteri(gltext
->TextureMode
,GL_TEXTURE_WRAP_T
, translateWrapToGl(gltext
->WrapT
, _Extensions
));
756 glTexParameteri(gltext
->TextureMode
,GL_TEXTURE_MAG_FILTER
, translateMagFilterToGl(gltext
));
757 glTexParameteri(gltext
->TextureMode
,GL_TEXTURE_MIN_FILTER
, translateMinFilterToGl(gltext
));
759 if (_AnisotropicFilter
> 1.f
&& gltext
->MinFilter
> ITexture::NearestMipMapLinear
)
760 glTexParameteri(gltext
->TextureMode
, GL_TEXTURE_MAX_ANISOTROPY_EXT
, _AnisotropicFilter
);
763 tex
.clearFilterOrWrapModeTouched();
766 // ***************************************************************************
767 bool CDriverGL::setupTextureEx (ITexture
& tex
, bool bUpload
, bool &bAllUploaded
, bool bMustRecreateSharedTexture
)
769 H_AUTO_OGL(setupTextureEx
)
770 //nldebug("3D: CDriverGL::setupTextureEx(%016p, %d, %d, %d)", &tex, bUpload, bAllUploaded, bMustRecreateSharedTexture);
771 bAllUploaded
= false;
773 if(tex
.isTextureCube() && (!_Extensions
.ARBTextureCubeMap
))
776 // 0. Create/Retrieve the driver texture.
777 //=======================================
778 bool mustCreate
= false;
779 if ( !tex
.TextureDrvShare
)
781 //nldebug("3D: creating CTextureDrvShare()");
782 // insert into driver list. (so it is deleted when driver is deleted).
783 ItTexDrvSharePtrList it
= _TexDrvShares
.insert(_TexDrvShares
.end(), (NL3D::CTextureDrvShare
*)NULL
);
784 // create and set iterator, for future deletion.
785 *it
= tex
.TextureDrvShare
= new CTextureDrvShare(this, it
, &tex
);
787 // Must (re)-create the texture.
791 // Does the texture has been touched ?
792 if ( (!tex
.touched()) && (!mustCreate
) )
794 // if wrap mode or filter mode is touched, update it here
795 if (tex
.filterOrWrapModeTouched())
797 activateTexture(0, NULL
); // unbind any previous texture
798 bindTextureWithMode(tex
);
800 setupTextureBasicParameters(tex
); // setup what has changed (will reset the touch flag)
803 _CurrentTexture
[0]= NULL
;
804 _CurrentTextureInfoGL
[0]= NULL
;
805 _DriverGLStates
.setTextureMode(CDriverGLStates::TextureDisabled
);
809 return true; // Do not do anything
812 // 1. If modified, may (re)load texture part or all of the texture.
813 //=================================================================
815 bool mustLoadAll
= false;
816 bool mustLoadPart
= false;
818 // To avoid any delete/new ptr problem, disable all texturing.
819 /* If an old texture is deleted, _CurrentTexture[*] and _CurrentTextureInfoGL[*] are invalid.
820 But this is grave only if a new texture is created, with the same pointer (bad luck).
821 Since an newly allocated texture always pass here before use, we are sure to avoid any problems.
823 for(uint stage
= 0; stage
< inlGetNumTextStages(); stage
++)
825 activateTexture(stage
, NULL
);
830 if(tex
.supportSharing())
832 // Try to get the shared texture.
834 // Create the shared Name.
836 getTextureShareName (tex
, name
);
838 // insert or get the texture.
840 CSynchronized
<TTexDrvInfoPtrMap
>::CAccessor
access(&_SyncTexDrvInfos
);
841 TTexDrvInfoPtrMap
&rTexDrvInfos
= access
.value();
843 ItTexDrvInfoPtrMap itTex
;
844 itTex
= rTexDrvInfos
.find(name
);
846 // texture not found?
847 if( itTex
==rTexDrvInfos
.end() )
849 // insert into driver map. (so it is deleted when driver is deleted).
850 itTex
= (rTexDrvInfos
.insert(make_pair(name
, (ITextureDrvInfos
*)NULL
))).first
;
851 // create and set iterator, for future deletion.
852 itTex
->second
= tex
.TextureDrvShare
->DrvTexture
= new CTextureDrvInfosGL(this, itTex
, this, isTextureRectangle(&tex
));
854 // need to load ALL this texture.
859 tex
.TextureDrvShare
->DrvTexture
= itTex
->second
;
861 if(bMustRecreateSharedTexture
)
862 // reload this shared texture (user request)
865 // Do not need to reload this texture, even if the format/mipmap has changed, since we found this
866 // couple in the map.
870 // Do not test if part of texture may need to be computed, because Rect invalidation is incompatible
871 // with texture sharing.
875 // If texture not already created.
876 if(!tex
.TextureDrvShare
->DrvTexture
)
878 // Must create it. Create auto a GL id (in constructor).
879 // Do not insert into the map. This un-shared texture will be deleted at deletion of the texture.
880 // Inform ITextureDrvInfos by passing NULL _Driver.
881 tex
.TextureDrvShare
->DrvTexture
= new CTextureDrvInfosGL(NULL
, ItTexDrvInfoPtrMap(), this, isTextureRectangle(&tex
));
883 // need to load ALL this texture.
886 else if(tex
.isAllInvalidated())
888 else if(tex
.touched())
894 if(mustLoadAll
|| mustLoadPart
)
896 // system of "backup the previous binded texture" seems to not work with some drivers....
897 bindTextureWithMode(tex
);
899 CTextureDrvInfosGL
* gltext
;
900 gltext
= getTextureGl(tex
);
902 glPixelStorei(GL_UNPACK_ALIGNMENT
,1);
904 // a. Load All the texture case.
905 //==============================
908 // profiling. sub old textre memory usage, and reset.
909 _AllocatedTextureMemory
-= gltext
->TextureMemory
;
910 gltext
->TextureMemory
= 0;
913 if(tex
.isTextureCube())
915 CTextureCube
*pTC
= NLMISC::safe_cast
<CTextureCube
*>(&tex
);
917 // Regenerate all the texture.
920 for(uint nText
= 0; nText
< 6; ++nText
)
921 if(pTC
->getTexture((CTextureCube::TFace
)nText
) != NULL
)
923 ITexture
*pTInTC
= pTC
->getTexture((CTextureCube::TFace
)nText
);
925 // In open GL, we have to flip the faces of the cube map
926 if( ((CTextureCube::TFace
)nText
) == CTextureCube::positive_x
)
928 if( ((CTextureCube::TFace
)nText
) == CTextureCube::negative_x
)
930 if( ((CTextureCube::TFace
)nText
) == CTextureCube::positive_y
)
932 if( ((CTextureCube::TFace
)nText
) == CTextureCube::negative_y
)
934 if( ((CTextureCube::TFace
)nText
) == CTextureCube::positive_z
)
936 if( ((CTextureCube::TFace
)nText
) == CTextureCube::negative_z
)
939 // Get the correct texture format from texture...
940 GLint glfmt
= getGlTextureFormat(*pTInTC
, gltext
->Compressed
);
941 GLint glSrcFmt
= getGlSrcTextureFormat(*pTInTC
, glfmt
);
942 GLenum glSrcType
= getGlSrcTextureComponentType(glSrcFmt
);
945 if(glSrcFmt
==GL_RGBA
&& pTInTC
->getPixelFormat()!=CBitmap::RGBA
)
946 pTInTC
->convertToType(CBitmap::RGBA
);
949 pTInTC
->buildMipMaps();
950 nMipMaps
= pTInTC
->getMipMapCount();
956 gltext
->MipMap
= nMipMaps
>1;
959 for(sint i
=0;i
<nMipMaps
;i
++)
961 void *ptr
= pTInTC
->getPixels(i
).getPtr();
962 uint w
= pTInTC
->getWidth(i
);
963 uint h
= pTInTC
->getHeight(i
);
966 NEL_MEASURE_UPLOAD_TIME_START
967 glTexImage2D (NLCubeFaceToGLCubeFace
[nText
], i
, glfmt
, w
, h
, 0, glSrcFmt
, glSrcType
, ptr
);
969 NEL_MEASURE_UPLOAD_TIME_END
973 NEL_MEASURE_UPLOAD_TIME_START
974 glTexImage2D (NLCubeFaceToGLCubeFace
[nText
], i
, glfmt
, w
, h
, 0, glSrcFmt
, glSrcType
, NULL
);
975 NEL_MEASURE_UPLOAD_TIME_END
977 // profiling: count TextureMemory usage.
978 gltext
->TextureMemory
+= computeMipMapMemoryUsage(w
, h
, glfmt
);
984 // Regenerate all the texture.
989 // Get the correct texture format from texture...
990 GLint glfmt
= getGlTextureFormat(tex
, gltext
->Compressed
);
991 GLint glSrcFmt
= getGlSrcTextureFormat(tex
, glfmt
);
992 GLenum glSrcType
= getGlSrcTextureComponentType(glSrcFmt
);
994 // DXTC: if same format, and same mipmapOn/Off, use glTexCompressedImage*.
995 // We cannot build the mipmaps if they are not here.
996 if(_Extensions
.EXTTextureCompressionS3TC
&& sameDXTCFormat(tex
, glfmt
))
1001 nMipMaps
= tex
.getMipMapCount();
1004 gltext
->MipMap
= nMipMaps
>1;
1006 // Degradation in Size allowed only if DXTC texture are provided with mipmaps.
1007 // Because use them to resize !!!
1008 uint decalMipMapResize
= 0;
1009 if(_ForceTextureResizePower
>0 && tex
.allowDegradation() && nMipMaps
>1)
1011 decalMipMapResize
= min(_ForceTextureResizePower
, (uint
)(nMipMaps
-1));
1015 for(sint i
=decalMipMapResize
;i
<nMipMaps
;i
++)
1017 void *ptr
= tex
.getPixels(i
).getPtr();
1018 sint size
= tex
.getPixels(i
).size();
1022 glCompressedTexImage2D (GL_TEXTURE_2D
, i
-decalMipMapResize
, glfmt
,
1023 tex
.getWidth(i
),tex
.getHeight(i
), 0, size
, ptr
);
1025 nglCompressedTexImage2DARB (GL_TEXTURE_2D
, i
-decalMipMapResize
, glfmt
,
1026 tex
.getWidth(i
),tex
.getHeight(i
), 0, size
, ptr
);
1028 bAllUploaded
= true;
1032 //glCompressedTexImage2DARB (GL_TEXTURE_2D, i-decalMipMapResize, glfmt,
1033 // tex.getWidth(i),tex.getHeight(i), 0, size, NULL);
1034 NEL_MEASURE_UPLOAD_TIME_START
1036 glTexImage2D (gltext
->TextureMode
, i
-decalMipMapResize
, glfmt
, tex
.getWidth(i
), tex
.getHeight(i
),
1037 0, glSrcFmt
, glSrcType
, NULL
);
1038 NEL_MEASURE_UPLOAD_TIME_END
1041 // profiling: count TextureMemory usage.
1042 gltext
->TextureMemory
+= tex
.getPixels(i
).size();
1048 if(glSrcFmt
==GL_RGBA
&& tex
.getPixelFormat()!=CBitmap::RGBA
)
1050 bUpload
= true; // Force all upload
1051 tex
.convertToType(CBitmap::RGBA
);
1054 // Degradation in Size.
1055 if(_ForceTextureResizePower
>0 && tex
.allowDegradation())
1057 uint w
= tex
.getWidth(0) >> _ForceTextureResizePower
;
1058 uint h
= tex
.getHeight(0) >> _ForceTextureResizePower
;
1067 nMipMaps
= tex
.getMipMapCount();
1073 gltext
->MipMap
= nMipMaps
>1;
1076 for(sint i
=0;i
<nMipMaps
;i
++)
1078 void *ptr
= tex
.getPixels(i
).getPtr();
1079 uint w
= tex
.getWidth(i
);
1080 uint h
= tex
.getHeight(i
);
1084 NEL_MEASURE_UPLOAD_TIME_START
1085 glTexImage2D (gltext
->TextureMode
, i
, glfmt
, w
, h
, 0,glSrcFmt
, glSrcType
, ptr
);
1086 NEL_MEASURE_UPLOAD_TIME_END
1087 bAllUploaded
= true;
1091 NEL_MEASURE_UPLOAD_TIME_START
1092 glTexImage2D (gltext
->TextureMode
, i
, glfmt
, w
, h
, 0,glSrcFmt
, glSrcType
, NULL
);
1093 NEL_MEASURE_UPLOAD_TIME_END
1095 // profiling: count TextureMemory usage.
1096 gltext
->TextureMemory
+= computeMipMapMemoryUsage (w
, h
, glfmt
);
1101 //printf("%d,%d,%d\n", tex.getMipMapCount(), tex.getWidth(0), tex.getHeight(0));
1103 // profiling. add new TextureMemory usage.
1104 _AllocatedTextureMemory
+= gltext
->TextureMemory
;
1106 // b. Load part of the texture case.
1107 //==================================
1108 // Replace parts of a compressed image. Maybe don't work with the actual system of invalidateRect()...
1109 else if (mustLoadPart
&& !gltext
->Compressed
)
1111 // Regenerate wanted part of the texture.
1116 // Get the correct texture format from texture...
1117 //===============================================
1119 GLint glfmt
= getGlTextureFormat(tex
, dummy
);
1120 GLint glSrcFmt
= getGlSrcTextureFormat(tex
, glfmt
);
1121 GLenum glSrcType
= getGlSrcTextureComponentType(glSrcFmt
);
1124 if(glSrcFmt
==GL_RGBA
&& tex
.getPixelFormat()!=CBitmap::RGBA
)
1125 tex
.convertToType(CBitmap::RGBA
);
1128 bool hadMipMap
= tex
.getMipMapCount()>1;
1130 nMipMaps
= tex
.getMipMapCount();
1131 // If the texture had no mipmap before, release them.
1134 tex
.releaseMipMaps();
1140 // For all rect, update the texture/mipmap.
1141 //===============================================
1142 list
<NLMISC::CRect
>::iterator itRect
;
1143 for(itRect
=tex
._ListInvalidRect
.begin(); itRect
!=tex
._ListInvalidRect
.end(); itRect
++)
1145 CRect
&rect
= *itRect
;
1148 sint x1
= rect
.X
+rect
.Width
;
1149 sint y1
= rect
.Y
+rect
.Height
;
1152 for(sint i
=0;i
<nMipMaps
;i
++)
1154 void *ptr
= tex
.getPixels(i
).getPtr();
1155 sint w
= tex
.getWidth(i
);
1156 sint h
= tex
.getHeight(i
);
1163 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
1170 if (glSrcFmt
== GL_ALPHA
)
1173 for(sint yy
= 0; yy
< (y1
-y0
); yy
++)
1175 char *row
= (char*)ptr
+ ((yy
+ y0
)*w
+ x0
) * pixelSize
;
1176 glTexSubImage2D (GL_TEXTURE_2D
, i
, x0
, y0
+yy
, x1
-x0
, 1, glSrcFmt
, glSrcType
, row
);
1179 glPixelStorei(GL_UNPACK_ROW_LENGTH
, w
);
1180 glPixelStorei(GL_UNPACK_SKIP_ROWS
, y0
);
1181 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, x0
);
1183 glTexSubImage2D (GL_TEXTURE_2D
, i
, x0
, y0
, x1
-x0
, y1
-y0
, glSrcFmt
,glSrcType
, ptr
);
1185 glTexSubImage2D (GL_TEXTURE_2D
, i
, x0
, y0
, x1
-x0
, y1
-y0
, glSrcFmt
,glSrcType
, NULL
);
1198 // Reset the transfer mode...
1200 glPixelStorei(GL_UNPACK_ALIGNMENT
, 4);
1202 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
1203 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
1204 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
1209 // Release, if wanted.
1210 if(tex
.getReleasable())
1213 // Basic parameters.
1214 //==================
1215 setupTextureBasicParameters(tex
);
1217 // Disable texture 0
1218 _CurrentTexture
[0]= NULL
;
1219 _CurrentTextureInfoGL
[0]= NULL
;
1220 _DriverGLStates
.setTextureMode(CDriverGLStates::TextureDisabled
);
1223 // The texture is correctly setuped.
1228 // ***************************************************************************
1229 bool CDriverGL::uploadTexture (ITexture
& tex
, CRect
& rect
, uint8 nNumMipMap
)
1231 H_AUTO_OGL(uploadTexture
)
1232 if (tex
.TextureDrvShare
== NULL
)
1233 return false; // Texture not created
1234 if (tex
.TextureDrvShare
->DrvTexture
== NULL
)
1235 return false; // Texture not created
1236 if (tex
.isTextureCube())
1239 nlassert(nNumMipMap
<(uint8
)tex
.getMipMapCount());
1244 sint x1
= rect
.X
+rect
.Width
;
1245 sint y1
= rect
.Y
+rect
.Height
;
1246 sint w
= tex
.getWidth (nNumMipMap
);
1247 sint h
= tex
.getHeight (nNumMipMap
);
1253 // bind the texture to upload
1254 CTextureDrvInfosGL
* gltext
;
1255 gltext
= getTextureGl (tex
);
1257 // system of "backup the previous binded texture" seems to not work with some drivers....
1258 _DriverGLStates
.activeTextureARB (0);
1259 CDriverGLStates::TTextureMode textureMode
= CDriverGLStates::Texture2D
;
1261 #ifndef USE_OPENGLES
1262 if(gltext
->TextureMode
== GL_TEXTURE_RECTANGLE_NV
)
1263 textureMode
= CDriverGLStates::TextureRect
;
1266 _DriverGLStates
.setTextureMode (textureMode
);
1267 // Bind this texture, for reload...
1268 glBindTexture (gltext
->TextureMode
, gltext
->ID
);
1270 glPixelStorei (GL_UNPACK_ALIGNMENT
, 1);
1273 GLint glfmt
= getGlTextureFormat (tex
, dummy
);
1274 GLint glSrcFmt
= getGlSrcTextureFormat (tex
, glfmt
);
1275 GLenum glSrcType
= getGlSrcTextureComponentType(glSrcFmt
);
1278 if (_Extensions
.EXTTextureCompressionS3TC
&& sameDXTCFormat(tex
, glfmt
))
1281 sint nUploadMipMaps
;
1283 nUploadMipMaps
= tex
.getMipMapCount();
1287 uint decalMipMapResize
= 0;
1288 if (_ForceTextureResizePower
>0 && tex
.allowDegradation() && nUploadMipMaps
>1)
1290 decalMipMapResize
= min(_ForceTextureResizePower
, (uint
)(nUploadMipMaps
-1));
1293 // Compute src compressed size and location
1294 sint imageSize
= (x1
-x0
)*(y1
-y0
);
1295 void *ptr
= tex
.getPixels(nNumMipMap
).getPtr();
1297 // If DXTC1 or DXTC1A, then 4 bits/texel else 8 bits/texel
1298 if (glfmt
== GL_COMPRESSED_RGB_S3TC_DXT1_EXT
|| glfmt
== GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
)
1301 ptr
= (uint8
*)ptr
+ y0
*w
/2 + x0
/2;
1305 ptr
= (uint8
*)ptr
+ y0
*w
+ x0
;
1310 if (decalMipMapResize
> nNumMipMap
)
1312 _CurrentTexture
[0]= NULL
;
1313 _CurrentTextureInfoGL
[0]= NULL
;
1314 _DriverGLStates
.setTextureMode (CDriverGLStates::TextureDisabled
);
1318 nlassert (((x0
&3) == 0) && ((y0
&3) == 0));
1319 if ((w
>=4) && (h
>=4))
1322 glCompressedTexSubImage2D (
1324 nglCompressedTexSubImage2DARB (
1326 GL_TEXTURE_2D
, nNumMipMap
-decalMipMapResize
,
1327 x0
, y0
, (x1
-x0
), (y1
-y0
), glfmt
, imageSize
, ptr
);
1331 // The CompressedTexSubImage2DARB function do not work properly if width or height
1332 // of the mipmap is less than 4 pixel so we use the other form. (its not really time critical
1333 // to upload 16 bytes so we can do it twice if texture is cut)
1334 imageSize
= tex
.getPixels(nNumMipMap
).size();
1336 glCompressedTexImage2D (
1338 nglCompressedTexImage2DARB (
1340 GL_TEXTURE_2D
, nNumMipMap
-decalMipMapResize
,
1341 glfmt
, w
, h
, 0, imageSize
, ptr
);
1346 // glSrcFmt and ITexture format must be identical
1347 nlassert (glSrcFmt
!=GL_RGBA
|| tex
.getPixelFormat()==CBitmap::RGBA
);
1349 void *ptr
= tex
.getPixels(nNumMipMap
).getPtr();
1354 if (glSrcFmt
== GL_ALPHA
)
1357 for(sint yy
= 0; yy
< (y1
-y0
); yy
++)
1359 char *row
= (char*)ptr
+ ((yy
+ y0
)*w
+ x0
) * pixelSize
;
1360 glTexSubImage2D (GL_TEXTURE_2D
, nNumMipMap
, x0
, y0
+yy
, x1
-x0
, 1, glSrcFmt
, glSrcType
, row
);
1363 // Reset the transfer mode...
1364 // glPixelStorei (GL_UNPACK_ALIGNMENT, 0);
1366 glPixelStorei (GL_UNPACK_ROW_LENGTH
, w
);
1367 glPixelStorei (GL_UNPACK_SKIP_ROWS
, y0
);
1368 glPixelStorei (GL_UNPACK_SKIP_PIXELS
, x0
);
1369 glTexSubImage2D (GL_TEXTURE_2D
, nNumMipMap
, x0
, y0
, x1
-x0
, y1
-y0
, glSrcFmt
,glSrcType
, ptr
);
1371 // Reset the transfer mode...
1372 glPixelStorei (GL_UNPACK_ROW_LENGTH
, 0);
1373 glPixelStorei (GL_UNPACK_SKIP_ROWS
, 0);
1374 glPixelStorei (GL_UNPACK_SKIP_PIXELS
, 0);
1378 // Disable texture 0
1379 _CurrentTexture
[0]= NULL
;
1380 _CurrentTextureInfoGL
[0]= NULL
;
1381 _DriverGLStates
.setTextureMode (CDriverGLStates::TextureDisabled
);
1386 // ***************************************************************************
1387 bool CDriverGL::uploadTextureCube (ITexture
& tex
, CRect
& /* rect */, uint8
/* nNumMipMap */, uint8
/* nNumFace */)
1389 H_AUTO_OGL(uploadTextureCube
)
1390 if (tex
.TextureDrvShare
== NULL
)
1391 return false; // Texture not created
1392 if (!tex
.isTextureCube())
1398 // ***************************************************************************
1399 bool CDriverGL::activateTexture(uint stage
, ITexture
*tex
)
1401 H_AUTO_OGL(activateTexture
)
1402 if (this->_CurrentTexture
[stage
]!=tex
)
1404 _DriverGLStates
.activeTextureARB(stage
);
1405 if(tex
&& tex
->TextureDrvShare
)
1407 // get the drv info. should be not NULL.
1408 CTextureDrvInfosGL
* gltext
;
1409 gltext
= getTextureGl(*tex
);
1411 // Profile, log the use of this texture
1412 //=========================================
1413 if (_SumTextureMemoryUsed
)
1415 // Insert the pointer of this texture
1416 if (gltext
->TextureUsedIdx
>= _TextureUsed
.size() || _TextureUsed
[gltext
->TextureUsedIdx
] != gltext
)
1418 gltext
->TextureUsedIdx
= _TextureUsed
.size();
1419 _TextureUsed
.push_back(gltext
);
1423 if(tex
->isTextureCube())
1425 // setup texture mode, after activeTextureARB()
1426 _DriverGLStates
.setTextureMode(CDriverGLStates::TextureCubeMap
);
1428 if(_Extensions
.ARBTextureCubeMap
)
1430 // Activate texturing...
1431 //======================
1433 // If the shared texture is the same than before, no op.
1434 if(_CurrentTextureInfoGL
[stage
] != gltext
)
1437 _CurrentTextureInfoGL
[stage
]= gltext
;
1439 // setup this texture
1440 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB
, gltext
->ID
);
1442 // Change parameters of texture, if necessary.
1443 //============================================
1444 if(gltext
->MagFilter
!= tex
->getMagFilter())
1446 gltext
->MagFilter
= tex
->getMagFilter();
1447 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,GL_TEXTURE_MAG_FILTER
, translateMagFilterToGl(gltext
));
1449 if(gltext
->MinFilter
!= tex
->getMinFilter())
1451 gltext
->MinFilter
= tex
->getMinFilter();
1452 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,GL_TEXTURE_MIN_FILTER
, translateMinFilterToGl(gltext
));
1459 // setup texture mode, after activeTextureARB()
1460 CDriverGLStates::TTextureMode textureMode
= CDriverGLStates::Texture2D
;
1461 #ifndef USE_OPENGLES
1462 if(gltext
->TextureMode
== GL_TEXTURE_RECTANGLE_NV
)
1463 textureMode
= CDriverGLStates::TextureRect
;
1465 _DriverGLStates
.setTextureMode(/*CDriverGLStates::Texture2D*/textureMode
);
1467 // Activate texture...
1468 //======================
1470 // If the shared texture is the same than before, no op.
1471 if(_CurrentTextureInfoGL
[stage
] != gltext
)
1474 _CurrentTextureInfoGL
[stage
]= gltext
;
1476 // setup this texture
1477 glBindTexture(gltext
->TextureMode
, gltext
->ID
);
1480 // Change parameters of texture, if necessary.
1481 //============================================
1482 if(gltext
->WrapS
!= tex
->getWrapS())
1484 gltext
->WrapS
= tex
->getWrapS();
1485 glTexParameteri(gltext
->TextureMode
,GL_TEXTURE_WRAP_S
, translateWrapToGl(gltext
->WrapS
, _Extensions
));
1487 if(gltext
->WrapT
!= tex
->getWrapT())
1489 gltext
->WrapT
= tex
->getWrapT();
1490 glTexParameteri(gltext
->TextureMode
,GL_TEXTURE_WRAP_T
, translateWrapToGl(gltext
->WrapT
, _Extensions
));
1492 if(gltext
->MagFilter
!= tex
->getMagFilter())
1494 gltext
->MagFilter
= tex
->getMagFilter();
1495 glTexParameteri(gltext
->TextureMode
,GL_TEXTURE_MAG_FILTER
, translateMagFilterToGl(gltext
));
1497 if(gltext
->MinFilter
!= tex
->getMinFilter())
1499 gltext
->MinFilter
= tex
->getMinFilter();
1500 glTexParameteri(gltext
->TextureMode
,GL_TEXTURE_MIN_FILTER
, translateMinFilterToGl(gltext
));
1507 // Force no texturing for this stage.
1508 _CurrentTextureInfoGL
[stage
]= NULL
;
1509 // setup texture mode, after activeTextureARB()
1510 _DriverGLStates
.setTextureMode(CDriverGLStates::TextureDisabled
);
1512 #ifndef USE_OPENGLES
1513 if (_Extensions
.ATITextureEnvCombine3
)
1515 // very strange bug with ATI cards : when a texture is set to NULL at a stage, the stage is still active sometimes...
1516 activateTexEnvMode(stage
, _TexEnvReplace
); // set the whole stage to replace fix the problem
1521 this->_CurrentTexture
[stage
]= tex
;
1528 // This maps the CMaterial::TTexOperator
1529 static const GLenum OperatorLUT
[9]= { GL_REPLACE
, GL_MODULATE
, GL_ADD
, GL_ADD_SIGNED_EXT
, GL_INTERPOLATE_EXT
, GL_INTERPOLATE_EXT
, GL_INTERPOLATE_EXT
, GL_INTERPOLATE_EXT
, GL_BUMP_ENVMAP_ATI
};
1531 // This maps the CMaterial::TTexSource
1532 static const GLenum SourceLUT
[4]= { GL_TEXTURE
, GL_PREVIOUS_EXT
, GL_PRIMARY_COLOR_EXT
, GL_CONSTANT_EXT
};
1534 // This maps the CMaterial::TTexOperand
1535 static const GLenum OperandLUT
[4]= { GL_SRC_COLOR
, GL_ONE_MINUS_SRC_COLOR
, GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
};
1537 // This maps the CMaterial::TTexOperator, used for openGL Arg2 setup.
1538 static const GLenum InterpolateSrcLUT
[8]= { GL_TEXTURE
, GL_TEXTURE
, GL_TEXTURE
, GL_TEXTURE
, GL_TEXTURE
, GL_PREVIOUS_EXT
, GL_PRIMARY_COLOR_EXT
, GL_CONSTANT_EXT
};
1540 #ifndef USE_OPENGLES
1542 // ***************************************************************************
1543 // Set general tex env using ENV_COMBINE4 for the current setupped stage (used by forceActivateTexEnvMode)
1544 static void forceActivateTexEnvModeEnvCombine4(const CMaterial::CTexEnv
&env
)
1546 H_AUTO_OGL(forceActivateTexEnvModeEnvCombine4
);
1548 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_COMBINE4_NV
);
1551 switch(env
.Env
.OpRGB
)
1553 case CMaterial::Replace
:
1554 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_ADD
);
1556 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
]);
1557 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1559 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, GL_ZERO
);
1560 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, GL_ONE_MINUS_SRC_COLOR
);
1562 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, GL_ZERO
);
1563 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, GL_SRC_COLOR
);
1565 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_RGB_NV
, GL_ZERO
);
1566 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_RGB_NV
, GL_SRC_COLOR
);
1568 case CMaterial::Add
:
1569 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_ADD
);
1571 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
]);
1572 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1574 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, GL_ZERO
);
1575 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, GL_ONE_MINUS_SRC_COLOR
);
1577 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
]);
1578 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1580 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_RGB_NV
, GL_ZERO
);
1581 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_RGB_NV
, GL_ONE_MINUS_SRC_COLOR
);
1583 case CMaterial::AddSigned
:
1584 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_ADD_SIGNED_EXT
);
1586 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
]);
1587 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1589 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, GL_ZERO
);
1590 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, GL_ONE_MINUS_SRC_COLOR
);
1592 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
]);
1593 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1595 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_RGB_NV
, GL_ZERO
);
1596 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_RGB_NV
, GL_ONE_MINUS_SRC_COLOR
);
1598 case CMaterial::InterpolateTexture
:
1599 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_ADD
);
1601 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
]);
1602 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1603 // Arg1 = (1 - texture)
1604 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, GL_TEXTURE
);
1605 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1607 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
]);
1608 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1610 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_RGB_NV
, GL_TEXTURE
);
1611 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_RGB_NV
, GL_SRC_ALPHA
);
1613 case CMaterial::InterpolatePrevious
:
1614 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_ADD
);
1616 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
]);
1617 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1618 // Arg1 = (1 - previous)
1619 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, GL_PREVIOUS_EXT
);
1620 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1622 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
]);
1623 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1625 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_RGB_NV
, GL_PREVIOUS_EXT
);
1626 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_RGB_NV
, GL_SRC_ALPHA
);
1628 case CMaterial::InterpolateDiffuse
:
1629 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_ADD
);
1631 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
]);
1632 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1633 // Arg1 = (1 - diffuse)
1634 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, GL_PRIMARY_COLOR_EXT
);
1635 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1637 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
]);
1638 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1640 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_RGB_NV
, GL_PRIMARY_COLOR_EXT
);
1641 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_RGB_NV
, GL_SRC_ALPHA
);
1643 case CMaterial::InterpolateConstant
:
1644 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_ADD
);
1646 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
]);
1647 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1648 // Arg1 = (1 - constant)
1649 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, GL_CONSTANT_EXT
);
1650 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1652 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
]);
1653 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1655 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_RGB_NV
, GL_CONSTANT_EXT
);
1656 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_RGB_NV
, GL_SRC_ALPHA
);
1658 case CMaterial::Mad
:
1659 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_ADD
);
1661 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
]);
1662 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1664 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
]);
1665 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1667 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg2RGB
]);
1668 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, OperandLUT
[env
.Env
.OpArg2RGB
]);
1670 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_RGB_NV
, GL_ZERO
);
1671 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_RGB_NV
, GL_ONE_MINUS_SRC_COLOR
);
1674 // default is modulate
1675 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_ADD
);
1677 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
]);
1678 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1680 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
]);
1681 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1683 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, GL_ZERO
);
1684 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, GL_SRC_COLOR
);
1686 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_RGB_NV
, GL_ZERO
);
1687 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_RGB_NV
, GL_SRC_COLOR
);
1691 switch(env
.Env
.OpAlpha
)
1693 case CMaterial::Replace
:
1694 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, GL_ADD
);
1696 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
]);
1697 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1699 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, GL_ZERO
);
1700 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1702 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, GL_ZERO
);
1703 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, GL_SRC_ALPHA
);
1705 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_ALPHA_NV
, GL_ZERO
);
1706 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_ALPHA_NV
, GL_SRC_ALPHA
);
1708 case CMaterial::Add
:
1709 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, GL_ADD
);
1711 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
]);
1712 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1714 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, GL_ZERO
);
1715 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1717 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1Alpha
]);
1718 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
1720 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_ALPHA_NV
, GL_ZERO
);
1721 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_ALPHA_NV
, GL_ONE_MINUS_SRC_ALPHA
);
1723 case CMaterial::AddSigned
:
1724 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, GL_ADD_SIGNED_EXT
);
1726 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
]);
1727 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1729 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, GL_ZERO
);
1730 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1732 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1Alpha
]);
1733 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
1735 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_ALPHA_NV
, GL_ZERO
);
1736 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_ALPHA_NV
, GL_ONE_MINUS_SRC_ALPHA
);
1738 case CMaterial::InterpolateTexture
:
1739 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, GL_ADD
);
1741 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
]);
1742 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1743 // Arg1 = (1 - texture)
1744 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, GL_TEXTURE
);
1745 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1747 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1Alpha
]);
1748 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
1750 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_ALPHA_NV
, GL_TEXTURE
);
1751 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_ALPHA_NV
, GL_SRC_ALPHA
);
1753 case CMaterial::InterpolatePrevious
:
1754 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, GL_ADD
);
1756 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
]);
1757 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1758 // Arg1 = (1 - previous)
1759 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, GL_PREVIOUS_EXT
);
1760 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1762 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1Alpha
]);
1763 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
1765 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_ALPHA_NV
, GL_PREVIOUS_EXT
);
1766 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_ALPHA_NV
, GL_SRC_ALPHA
);
1768 case CMaterial::InterpolateDiffuse
:
1769 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, GL_ADD
);
1771 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
]);
1772 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1773 // Arg1 = (1 - diffuse)
1774 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, GL_PRIMARY_COLOR_EXT
);
1775 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1777 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1Alpha
]);
1778 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
1780 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_ALPHA_NV
, GL_PRIMARY_COLOR_EXT
);
1781 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_ALPHA_NV
, GL_SRC_ALPHA
);
1783 case CMaterial::InterpolateConstant
:
1784 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, GL_ADD
);
1786 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
]);
1787 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1788 // Arg1 = (1 - constant)
1789 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, GL_CONSTANT_EXT
);
1790 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, GL_ONE_MINUS_SRC_ALPHA
);
1792 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1Alpha
]);
1793 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
1795 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_ALPHA_NV
, GL_CONSTANT_EXT
);
1796 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_ALPHA_NV
, GL_SRC_ALPHA
);
1798 case CMaterial::Mad
:
1799 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, GL_ADD
);
1801 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
]);
1802 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1804 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1Alpha
]);
1805 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
1807 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg2Alpha
]);
1808 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg2Alpha
]);
1810 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_ALPHA_NV
, GL_ZERO
);
1811 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_ALPHA_NV
, GL_ONE_MINUS_SRC_ALPHA
);
1814 // default is modulate
1815 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, GL_ADD
);
1817 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
]);
1818 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1820 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1Alpha
]);
1821 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
1823 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, GL_ZERO
);
1824 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, GL_SRC_ALPHA
);
1826 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE3_ALPHA_NV
, GL_ZERO
);
1827 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND3_ALPHA_NV
, GL_SRC_ALPHA
);
1834 // ***************************************************************************
1835 void CDriverGL::forceActivateTexEnvMode(uint stage
, const CMaterial::CTexEnv
&env
)
1837 H_AUTO_OGL(forceActivateTexEnvMode
)
1839 _CurrentTexEnv
[stage
].EnvPacked
= env
.EnvPacked
;
1840 // Disable Special tex env f().
1841 _CurrentTexEnvSpecial
[stage
]= TexEnvSpecialDisabled
;
1844 // Setup the gl env mode.
1845 _DriverGLStates
.activeTextureARB(stage
);
1848 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_COMBINE
);
1852 if (env
.Env
.OpRGB
== CMaterial::Mad
)
1857 // GL_MODULATE_ADD_ATI
1858 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB
, GL_DOT3_RGB
);
1860 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC0_RGB
, SourceLUT
[env
.Env
.SrcArg0RGB
] );
1861 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1863 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC2_RGB
, SourceLUT
[env
.Env
.SrcArg1RGB
] );
1864 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1866 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC1_RGB
, SourceLUT
[env
.Env
.SrcArg2RGB
] );
1867 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB
, OperandLUT
[env
.Env
.OpArg2RGB
]);
1871 // fallback to modulate ..
1872 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB
, GL_MODULATE
);
1875 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC0_RGB
, SourceLUT
[env
.Env
.SrcArg0RGB
] );
1876 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1878 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC1_RGB
, SourceLUT
[env
.Env
.SrcArg1RGB
] );
1879 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1885 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB
, OperatorLUT
[env
.Env
.OpRGB
] );
1887 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC0_RGB
, SourceLUT
[env
.Env
.SrcArg0RGB
] );
1888 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1890 if(env
.Env
.OpRGB
> CMaterial::Replace
)
1892 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC1_RGB
, SourceLUT
[env
.Env
.SrcArg1RGB
] );
1893 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1895 if(env
.Env
.OpRGB
>= CMaterial::InterpolateTexture
)
1897 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC2_RGB
, InterpolateSrcLUT
[env
.Env
.OpRGB
] );
1898 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB
, GL_SRC_ALPHA
);
1904 if (env
.Env
.OpAlpha
== CMaterial::Mad
)
1908 // GL_MODULATE_ADD_ATI
1909 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB
, GL_DOT3_RGB
);
1911 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC0_ALPHA
, SourceLUT
[env
.Env
.SrcArg0Alpha
] );
1912 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1914 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC2_ALPHA
, SourceLUT
[env
.Env
.SrcArg1Alpha
] );
1915 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
1917 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC1_ALPHA
, SourceLUT
[env
.Env
.SrcArg2Alpha
] );
1918 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA
, OperandLUT
[env
.Env
.OpArg2Alpha
]);
1922 // fallback to modulate ..
1923 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA
, GL_MODULATE
);
1926 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC0_ALPHA
, SourceLUT
[env
.Env
.SrcArg0RGB
] );
1927 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1929 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC1_ALPHA
, SourceLUT
[env
.Env
.SrcArg1RGB
] );
1930 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1936 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA
, OperatorLUT
[env
.Env
.OpAlpha
] );
1938 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC0_ALPHA
, SourceLUT
[env
.Env
.SrcArg0Alpha
] );
1939 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
1941 if(env
.Env
.OpAlpha
> CMaterial::Replace
)
1943 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC1_ALPHA
, SourceLUT
[env
.Env
.SrcArg1Alpha
] );
1944 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
1946 if(env
.Env
.OpAlpha
>= CMaterial::InterpolateTexture
)
1948 glTexEnvi(GL_TEXTURE_ENV
, GL_SRC2_ALPHA
, InterpolateSrcLUT
[env
.Env
.OpAlpha
] );
1949 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA
, GL_SRC_ALPHA
);
1954 // if the Mad operator is used, then
1955 // "Normal drivers", setup EnvCombine.
1956 if(_Extensions
.EXTTextureEnvCombine
)
1958 // if Mad operator is used, special setup
1959 if ((env
.Env
.OpAlpha
== CMaterial::Mad
|| env
.Env
.OpRGB
== CMaterial::Mad
) && _Extensions
.NVTextureEnvCombine4
)
1961 forceActivateTexEnvModeEnvCombine4(env
);
1965 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_COMBINE_EXT
);
1968 if (env
.Env
.OpRGB
== CMaterial::Mad
)
1971 if (_Extensions
.ATITextureEnvCombine3
)
1973 glTexEnvf(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_MODULATE_ADD_ATI
);
1975 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
] );
1976 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1978 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
] );
1979 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
1981 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg2RGB
] );
1982 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, OperandLUT
[env
.Env
.OpArg2RGB
]);
1986 // fallback to modulate ..
1987 glTexEnvf(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_MODULATE
);
1990 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
] );
1991 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
1993 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
] );
1994 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
2000 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, OperatorLUT
[env
.Env
.OpRGB
] );
2002 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
] );
2003 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_RGB_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
2005 if(env
.Env
.OpRGB
> CMaterial::Replace
)
2007 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_RGB_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
] );
2008 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_RGB_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
2010 if(env
.Env
.OpRGB
>= CMaterial::InterpolateTexture
)
2012 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_RGB_EXT
, InterpolateSrcLUT
[env
.Env
.OpRGB
] );
2013 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_RGB_EXT
, GL_SRC_ALPHA
);
2019 if (env
.Env
.OpAlpha
== CMaterial::Mad
)
2021 if (_Extensions
.ATITextureEnvCombine3
)
2023 glTexEnvf(GL_TEXTURE_ENV
, GL_COMBINE_RGB_EXT
, GL_MODULATE_ADD_ATI
);
2025 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
] );
2026 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
2028 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1Alpha
] );
2029 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
2031 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg2Alpha
] );
2032 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg2Alpha
]);
2036 // fallback to modulate ..
2037 glTexEnvf(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, GL_MODULATE
);
2040 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0RGB
] );
2041 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0RGB
]);
2043 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1RGB
] );
2044 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1RGB
]);
2050 glTexEnvi(GL_TEXTURE_ENV
, GL_COMBINE_ALPHA_EXT
, OperatorLUT
[env
.Env
.OpAlpha
] );
2052 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE0_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg0Alpha
] );
2053 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND0_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg0Alpha
]);
2055 if(env
.Env
.OpAlpha
> CMaterial::Replace
)
2057 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE1_ALPHA_EXT
, SourceLUT
[env
.Env
.SrcArg1Alpha
] );
2058 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND1_ALPHA_EXT
, OperandLUT
[env
.Env
.OpArg1Alpha
]);
2060 if(env
.Env
.OpAlpha
>= CMaterial::InterpolateTexture
)
2062 glTexEnvi(GL_TEXTURE_ENV
, GL_SOURCE2_ALPHA_EXT
, InterpolateSrcLUT
[env
.Env
.OpAlpha
] );
2063 glTexEnvi(GL_TEXTURE_ENV
, GL_OPERAND2_ALPHA_EXT
, GL_SRC_ALPHA
);
2069 // Very Bad drivers.
2072 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
2077 // ***************************************************************************
2078 void CDriverGL::activateTexEnvColor(uint stage
, NLMISC::CRGBA col
)
2080 H_AUTO_OGL(CDriverGL_activateTexEnvColor
)
2081 if (col
!= _CurrentTexEnv
[stage
].ConstantColor
)
2083 forceActivateTexEnvColor(stage
, col
);
2087 // ***************************************************************************
2088 void CDriverGL::activateTexEnvMode(uint stage
, const CMaterial::CTexEnv
&env
)
2090 H_AUTO_OGL(CDriverGL_activateTexEnvMode
)
2091 // If a special Texture environnement is setuped, or if not the same normal texture environnement,
2092 // must setup a new normal Texture environnement.
2093 if(_CurrentTexEnvSpecial
[stage
] != TexEnvSpecialDisabled
|| _CurrentTexEnv
[stage
].EnvPacked
!= env
.EnvPacked
)
2095 forceActivateTexEnvMode(stage
, env
);
2100 // ***************************************************************************
2101 void CDriverGL::activateTexEnvColor(uint stage
, const CMaterial::CTexEnv
&env
)
2103 H_AUTO_OGL(CDriverGL_activateTexEnvColor
)
2104 if(_CurrentTexEnv
[stage
].ConstantColor
!= env
.ConstantColor
)
2106 forceActivateTexEnvColor(stage
, env
);
2111 // ***************************************************************************
2112 void CDriverGL::forceDXTCCompression(bool dxtcComp
)
2114 H_AUTO_OGL(CDriverGL_forceDXTCCompression
)
2115 _ForceDXTCCompression
= dxtcComp
;
2118 // ***************************************************************************
2119 void CDriverGL::setAnisotropicFilter(sint filtering
)
2121 H_AUTO_OGL(CDriverGL_setAnisotropicFiltering
);
2123 if (!_Extensions
.EXTTextureFilterAnisotropic
) return;
2125 if (filtering
< 0 || filtering
> _Extensions
.EXTTextureFilterAnisotropicMaximum
)
2127 // set maximum value for anisotropic filter
2128 _AnisotropicFilter
= _Extensions
.EXTTextureFilterAnisotropicMaximum
;
2132 // set specified value for anisotropic filter
2133 _AnisotropicFilter
= filtering
;
2137 // ***************************************************************************
2138 uint
CDriverGL::getAnisotropicFilter() const
2140 H_AUTO_OGL(CDriverGL_getAnisotropicFilter
);
2142 return (uint
)_AnisotropicFilter
;
2145 // ***************************************************************************
2146 uint
CDriverGL::getAnisotropicFilterMaximum() const
2148 H_AUTO_OGL(CDriverGL_getAnisotropicFilterMaximum
);
2150 return (uint
)_Extensions
.EXTTextureFilterAnisotropicMaximum
;
2153 // ***************************************************************************
2154 void CDriverGL::forceTextureResize(uint divisor
)
2156 H_AUTO_OGL(CDriverGL_forceTextureResize
)
2157 clamp(divisor
, 1U, 256U);
2160 _ForceTextureResizePower
= getPowerOf2(divisor
);
2164 // ***************************************************************************
2165 void CDriverGL::swapTextureHandle(ITexture
&tex0
, ITexture
&tex1
)
2167 H_AUTO_OGL(CDriverGL_swapTextureHandle
)
2168 // ensure creation of both texture
2172 // avoid any problem, disable all textures
2173 for(uint stage
= 0; stage
< inlGetNumTextStages(); stage
++)
2175 activateTexture(stage
, NULL
);
2179 CTextureDrvInfosGL
*t0
= getTextureGl(tex0
);
2180 CTextureDrvInfosGL
*t1
= getTextureGl(tex1
);
2182 /* Swap contents. Can't swap directly the pointers cause would have to change all CTextureDrvShare which point on
2183 Can't do swap(*t0, *t1), because must keep the correct _DriverIterator
2185 swap(t0
->ID
, t1
->ID
);
2186 swap(t0
->MipMap
, t1
->MipMap
);
2187 swap(t0
->Compressed
, t1
->Compressed
);
2188 swap(t0
->TextureMemory
, t1
->TextureMemory
);
2189 swap(t0
->WrapS
, t1
->WrapS
);
2190 swap(t0
->WrapT
, t1
->WrapT
);
2191 swap(t0
->MagFilter
, t1
->MagFilter
);
2192 swap(t0
->MinFilter
, t1
->MinFilter
);
2193 swap(t0
->TextureMode
, t1
->TextureMode
);
2194 swap(t0
->FBOId
, t1
->FBOId
);
2195 swap(t0
->DepthStencilFBO
, t1
->DepthStencilFBO
);
2196 swap(t0
->InitFBO
, t1
->InitFBO
);
2200 // ***************************************************************************
2201 uintptr_t CDriverGL::getTextureHandle(const ITexture
&tex
)
2203 H_AUTO_OGL(CDriverGL_getTextureHandle
)
2204 // If DrvShare not setuped
2205 if(!tex
.TextureDrvShare
)
2208 // If DrvInfo not setuped
2209 const CTextureDrvInfosGL
*t0
= (const CTextureDrvInfosGL
*)(const ITextureDrvInfos
*)(tex
.TextureDrvShare
->DrvTexture
);
2216 // ***************************************************************************
2219 Under opengl, "render to texture" uses the frame buffer. The scene is rendered into the current frame buffer and the result
2220 is copied into the texture.
2222 setRenderTarget (tex) does nothing but backup the framebuffer area used and updates the viewport and scissor
2223 setRenderTarget (NULL) copies the modified framebuffer area into "tex" and then, updates the viewport and scissor
2226 bool CDriverGL::setRenderTarget (ITexture
*tex
, uint32 x
, uint32 y
, uint32 width
, uint32 height
, uint32 mipmapLevel
, uint32 cubeFace
)
2228 H_AUTO_OGL(CDriverGL_setRenderTarget
)
2230 // make backup of offscreen buffer to old texture if not using FBOs
2231 if (!_RenderTargetFBO
&& _TextureTarget
&& _TextureTargetUpload
&& (_TextureTarget
!= tex
|| _TextureTargetCubeFace
!= cubeFace
))
2234 copyFrameBufferToTexture (_TextureTarget
, _TextureTargetLevel
, _TextureTargetX
, _TextureTargetY
, 0,
2235 0, _TextureTargetWidth
, _TextureTargetHeight
, _TextureTargetCubeFace
);
2238 // Set a new texture as render target ?
2241 // Check the texture is a render target
2242 nlassertex (tex
->getRenderTarget(), ("The texture must be a render target. Call ITexture::setRenderTarget(true)."));
2244 if(tex
->isBloomTexture() && supportBloomEffect())
2246 // NOTE: No support for mip map level here!
2249 getWindowSize(w
, h
);
2251 getViewport(_OldViewport
);
2253 if (!width
) width
= tex
->getWidth();
2254 if (!height
) height
= tex
->getHeight();
2257 newVP
.init(0, 0, ((float)width
/(float)w
), ((float)height
/(float)h
));
2258 setupViewport(newVP
);
2260 _RenderTargetFBO
= tex
;
2262 return activeFrameBufferObject(tex
);
2265 // Backup the parameters
2266 _TextureTargetLevel
= mipmapLevel
;
2267 _TextureTargetX
= x
;
2268 _TextureTargetY
= y
;
2269 _TextureTargetWidth
= width
;
2270 _TextureTargetHeight
= height
;
2271 _TextureTargetUpload
= true;
2272 _TextureTargetCubeFace
= cubeFace
;
2274 else if (_RenderTargetFBO
)
2276 activeFrameBufferObject(NULL
);
2277 setupViewport(_OldViewport
);
2278 _OldViewport
= _CurrViewport
;
2280 _RenderTargetFBO
= NULL
;
2284 // Backup the texture
2285 _TextureTarget
= tex
;
2287 // Update the viewport
2288 setupViewport (_CurrViewport
);
2290 // Update the scissor
2291 setupScissor (_CurrScissor
);
2293 _RenderTargetFBO
= NULL
;
2294 _OldViewport
= _CurrViewport
;
2299 ITexture
*CDriverGL::getRenderTarget() const
2301 return _RenderTargetFBO
? _RenderTargetFBO
: _TextureTarget
;
2304 // ***************************************************************************
2306 bool CDriverGL::copyTargetToTexture (ITexture
*tex
,
2315 H_AUTO_OGL(CDriverGL_copyTargetToTexture
)
2316 if (!_TextureTarget
)
2318 _TextureTargetUpload
= false;
2319 if ((width
== 0) || (height
== 0))
2323 getRenderTargetSize (_width
, _height
);
2329 copyFrameBufferToTexture(tex
, mipmapLevel
, offsetx
, offsety
, x
, y
, width
, height
);
2333 // ***************************************************************************
2335 bool CDriverGL::getRenderTargetSize (uint32
&width
, uint32
&height
)
2337 H_AUTO_OGL(CDriverGL_getRenderTargetSize
)
2338 NLMISC::CSmartPtr
<ITexture
> tex
= _RenderTargetFBO
? _RenderTargetFBO
: (_TextureTarget
? _TextureTarget
: NULL
);
2341 width
= tex
->getWidth();
2342 height
= tex
->getHeight();
2346 getWindowSize(width
, height
);
2352 // ***************************************************************************