Changed: #1275 Create an OpenGL ES driver

This commit is contained in:
kervala 2012-05-12 19:21:52 +02:00
parent 4d9ee467e1
commit 8eace20bd5
16 changed files with 1590 additions and 270 deletions

View file

@ -2,6 +2,10 @@ IF(WITH_DRIVER_OPENGL)
ADD_SUBDIRECTORY(opengl)
ENDIF(WITH_DRIVER_OPENGL)
IF(WITH_DRIVER_OPENGLES)
ADD_SUBDIRECTORY(opengles)
ENDIF(WITH_DRIVER_OPENGLES)
IF(WIN32)
IF(WITH_DRIVER_DIRECT3D)
ADD_SUBDIRECTORY(direct3d)

View file

@ -21,21 +21,6 @@
// by default, we disable the windows menu keys (F10, ALT and ALT+SPACE key doesn't freeze or open the menu)
#define NL_DISABLE_MENU
#ifdef NL_OS_WINDOWS
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include <windows.h>
# include <windowsx.h>
# include <string>
# include <GL/gl.h>
#elif defined(NL_OS_MAC)
#elif defined (NL_OS_UNIX)
# include <GL/gl.h>
# include <GL/glx.h>
#endif // NL_OS_UNIX
#include <vector>
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"
@ -162,12 +147,21 @@ extern "C"
GLenum CDriverGL::NLCubeFaceToGLCubeFace[6] =
{
#ifdef USE_OPENGLES
GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES
#else
GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
#endif
};
// ***************************************************************************
@ -175,7 +169,13 @@ CDriverGL::CDriverGL()
{
H_AUTO_OGL(CDriverGL_CDriverGL)
#ifdef NL_OS_WINDOWS
#ifdef USE_OPENGLES
_EglDisplay = 0;
_EglContext = 0;
_EglSurface = 0;
#elif defined(NL_OS_WINDOWS)
_PBuffer = NULL;
_hRC = NULL;
@ -296,7 +296,11 @@ CDriverGL::CDriverGL()
for(i=0; i < IDRV_MAT_MAXTEXTURES; i++)
{
_MaterialAllTextureTouchedFlag|= IDRV_TOUCHED_TEX[i];
#ifdef GL_NONE
_CurrentTexAddrMode[i] = GL_NONE;
#else
_CurrentTexAddrMode[i] = 0;
#endif
}
_UserTexMatEnabled = 0;
@ -381,7 +385,9 @@ bool CDriverGL::setupDisplay()
for(uint i = 0; i < lines.size(); i++)
nlinfo("3D: %s", lines[i].c_str());
#ifdef NL_OS_WINDOWS
#ifdef USE_OPENGLES
registerEGlExtensions(_Extensions, _EglDisplay);
#elif defined(NL_OS_WINDOWS)
registerWGlExtensions(_Extensions, _hDC);
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
@ -421,18 +427,30 @@ bool CDriverGL::setupDisplay()
glViewport(0,0,_CurrentMode.Width,_CurrentMode.Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef USE_OPENGLES
glOrthof(0.f,_CurrentMode.Width,_CurrentMode.Height,0.f,-1.0f,1.0f);
#else
glOrtho(0,_CurrentMode.Width,_CurrentMode.Height,0,-1.0f,1.0f);
#endif
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
#ifndef USE_OPENGLES
glDisable(GL_AUTO_NORMAL);
#endif
glDisable(GL_COLOR_MATERIAL);
#ifndef USE_OPENGLES
glEnable(GL_DITHER);
#endif
glDisable(GL_FOG);
glDisable(GL_LINE_SMOOTH);
#ifndef USE_OPENGLES
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
#endif
glEnable(GL_DEPTH_TEST);
glDisable(GL_NORMALIZE);
#ifndef USE_OPENGLES
glDisable(GL_COLOR_SUM_EXT);
#endif
_CurrViewport.init(0.f, 0.f, 1.f, 1.f);
_CurrScissor.initFullScreen();
@ -451,7 +469,9 @@ bool CDriverGL::setupDisplay()
// Be always in EXTSeparateSpecularColor.
if(_Extensions.EXTSeparateSpecularColor)
{
#ifndef USE_OPENGLES
glLightModeli((GLenum)GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
#endif
}
_VertexProgramEnabled= false;
@ -470,6 +490,7 @@ bool CDriverGL::setupDisplay()
_SupportVBHard= true;
_MaxVerticesByVBHard = std::numeric_limits<uint32>::max(); // cant' know the value..
}
#ifndef USE_OPENGLES
// Next with NVidia ext
else if(_Extensions.NVVertexArrayRange)
{
@ -500,6 +521,7 @@ bool CDriverGL::setupDisplay()
// tmp fix for ati
_MaxVerticesByVBHard= 16777216;
}
#endif
// Reset VertexArrayRange.
_CurrentVertexArrayRange= NULL;
@ -559,6 +581,7 @@ bool CDriverGL::setupDisplay()
// set All TexGen by default to identity matrix (prefer use the textureMatrix scheme)
_DriverGLStates.activeTextureARB(stage);
#ifndef USE_OPENGLES
GLfloat params[4];
params[0]=1; params[1]=0; params[2]=0; params[3]=0;
glTexGenfv(GL_S, GL_OBJECT_PLANE, params);
@ -572,6 +595,7 @@ bool CDriverGL::setupDisplay()
params[0]=0; params[1]=0; params[2]=0; params[3]=1;
glTexGenfv(GL_Q, GL_OBJECT_PLANE, params);
glTexGenfv(GL_Q, GL_EYE_PLANE, params);
#endif
}
resetTextureShaders();
@ -603,42 +627,44 @@ bool CDriverGL::setupDisplay()
// check whether per pixel lighting shader is supported
checkForPerPixelLightingSupport();
#ifndef USE_OPENGLES
// if EXTVertexShader is used, bind the standard GL arrays, and allocate constant
if (!_Extensions.NVVertexProgram && !_Extensions.ARBVertexProgram && _Extensions.EXTVertexShader)
{
_EVSPositionHandle = nglBindParameterEXT(GL_CURRENT_VERTEX_EXT);
_EVSNormalHandle = nglBindParameterEXT(GL_CURRENT_NORMAL);
_EVSColorHandle = nglBindParameterEXT(GL_CURRENT_COLOR);
_EVSPositionHandle = nglBindParameterEXT(GL_CURRENT_VERTEX_EXT);
_EVSNormalHandle = nglBindParameterEXT(GL_CURRENT_NORMAL);
_EVSColorHandle = nglBindParameterEXT(GL_CURRENT_COLOR);
if (!_EVSPositionHandle || !_EVSNormalHandle || !_EVSColorHandle)
if (!_EVSPositionHandle || !_EVSNormalHandle || !_EVSColorHandle)
{
nlwarning("Unable to bind input parameters for use with EXT_vertex_shader, vertex program support is disabled");
_Extensions.EXTVertexShader = false;
}
else
{
// bind texture units
for(uint k = 0; k < 8; ++k)
{
nlwarning("Unable to bind input parameters for use with EXT_vertex_shader, vertex program support is disabled");
_EVSTexHandle[k] = nglBindTextureUnitParameterEXT(GL_TEXTURE0_ARB + k, GL_CURRENT_TEXTURE_COORDS);
}
// Other attributes are managed using variant pointers :
// Secondary color
// Fog Coords
// Skin Weight
// Skin palette
// This mean that they must have 4 components
// Allocate invariants. One assitionnal variant is needed for fog coordinate if fog bug is not fixed in driver version
_EVSConstantHandle = nglGenSymbolsEXT(GL_VECTOR_EXT, GL_INVARIANT_EXT, GL_FULL_RANGE_EXT, _EVSNumConstant + (_ATIFogRangeFixed ? 0 : 1));
if (_EVSConstantHandle == 0)
{
nlwarning("Unable to allocate constants for EXT_vertex_shader, vertex program support is disabled");
_Extensions.EXTVertexShader = false;
}
else
{
// bind texture units
for(uint k = 0; k < 8; ++k)
{
_EVSTexHandle[k] = nglBindTextureUnitParameterEXT(GL_TEXTURE0_ARB + k, GL_CURRENT_TEXTURE_COORDS);
}
// Other attributes are managed using variant pointers :
// Secondary color
// Fog Coords
// Skin Weight
// Skin palette
// This mean that they must have 4 components
// Allocate invariants. One assitionnal variant is needed for fog coordinate if fog bug is not fixed in driver version
_EVSConstantHandle = nglGenSymbolsEXT(GL_VECTOR_EXT, GL_INVARIANT_EXT, GL_FULL_RANGE_EXT, _EVSNumConstant + (_ATIFogRangeFixed ? 0 : 1));
if (_EVSConstantHandle == 0)
{
nlwarning("Unable to allocate constants for EXT_vertex_shader, vertex program support is disabled");
_Extensions.EXTVertexShader = false;
}
}
}
}
#endif
// Reset the vbl interval
setSwapVBLInterval(_Interval);
@ -685,7 +711,11 @@ bool CDriverGL::activeFrameBufferObject(ITexture * tex)
}
else
{
#ifdef USE_OPENGLES
nglBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
#else
nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
#endif
return true;
}
}
@ -717,7 +747,9 @@ void CDriverGL::disableHardwareTextureShader()
// --------------------------------------------------
void CDriverGL::resetTextureShaders()
{
H_AUTO_OGL(CDriverGL_resetTextureShaders)
H_AUTO_OGL(CDriverGL_resetTextureShaders);
#ifndef USE_OPENGLES
if (_Extensions.NVTextureShader)
{
glEnable(GL_TEXTURE_SHADER_NV);
@ -739,6 +771,7 @@ void CDriverGL::resetTextureShaders()
_NVTextureShaderEnabled = false;
}
#endif
}
// --------------------------------------------------
@ -773,8 +806,13 @@ bool CDriverGL::clear2D(CRGBA rgba)
// --------------------------------------------------
bool CDriverGL::clearZBuffer(float zval)
{
H_AUTO_OGL(CDriverGL_clearZBuffer)
H_AUTO_OGL(CDriverGL_clearZBuffer);
#ifdef USE_OPENGLES
glClearDepthf(zval);
#else
glClearDepth(zval);
#endif
_DriverGLStates.enableZWrite(true);
glClear(GL_DEPTH_BUFFER_BIT);
@ -810,6 +848,7 @@ bool CDriverGL::swapBuffers()
//resetTextureShaders();
activeVertexProgram(NULL);
#ifndef USE_OPENGLES
/* Yoyo: must do this (GeForce bug ??) else weird results if end render with a VBHard.
Setup a std vertex buffer to ensure NVidia synchronisation.
*/
@ -872,6 +911,7 @@ bool CDriverGL::swapBuffers()
itVBHard++;
}
}
#endif
#ifdef NL_OS_WINDOWS
if (_EventEmitter.getNumEmitters() > 1) // is direct input running ?
@ -887,7 +927,11 @@ bool CDriverGL::swapBuffers()
if (_VRAMVertexArrayRange) _VRAMVertexArrayRange->updateLostBuffers();
}
#ifdef NL_OS_WINDOWS
#ifdef USE_OPENGLES
eglSwapBuffers (_EglDisplay, _EglSurface);
#elif defined(NL_OS_WINDOWS)
SwapBuffers(_hDC);
@ -908,6 +952,7 @@ bool CDriverGL::swapBuffers()
#endif // NL_OS_WINDOWS
#ifndef USE_OPENGLES
// Activate the default texture environnments for all stages.
//===========================================================
// This is not a requirement, but it ensure a more stable state each frame.
@ -935,6 +980,8 @@ bool CDriverGL::swapBuffers()
glDisable(GL_TEXTURE_SHADER_NV);
_NVTextureShaderEnabled = false;
}
#endif
_CurrentMaterial= NULL;
// Reset the profiling counter.
@ -1184,9 +1231,14 @@ void CDriverGL::getZBufferPart (std::vector<float> &zbuffer, NLMISC::CRect &rec
if(clipRect(rect))
{
zbuffer.resize(rect.Width*rect.Height);
#ifdef USE_OPENGLES
glReadPixels (rect.X, rect.Y, rect.Width, rect.Height, GL_DEPTH_COMPONENT16_OES, GL_FLOAT, &(zbuffer[0]));
#else
glPixelTransferf(GL_DEPTH_SCALE, 1.0f) ;
glPixelTransferf(GL_DEPTH_BIAS, 0.f) ;
glReadPixels (rect.X, rect.Y, rect.Width, rect.Height, GL_DEPTH_COMPONENT , GL_FLOAT, &(zbuffer[0]));
#endif
}
}
@ -1215,8 +1267,23 @@ bool CDriverGL::fillBuffer (CBitmap &bitmap)
if( rect.Width!=bitmap.getWidth() || rect.Height!=bitmap.getHeight() || bitmap.getPixelFormat()!=CBitmap::RGBA )
return false;
#ifdef USE_OPENGLES
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rect.Width, rect.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &(bitmap.getPixels()[0]));
// glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, smBackgroundCrop,0);
nglDrawTexfOES(0.f, 0.f, 0.f, 1.f, 1.f);
#else
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glDrawPixels (rect.Width, rect.Height, GL_RGBA, GL_UNSIGNED_BYTE, &(bitmap.getPixels()[0]) );
#endif
return true;
}
@ -1245,15 +1312,22 @@ void CDriverGL::copyFrameBufferToTexture(ITexture *tex,
_DriverGLStates.activeTextureARB(0);
// setup texture mode, after activeTextureARB()
CDriverGLStates::TTextureMode textureMode= CDriverGLStates::Texture2D;
#ifdef GL_TEXTURE_RECTANGLE_NV
if(gltext->TextureMode == GL_TEXTURE_RECTANGLE_NV)
textureMode = CDriverGLStates::TextureRect;
#endif
_DriverGLStates.setTextureMode(textureMode);
if (tex->isTextureCube())
{
if(_Extensions.ARBTextureCubeMap)
{
#ifdef USE_OPENGLES
glBindTexture(GL_TEXTURE_CUBE_MAP_OES, gltext->ID);
#else
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, gltext->ID);
#endif
glCopyTexSubImage2D(NLCubeFaceToGLCubeFace[cubeFace], level, offsetx, offsety, x, y, width, height);
}
}
@ -1276,6 +1350,7 @@ void CDriverGL::setPolygonMode (TPolygonMode mode)
H_AUTO_OGL(CDriverGL_setPolygonMode )
IDriver::setPolygonMode (mode);
#ifndef USE_OPENGLES
// Set the polygon mode
switch (_PolygonMode)
{
@ -1289,6 +1364,7 @@ void CDriverGL::setPolygonMode (TPolygonMode mode)
glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
break;
}
#endif
}
// ***************************************************************************
@ -1488,7 +1564,10 @@ void CDriverGL::setMatrix2DForTextureOffsetAddrMode(const uint stage, const floa
//nlassert(supportTextureShaders());
nlassert(stage < inlGetNumTextStages() );
_DriverGLStates.activeTextureARB(stage);
#ifndef USE_OPENGLES
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, mat);
#endif
}
@ -1499,7 +1578,7 @@ void CDriverGL::enableNVTextureShader(bool enabled)
if (enabled != _NVTextureShaderEnabled)
{
#ifndef USE_OPENGLES
if (enabled)
{
glEnable(GL_TEXTURE_SHADER_NV);
@ -1508,6 +1587,7 @@ void CDriverGL::enableNVTextureShader(bool enabled)
{
glDisable(GL_TEXTURE_SHADER_NV);
}
#endif
_NVTextureShaderEnabled = enabled;
}
}
@ -1568,8 +1648,11 @@ void CDriverGL::setBlendConstantColor(NLMISC::CRGBA col)
// update GL
if(!_Extensions.EXTBlendColor)
return;
#ifndef USE_OPENGLES
static const float OO255= 1.0f/255;
nglBlendColorEXT(col.R*OO255, col.G*OO255, col.B*OO255, col.A*OO255);
#endif
}
// ***************************************************************************
@ -1623,6 +1706,7 @@ void CDriverGL::setEMBMMatrix(const uint stage,const float mat[4])
{
H_AUTO_OGL(CDriverGL_setEMBMMatrix)
#ifndef USE_OPENGLES
nlassert(supportEMBM());
nlassert(stage < IDRV_MAT_MAXTEXTURES);
//
@ -1631,13 +1715,15 @@ void CDriverGL::setEMBMMatrix(const uint stage,const float mat[4])
_DriverGLStates.activeTextureARB(stage);
nglTexBumpParameterfvATI(GL_BUMP_ROT_MATRIX_ATI, const_cast<float *>(mat));
}
#endif
}
// ***************************************************************************
void CDriverGL::initEMBM()
{
H_AUTO_OGL(CDriverGL_initEMBM)
H_AUTO_OGL(CDriverGL_initEMBM);
#ifndef USE_OPENGLES
if (supportEMBM())
{
std::fill(_StageSupportEMBM, _StageSupportEMBM + IDRV_MAT_MAXTEXTURES, false);
@ -1687,6 +1773,7 @@ void CDriverGL::initEMBM()
_DriverGLStates.activeTextureARB(0);
}
}
#endif
}
// ***************************************************************************
@ -1832,6 +1919,8 @@ uint loadARBFragmentProgramStringNative(const char *prog, bool forceNativeProgra
nlwarning("The param 'prog' is null, cannot load");
return 0;
}
#ifndef USE_OPENGLES
GLuint progID;
nglGenProgramsARB(1, &progID);
if (!progID)
@ -1859,6 +1948,8 @@ uint loadARBFragmentProgramStringNative(const char *prog, bool forceNativeProgra
{
nlwarning("init fragment program failed: errorPos: %d isNative: %d: %s", errorPos, isNative, (const char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB));
}
#endif
return 0;
}
@ -1869,11 +1960,12 @@ uint loadARBFragmentProgramStringNative(const char *prog, bool forceNativeProgra
*/
static void fetchPerturbedEnvMapR200()
{
H_AUTO_OGL(CDriverGL_fetchPerturbedEnvMapR200)
H_AUTO_OGL(CDriverGL_fetchPerturbedEnvMapR200);
#ifndef USE_OPENGLES
////////////
// PASS 1 //
////////////
nglSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI); // sample bump map 0
nglSampleMapATI(GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI); // sample bump map 1
nglPassTexCoordATI(GL_REG_2_ATI, GL_TEXTURE2_ARB, GL_SWIZZLE_STR_ATI); // get texcoord for envmap
@ -1885,6 +1977,7 @@ static void fetchPerturbedEnvMapR200()
// PASS 2 //
////////////
nglSampleMapATI(GL_REG_2_ATI, GL_REG_2_ATI, GL_SWIZZLE_STR_ATI); // fetch envmap at perturbed texcoords
#endif
}
// ***************************************************************************
@ -1896,8 +1989,9 @@ void CDriverGL::forceNativeFragmentPrograms(bool nativeOnly)
// ***************************************************************************
void CDriverGL::initFragmentShaders()
{
H_AUTO_OGL(CDriverGL_initFragmentShaders)
H_AUTO_OGL(CDriverGL_initFragmentShaders);
#ifndef USE_OPENGLES
///////////////////
// WATER SHADERS //
///////////////////
@ -2006,13 +2100,15 @@ void CDriverGL::initFragmentShaders()
}
// if none of the previous programs worked, fallback on NV_texture_shader, or (todo) simpler shader
#endif
}
// ***************************************************************************
void CDriverGL::deleteARBFragmentPrograms()
{
H_AUTO_OGL(CDriverGL_deleteARBFragmentPrograms)
H_AUTO_OGL(CDriverGL_deleteARBFragmentPrograms);
#ifndef USE_OPENGLES
for(uint k = 0; k < 4; ++k)
{
if (ARBWaterShader[k])
@ -2022,6 +2118,7 @@ void CDriverGL::deleteARBFragmentPrograms()
ARBWaterShader[k] = 0;
}
}
#endif
}
// ***************************************************************************
@ -2029,6 +2126,7 @@ void CDriverGL::deleteFragmentShaders()
{
H_AUTO_OGL(CDriverGL_deleteFragmentShaders)
#ifndef USE_OPENGLES
deleteARBFragmentPrograms();
if (ATIWaterShaderHandleNoDiffuseMap)
@ -2046,6 +2144,7 @@ void CDriverGL::deleteFragmentShaders()
nglDeleteFragmentShaderATI((GLuint) ATICloudShaderHandle);
ATICloudShaderHandle = 0;
}
#endif
}
// ***************************************************************************
@ -2072,7 +2171,9 @@ void CDriverGL::setSwapVBLInterval(uint interval)
bool res = true;
#ifdef NL_OS_WINDOWS
#ifdef USE_OPENGLES
res = eglSwapInterval(_EglDisplay, _Interval) == EGL_TRUE;
#elif defined(NL_OS_WINDOWS)
if(_Extensions.WGLEXTSwapControl)
{
res = nwglSwapIntervalEXT(_Interval) == TRUE;
@ -2108,7 +2209,8 @@ uint CDriverGL::getSwapVBLInterval()
{
H_AUTO_OGL(CDriverGL_getSwapVBLInterval)
#ifdef NL_OS_WINDOWS
#ifdef USE_OPENGLES
#elif defined(NL_OS_WINDOWS)
if(_Extensions.WGLEXTSwapControl)
{
return nwglGetSwapIntervalEXT();
@ -2135,12 +2237,14 @@ uint CDriverGL::getSwapVBLInterval()
// ***************************************************************************
void CDriverGL::enablePolygonSmoothing(bool smooth)
{
H_AUTO_OGL(CDriverGL_enablePolygonSmoothing)
H_AUTO_OGL(CDriverGL_enablePolygonSmoothing);
#ifndef USE_OPENGLES
if(smooth)
glEnable(GL_POLYGON_SMOOTH);
else
glDisable(GL_POLYGON_SMOOTH);
#endif
_PolygonSmooth= smooth;
}
@ -2576,6 +2680,8 @@ IOcclusionQuery *CDriverGL::createOcclusionQuery()
{
H_AUTO_OGL(CDriverGL_createOcclusionQuery)
nlassert(_Extensions.NVOcclusionQuery);
#ifndef USE_OPENGLES
GLuint id;
nglGenOcclusionQueriesNV(1, &id);
if (id == 0) return NULL;
@ -2587,12 +2693,17 @@ IOcclusionQuery *CDriverGL::createOcclusionQuery()
oqgl->Iterator = _OcclusionQueryList.begin();
oqgl->VisibleCount = 0;
return oqgl;
#else
return NULL;
#endif
}
// ***************************************************************************
void CDriverGL::deleteOcclusionQuery(IOcclusionQuery *oq)
{
H_AUTO_OGL(CDriverGL_deleteOcclusionQuery)
H_AUTO_OGL(CDriverGL_deleteOcclusionQuery);
#ifndef USE_OPENGLES
if (!oq) return;
COcclusionQueryGL *oqgl = NLMISC::safe_cast<COcclusionQueryGL *>(oq);
nlassert((CDriverGL *) oqgl->Driver == this); // should come from the same driver
@ -2606,12 +2717,15 @@ void CDriverGL::deleteOcclusionQuery(IOcclusionQuery *oq)
_CurrentOcclusionQuery = NULL;
}
delete oqgl;
#endif
}
// ***************************************************************************
void COcclusionQueryGL::begin()
{
H_AUTO_OGL(COcclusionQueryGL_begin)
H_AUTO_OGL(COcclusionQueryGL_begin);
#ifndef USE_OPENGLES
nlassert(Driver);
nlassert(Driver->_CurrentOcclusionQuery == NULL); // only one query at a time
nlassert(ID);
@ -2619,23 +2733,29 @@ void COcclusionQueryGL::begin()
Driver->_CurrentOcclusionQuery = this;
OcclusionType = NotAvailable;
VisibleCount = 0;
#endif
}
// ***************************************************************************
void COcclusionQueryGL::end()
{
H_AUTO_OGL(COcclusionQueryGL_end)
H_AUTO_OGL(COcclusionQueryGL_end);
#ifndef USE_OPENGLES
nlassert(Driver);
nlassert(Driver->_CurrentOcclusionQuery == this); // only one query at a time
nlassert(ID);
nglEndOcclusionQueryNV();
Driver->_CurrentOcclusionQuery = NULL;
#endif
}
// ***************************************************************************
IOcclusionQuery::TOcclusionType COcclusionQueryGL::getOcclusionType()
{
H_AUTO_OGL(COcclusionQueryGL_getOcclusionType)
H_AUTO_OGL(COcclusionQueryGL_getOcclusionType);
#ifndef USE_OPENGLES
nlassert(Driver);
nlassert(ID);
nlassert(Driver->_CurrentOcclusionQuery != this); // can't query result between a begin/end pair!
@ -2652,6 +2772,7 @@ IOcclusionQuery::TOcclusionType COcclusionQueryGL::getOcclusionType()
// Note : we could return the exact number of pixels that passed the z-test, but this value is not supported by all implementation (Direct3D ...)
}
}
#endif
return OcclusionType;
}

View file

@ -26,21 +26,10 @@
# define H_AUTO_OGL(label)
#endif
#ifdef NL_OS_WINDOWS
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include <windows.h>
# include <GL/gl.h>
#elif defined(NL_OS_MAC)
# define GL_GLEXT_LEGACY
#ifdef NL_OS_MAC
# import <Cocoa/Cocoa.h>
# include <OpenGL/gl.h>
# include "mac/glext.h"
# import "mac/cocoa_opengl_view.h"
#elif defined (NL_OS_UNIX)
# define GLX_GLXEXT_PROTOTYPES
# include <GL/gl.h>
# include <GL/glx.h>
# ifdef XF86VIDMODE
# include <X11/extensions/xf86vmode.h>
# endif //XF86VIDMODE
@ -764,22 +753,32 @@ private:
TCursorMap _Cursors;
#ifdef USE_OPENGLES
EGLDisplay _EglDisplay;
EGLContext _EglContext;
EGLSurface _EglSurface;
#elif defined(NL_OS_WINDOWS)
HGLRC _hRC;
HDC _hDC;
PIXELFORMATDESCRIPTOR _pfd;
// Off-screen rendering in Dib section
HPBUFFERARB _PBuffer;
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
GLXContext _ctx;
#endif
#ifdef NL_OS_WINDOWS
bool convertBitmapToIcon(const NLMISC::CBitmap &bitmap, HICON &icon, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col = NLMISC::CRGBA::White, sint hotSpotX = 0, sint hotSpotY = 0, bool cursor = false);
friend bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HDC _hDC;
PIXELFORMATDESCRIPTOR _pfd;
HGLRC _hRC;
static uint _Registered;
DEVMODE _OldScreenMode;
NLMISC::CEventEmitterMulti _EventEmitter; // this can contains a win emitter and eventually a direct input emitter
// Off-screen rendering in Dib section
HPBUFFERARB _PBuffer;
#elif defined(NL_OS_MAC)
friend bool GlWndProc(CDriverGL*, const void*);
@ -804,7 +803,6 @@ private:
friend bool GlWndProc(CDriverGL *driver, XEvent &e);
Display* _dpy;
GLXContext _ctx;
NLMISC::CUnixEventEmitter _EventEmitter;
XVisualInfo* _visual_info;
uint32 _xrandr_version;
@ -963,6 +961,7 @@ private:
bool _CurrentGlNormalize;
private:
bool createContext();
bool setupDisplay();
bool unInit();

View file

@ -16,18 +16,20 @@
#include "stdopengl.h"
#include "driver_opengl.h"
#include "driver_opengl_extension.h"
#include "nel/misc/common.h"
#include "driver_opengl.h"
#include "driver_opengl_extension.h"
#include "nel/3d/material.h"
using namespace std;
using namespace NLMISC;
// ***************************************************************************
#ifdef NL_OS_WINDOWS
#ifdef USE_OPENGLES
#define nglGetProcAddress eglGetProcAddress
#elif defined(NL_OS_WINDOWS)
#define nglGetProcAddress wglGetProcAddress
#elif defined(NL_OS_MAC)
// #include <mach-o/dyld.h>
@ -63,6 +65,47 @@ void (*nglGetProcAddress(const char *procName))()
// ***************************************************************************
// The exported function names
#ifdef USE_OPENGLES
// GL_OES_mapbuffer
NEL_PFNGLMAPBUFFEROESPROC nglMapBufferOES;
NEL_PFNGLUNMAPBUFFEROESPROC nglUnmapBufferOES;
NEL_PFNGLGETBUFFERPOINTERVOESPROC nglGetBufferPointervOES;
NEL_PFNGLBUFFERSUBDATAPROC nglBufferSubData;
PFNGLDRAWTEXFOESPROC nglDrawTexfOES;
// GL_OES_framebuffer_object
NEL_PFNGLISRENDERBUFFEROESPROC nglIsRenderbufferOES;
NEL_PFNGLBINDRENDERBUFFEROESPROC nglBindRenderbufferOES;
NEL_PFNGLDELETERENDERBUFFERSOESPROC nglDeleteRenderbuffersOES;
NEL_PFNGLGENRENDERBUFFERSOESPROC nglGenRenderbuffersOES;
NEL_PFNGLRENDERBUFFERSTORAGEOESPROC nglRenderbufferStorageOES;
NEL_PFNGLGETRENDERBUFFERPARAMETERIVOESPROC nglGetRenderbufferParameterivOES;
NEL_PFNGLISFRAMEBUFFEROESPROC nglIsFramebufferOES;
NEL_PFNGLBINDFRAMEBUFFEROESPROC nglBindFramebufferOES;
NEL_PFNGLDELETEFRAMEBUFFERSOESPROC nglDeleteFramebuffersOES;
NEL_PFNGLGENFRAMEBUFFERSOESPROC nglGenFramebuffersOES;
NEL_PFNGLCHECKFRAMEBUFFERSTATUSOESPROC nglCheckFramebufferStatusOES;
NEL_PFNGLFRAMEBUFFERRENDERBUFFEROESPROC nglFramebufferRenderbufferOES;
NEL_PFNGLFRAMEBUFFERTEXTURE2DOESPROC nglFramebufferTexture2DOES;
NEL_PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC nglGetFramebufferAttachmentParameterivOES;
NEL_PFNGLGENERATEMIPMAPOESPROC nglGenerateMipmapOES;
// GL_OES_texture_cube_map
NEL_PFNGLTEXGENFOESPROC nglTexGenfOES;
NEL_PFNGLTEXGENFVOESPROC nglTexGenfvOES;
NEL_PFNGLTEXGENIOESPROC nglTexGeniOES;
NEL_PFNGLTEXGENIVOESPROC nglTexGenivOES;
NEL_PFNGLTEXGENXOESPROC nglTexGenxOES;
NEL_PFNGLTEXGENXVOESPROC nglTexGenxvOES;
NEL_PFNGLGETTEXGENFVOESPROC nglGetTexGenfvOES;
NEL_PFNGLGETTEXGENIVOESPROC nglGetTexGenivOES;
NEL_PFNGLGETTEXGENXVOESPROC nglGetTexGenxvOES;
#else
// ARB_multitexture
NEL_PFNGLACTIVETEXTUREARBPROC nglActiveTextureARB;
NEL_PFNGLCLIENTACTIVETEXTUREARBPROC nglClientActiveTextureARB;
@ -468,6 +511,8 @@ NEL_PFNGLXGETSWAPINTERVALMESAPROC nglXGetSwapIntervalMESA;
#endif
#endif // USE_OPENGLES
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
@ -493,6 +538,8 @@ namespace NL3D
static bool setupARBMultiTexture(const char *glext)
{
H_AUTO_OGL(setupARBMultiTexture);
#ifndef USE_OPENGLES
CHECK_EXT("GL_ARB_multitexture");
CHECK_ADDRESS(NEL_PFNGLACTIVETEXTUREARBPROC, glActiveTextureARB);
@ -531,16 +578,21 @@ static bool setupARBMultiTexture(const char *glext)
CHECK_ADDRESS(NEL_PFNGLMULTITEXCOORD4IVARBPROC, glMultiTexCoord4ivARB);
CHECK_ADDRESS(NEL_PFNGLMULTITEXCOORD4FVARBPROC, glMultiTexCoord4fvARB);
CHECK_ADDRESS(NEL_PFNGLMULTITEXCOORD4DVARBPROC, glMultiTexCoord4dvARB);
#endif
return true;
}
// *********************************
static bool setupEXTTextureEnvCombine(const char *glext)
{
H_AUTO_OGL(setupEXTTextureEnvCombine);
#ifdef USE_OPENGLES
return true;
#else
return (strstr(glext, "GL_EXT_texture_env_combine")!=NULL || strstr(glext, "GL_ARB_texture_env_combine")!=NULL);
#endif
}
@ -548,6 +600,8 @@ static bool setupEXTTextureEnvCombine(const char *glext)
static bool setupARBTextureCompression(const char *glext)
{
H_AUTO_OGL(setupARBTextureCompression);
#ifndef USE_OPENGLES
CHECK_EXT("GL_ARB_texture_compression");
CHECK_ADDRESS(NEL_PFNGLCOMPRESSEDTEXIMAGE3DARBPROC, glCompressedTexImage3DARB);
@ -557,20 +611,52 @@ static bool setupARBTextureCompression(const char *glext)
CHECK_ADDRESS(NEL_PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC, glCompressedTexSubImage2DARB);
CHECK_ADDRESS(NEL_PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC, glCompressedTexSubImage1DARB);
CHECK_ADDRESS(NEL_PFNGLGETCOMPRESSEDTEXIMAGEARBPROC, glGetCompressedTexImageARB);
#endif
return true;
}
// *********************************
static bool setupARBTextureNonPowerOfTwo(const char *glext)
{
H_AUTO_OGL(setupARBTextureCompression);
#ifndef USE_OPENGL_ES
CHECK_EXT("GL_ARB_texture_non_power_of_two");
#endif
return true;
}
// ***************************************************************************
static bool setupOESMapBuffer(const char *glext)
{
H_AUTO_OGL(setupOESMapBuffer);
CHECK_EXT("OES_mapbuffer");
#ifdef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLMAPBUFFEROESPROC, glMapBufferOES);
CHECK_ADDRESS(NEL_PFNGLUNMAPBUFFEROESPROC, glUnmapBufferOES);
CHECK_ADDRESS(NEL_PFNGLGETBUFFERPOINTERVOESPROC, glGetBufferPointervOES);
#endif
return true;
}
// ***************************************************************************
static bool setupOESDrawTexture(const char *glext)
{
H_AUTO_OGL(setupOESDrawTexture);
CHECK_EXT("OES_draw_texture");
#ifdef USE_OPENGLES
CHECK_ADDRESS(PFNGLDRAWTEXFOESPROC, glDrawTexfOES);
#endif
return true;
}
// *********************************
static bool setupNVVertexArrayRange(const char *glext)
@ -583,6 +669,7 @@ static bool setupNVVertexArrayRange(const char *glext)
// Tess Fence too.
CHECK_EXT("GL_NV_fence");
#ifndef USE_OPENGLES
// Get VAR address.
CHECK_ADDRESS(NEL_PFNGLFLUSHVERTEXARRAYRANGENVPROC, glFlushVertexArrayRangeNV);
CHECK_ADDRESS(NEL_PFNGLVERTEXARRAYRANGENVPROC, glVertexArrayRangeNV);
@ -603,29 +690,38 @@ static bool setupNVVertexArrayRange(const char *glext)
CHECK_ADDRESS(NEL_PFNGLGETFENCEIVNVPROC, glGetFenceivNV);
CHECK_ADDRESS(NEL_PFNGLFINISHFENCENVPROC, glFinishFenceNV);
CHECK_ADDRESS(NEL_PFNGLSETFENCENVPROC, glSetFenceNV);
#endif
return true;
}
// *********************************
static bool setupEXTTextureCompressionS3TC(const char *glext)
{
H_AUTO_OGL(setupEXTTextureCompressionS3TC);
#ifdef USE_OPENGLES
CHECK_EXT("EXT_texture_compression_s3tc");
// TODO: check also for EXT_texture_compression_dxt1
#else
CHECK_EXT("GL_EXT_texture_compression_s3tc");
// TODO: check also for GL_S3_s3tc, GL_EXT_texture_compression_dxt1
#endif
return true;
}
// *********************************
static bool setupEXTVertexWeighting(const char *glext)
{
H_AUTO_OGL(setupEXTVertexWeighting);
CHECK_EXT("GL_EXT_vertex_weighting");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLVERTEXWEIGHTFEXTPROC, glVertexWeightfEXT);
CHECK_ADDRESS(NEL_PFNGLVERTEXWEIGHTFVEXTPROC, glVertexWeightfvEXT);
CHECK_ADDRESS(NEL_PFNGLVERTEXWEIGHTPOINTEREXTPROC, glVertexWeightPointerEXT);
#endif
return true;
}
@ -679,6 +775,9 @@ static bool setupATIEnvMapBumpMap(const char *glext)
H_AUTO_OGL(setupATIEnvMapBumpMap);
CHECK_EXT("GL_ATI_envmap_bumpmap");
GLint num = -1;
#ifndef USE_OPENGLES
CHECK_ADDRESS(PFNGLTEXBUMPPARAMETERIVATIPROC, glTexBumpParameterivATI);
CHECK_ADDRESS(PFNGLTEXBUMPPARAMETERFVATIPROC, glTexBumpParameterfvATI);
CHECK_ADDRESS(PFNGLGETTEXBUMPPARAMETERIVATIPROC, glGetTexBumpParameterivATI);
@ -686,8 +785,8 @@ static bool setupATIEnvMapBumpMap(const char *glext)
// Check for broken ATI drivers and disable EMBM if we caught one.
// Reminder: This code crashes with Catalyst 7.11 fglrx drivers!
GLint num = -1;
nglGetTexBumpParameterivATI(GL_BUMP_NUM_TEX_UNITS_ATI, &num);
#endif
return num > 0;
}
@ -696,7 +795,23 @@ static bool setupATIEnvMapBumpMap(const char *glext)
static bool setupARBTextureCubeMap(const char *glext)
{
H_AUTO_OGL(setupARBTextureCubeMap);
#ifdef USE_OPENGLES
CHECK_EXT("OES_texture_cube_map");
#else
CHECK_EXT("GL_ARB_texture_cube_map");
#endif
// CHECK_ADDRESS(NEL_PFNGLTEXGENFOESPROC, glTexGenfOES);
// CHECK_ADDRESS(NEL_PFNGLTEXGENFVOESPROC, glTexGenfvOES);
// CHECK_ADDRESS(NEL_PFNGLTEXGENIOESPROC, glTexGeniOES);
// CHECK_ADDRESS(NEL_PFNGLTEXGENIVOESPROC, glTexGenivOES);
// CHECK_ADDRESS(NEL_PFNGLTEXGENXOESPROC, glTexGenxOES);
// CHECK_ADDRESS(NEL_PFNGLTEXGENXVOESPROC, glTexGenxvOES);
// CHECK_ADDRESS(NEL_PFNGLGETTEXGENFVOESPROC, glGetTexGenfvOES);
// CHECK_ADDRESS(NEL_PFNGLGETTEXGENIVOESPROC, glGetTexGenivOES);
// CHECK_ADDRESS(NEL_PFNGLGETTEXGENXVOESPROC, glGetTexGenxvOES);
return true;
}
@ -714,6 +829,8 @@ static bool setupNVVertexProgram(const char *glext)
// #endif
CHECK_EXT("GL_NV_vertex_program");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLAREPROGRAMSRESIDENTNVPROC, glAreProgramsResidentNV);
CHECK_ADDRESS(NEL_PFNGLBINDPROGRAMNVPROC, glBindProgramNV);
CHECK_ADDRESS(NEL_PFNGLDELETEPROGRAMSNVPROC, glDeleteProgramsNV);
@ -777,6 +894,7 @@ static bool setupNVVertexProgram(const char *glext)
CHECK_ADDRESS(NEL_PFNGLVERTEXATTRIBS4FVNVPROC, glVertexAttribs4fvNV);
CHECK_ADDRESS(NEL_PFNGLVERTEXATTRIBS4SVNVPROC, glVertexAttribs4svNV);
CHECK_ADDRESS(NEL_PFNGLVERTEXATTRIBS4UBVNVPROC, glVertexAttribs4ubvNV);
#endif
return true;
}
@ -787,6 +905,7 @@ static bool setupEXTVertexShader(const char *glext)
H_AUTO_OGL(setupEXTVertexShader);
CHECK_EXT("GL_EXT_vertex_shader");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLBEGINVERTEXSHADEREXTPROC, glBeginVertexShaderEXT);
CHECK_ADDRESS(NEL_PFNGLENDVERTEXSHADEREXTPROC, glEndVertexShaderEXT);
CHECK_ADDRESS(NEL_PFNGLBINDVERTEXSHADEREXTPROC, glBindVertexShaderEXT);
@ -849,6 +968,7 @@ static bool setupEXTVertexShader(const char *glext)
GLint numVSVariants;
glGetIntegerv(GL_MAX_VERTEX_SHADER_VARIANTS_EXT, &numVSVariants);
if (numVSInvariants < 4) return false;
#endif
return true;
@ -861,6 +981,7 @@ static bool setupEXTSecondaryColor(const char *glext)
H_AUTO_OGL(setupEXTSecondaryColor);
CHECK_EXT("GL_EXT_secondary_color");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLSECONDARYCOLOR3BEXTPROC, glSecondaryColor3bEXT);
CHECK_ADDRESS(NEL_PFNGLSECONDARYCOLOR3BVEXTPROC, glSecondaryColor3bvEXT);
CHECK_ADDRESS(NEL_PFNGLSECONDARYCOLOR3DEXTPROC, glSecondaryColor3dEXT);
@ -878,6 +999,7 @@ static bool setupEXTSecondaryColor(const char *glext)
CHECK_ADDRESS(NEL_PFNGLSECONDARYCOLOR3USEXTPROC, glSecondaryColor3usEXT);
CHECK_ADDRESS(NEL_PFNGLSECONDARYCOLOR3USVEXTPROC, glSecondaryColor3usvEXT);
CHECK_ADDRESS(NEL_PFNGLSECONDARYCOLORPOINTEREXTPROC, glSecondaryColorPointerEXT);
#endif
return true;
}
@ -888,12 +1010,14 @@ static bool setupWGLARBPBuffer(const char *glext)
H_AUTO_OGL(setupWGLARBPBuffer);
CHECK_EXT("WGL_ARB_pbuffer");
#ifndef USE_OPENGLES
#ifdef NL_OS_WINDOWS
CHECK_ADDRESS(PFNWGLCREATEPBUFFERARBPROC, wglCreatePbufferARB);
CHECK_ADDRESS(PFNWGLGETPBUFFERDCARBPROC, wglGetPbufferDCARB);
CHECK_ADDRESS(PFNWGLRELEASEPBUFFERDCARBPROC, wglReleasePbufferDCARB);
CHECK_ADDRESS(PFNWGLDESTROYPBUFFERARBPROC, wglDestroyPbufferARB);
CHECK_ADDRESS(PFNWGLQUERYPBUFFERARBPROC, wglQueryPbufferARB);
#endif
#endif
return true;
@ -905,7 +1029,9 @@ static bool setupARBMultisample(const char *glext)
H_AUTO_OGL(setupARBMultisample);
CHECK_EXT("GL_ARB_multisample");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLSAMPLECOVERAGEARBPROC, glSampleCoverageARB);
#endif
return true;
}
@ -917,9 +1043,11 @@ static bool setupWGLARBPixelFormat (const char *glext)
H_AUTO_OGL(setupWGLARBPixelFormat);
CHECK_EXT("WGL_ARB_pixel_format");
#ifndef USE_OPENGLES
CHECK_ADDRESS(PFNWGLGETPIXELFORMATATTRIBIVARBPROC, wglGetPixelFormatAttribivARB);
CHECK_ADDRESS(PFNWGLGETPIXELFORMATATTRIBFVARBPROC, wglGetPixelFormatAttribfvARB);
CHECK_ADDRESS(PFNWGLCHOOSEPIXELFORMATARBPROC, wglChoosePixelFormatARB);
#endif
return true;
}
@ -947,7 +1075,11 @@ static bool setupEXTBlendColor(const char *glext)
{
H_AUTO_OGL(setupEXTBlendColor);
CHECK_EXT("GL_EXT_blend_color");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLBLENDCOLOREXTPROC, glBlendColorEXT);
#endif
return true;
}
@ -966,6 +1098,7 @@ static bool setupATIVertexArrayObject(const char *glext)
H_AUTO_OGL(setupATIVertexArrayObject);
CHECK_EXT("GL_ATI_vertex_array_object");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLNEWOBJECTBUFFERATIPROC, glNewObjectBufferATI);
CHECK_ADDRESS(NEL_PFNGLISOBJECTBUFFERATIPROC, glIsObjectBufferATI);
CHECK_ADDRESS(NEL_PFNGLUPDATEOBJECTBUFFERATIPROC, glUpdateObjectBufferATI);
@ -992,6 +1125,8 @@ static bool setupATIVertexArrayObject(const char *glext)
CHECK_ADDRESS(NEL_PFNGLGETVARIANTARRAYOBJECTFVATIPROC, glGetVariantArrayObjectfvATI);
CHECK_ADDRESS(NEL_PFNGLGETVARIANTARRAYOBJECTIVATIPROC, glGetVariantArrayObjectivATI);
}
#endif
return true;
}
@ -1000,8 +1135,12 @@ static bool setupATIMapObjectBuffer(const char *glext)
{
H_AUTO_OGL(setupATIMapObjectBuffer);
CHECK_EXT("GL_ATI_map_object_buffer");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLMAPOBJECTBUFFERATIPROC, glMapObjectBufferATI);
CHECK_ADDRESS(NEL_PFNGLUNMAPOBJECTBUFFERATIPROC, glUnmapObjectBufferATI);
#endif
return true;
}
@ -1013,6 +1152,7 @@ static bool setupATIFragmentShader(const char *glext)
H_AUTO_OGL(setupATIFragmentShader);
CHECK_EXT("GL_ATI_fragment_shader");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLGENFRAGMENTSHADERSATIPROC, glGenFragmentShadersATI);
CHECK_ADDRESS(NEL_PFNGLBINDFRAGMENTSHADERATIPROC, glBindFragmentShaderATI);
CHECK_ADDRESS(NEL_PFNGLDELETEFRAGMENTSHADERATIPROC, glDeleteFragmentShaderATI);
@ -1027,6 +1167,7 @@ static bool setupATIFragmentShader(const char *glext)
CHECK_ADDRESS(NEL_PFNGLALPHAFRAGMENTOP2ATIPROC, glAlphaFragmentOp2ATI);
CHECK_ADDRESS(NEL_PFNGLALPHAFRAGMENTOP3ATIPROC, glAlphaFragmentOp3ATI);
CHECK_ADDRESS(NEL_PFNGLSETFRAGMENTSHADERCONSTANTATIPROC, glSetFragmentShaderConstantATI);
#endif
return true;
}
@ -1037,9 +1178,11 @@ static bool setupATIVertexAttribArrayObject(const char *glext)
H_AUTO_OGL(setupATIVertexAttribArrayObject);
CHECK_EXT("GL_ATI_vertex_attrib_array_object");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLVERTEXATTRIBARRAYOBJECTATIPROC, glVertexAttribArrayObjectATI);
CHECK_ADDRESS(NEL_PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC, glGetVertexAttribArrayObjectfvATI);
CHECK_ADDRESS(NEL_PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC, glGetVertexAttribArrayObjectivATI);
#endif
return true;
}
@ -1050,6 +1193,7 @@ static bool setupARBFragmentProgram(const char *glext)
H_AUTO_OGL(setupARBFragmentProgram);
CHECK_EXT("GL_ARB_fragment_program");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLPROGRAMSTRINGARBPROC, glProgramStringARB);
CHECK_ADDRESS(NEL_PFNGLBINDPROGRAMARBPROC, glBindProgramARB);
CHECK_ADDRESS(NEL_PFNGLDELETEPROGRAMSARBPROC, glDeleteProgramsARB);
@ -1069,6 +1213,7 @@ static bool setupARBFragmentProgram(const char *glext)
CHECK_ADDRESS(NEL_PFNGLGETPROGRAMIVARBPROC, glGetProgramivARB);
CHECK_ADDRESS(NEL_PFNGLGETPROGRAMSTRINGARBPROC, glGetProgramStringARB);
CHECK_ADDRESS(NEL_PFNGLISPROGRAMARBPROC, glIsProgramARB);
#endif
return true;
}
@ -1077,6 +1222,8 @@ static bool setupARBFragmentProgram(const char *glext)
static bool setupARBVertexBufferObject(const char *glext)
{
H_AUTO_OGL(setupARBVertexBufferObject);
#ifndef USE_OPENGLES
CHECK_EXT("GL_ARB_vertex_buffer_object");
CHECK_ADDRESS(PFNGLBINDBUFFERARBPROC, glBindBufferARB);
@ -1090,6 +1237,7 @@ static bool setupARBVertexBufferObject(const char *glext)
CHECK_ADDRESS(PFNGLUNMAPBUFFERARBPROC, glUnmapBufferARB);
CHECK_ADDRESS(PFNGLGETBUFFERPARAMETERIVARBPROC, glGetBufferParameterivARB);
CHECK_ADDRESS(PFNGLGETBUFFERPOINTERVARBPROC, glGetBufferPointervARB);
#endif
return true;
}
@ -1100,6 +1248,7 @@ static bool setupARBVertexProgram(const char *glext)
H_AUTO_OGL(setupARBVertexProgram);
CHECK_EXT("GL_ARB_vertex_program");
#ifndef USE_OPENGLES
CHECK_ADDRESS(PFNGLVERTEXATTRIB1SARBPROC, glVertexAttrib1sARB);
CHECK_ADDRESS(PFNGLVERTEXATTRIB1FARBPROC, glVertexAttrib1fARB);
CHECK_ADDRESS(PFNGLVERTEXATTRIB1DARBPROC, glVertexAttrib1dARB);
@ -1162,6 +1311,7 @@ static bool setupARBVertexProgram(const char *glext)
CHECK_ADDRESS(PFNGLGETVERTEXATTRIBIVARBPROC, glGetVertexAttribivARB);
CHECK_ADDRESS(PFNGLGETVERTEXATTRIBPOINTERVARBPROC, glGetVertexAttribPointervARB);
CHECK_ADDRESS(PFNGLISPROGRAMARBPROC, glIsProgramARB);
#endif
return true;
}
@ -1172,6 +1322,7 @@ static bool setupNVOcclusionQuery(const char *glext)
H_AUTO_OGL(setupNVOcclusionQuery);
CHECK_EXT("GL_NV_occlusion_query");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLGENOCCLUSIONQUERIESNVPROC, glGenOcclusionQueriesNV);
CHECK_ADDRESS(NEL_PFNGLDELETEOCCLUSIONQUERIESNVPROC, glDeleteOcclusionQueriesNV);
CHECK_ADDRESS(NEL_PFNGLISOCCLUSIONQUERYNVPROC, glIsOcclusionQueryNV);
@ -1179,6 +1330,7 @@ static bool setupNVOcclusionQuery(const char *glext)
CHECK_ADDRESS(NEL_PFNGLENDOCCLUSIONQUERYNVPROC, glEndOcclusionQueryNV);
CHECK_ADDRESS(NEL_PFNGLGETOCCLUSIONQUERYIVNVPROC, glGetOcclusionQueryivNV);
CHECK_ADDRESS(NEL_PFNGLGETOCCLUSIONQUERYUIVNVPROC, glGetOcclusionQueryuivNV);
#endif
return true;
}
@ -1204,7 +1356,11 @@ static bool setupEXTTextureRectangle(const char *glext)
static bool setupARBTextureRectangle(const char *glext)
{
H_AUTO_OGL(setupARBTextureRectangle);
#ifndef USE_OPENGLES
CHECK_EXT("GL_ARB_texture_rectangle");
#endif
return true;
}
@ -1220,6 +1376,26 @@ static bool setupEXTTextureFilterAnisotropic(const char *glext)
static bool setupFrameBufferObject(const char *glext)
{
H_AUTO_OGL(setupFrameBufferObject);
#ifdef USE_OPENGLES
CHECK_EXT("GL_OES_framebuffer_object");
CHECK_ADDRESS(NEL_PFNGLISRENDERBUFFEROESPROC, glIsRenderbufferOES);
CHECK_ADDRESS(NEL_PFNGLBINDRENDERBUFFEROESPROC, glBindRenderbufferOES);
CHECK_ADDRESS(NEL_PFNGLDELETERENDERBUFFERSOESPROC, glDeleteRenderbuffersOES);
CHECK_ADDRESS(NEL_PFNGLGENRENDERBUFFERSOESPROC, glGenRenderbuffersOES);
CHECK_ADDRESS(NEL_PFNGLRENDERBUFFERSTORAGEOESPROC, glRenderbufferStorageOES);
CHECK_ADDRESS(NEL_PFNGLGETRENDERBUFFERPARAMETERIVOESPROC, glGetRenderbufferParameterivOES);
CHECK_ADDRESS(NEL_PFNGLISFRAMEBUFFEROESPROC, glIsFramebufferOES);
CHECK_ADDRESS(NEL_PFNGLBINDFRAMEBUFFEROESPROC, glBindFramebufferOES);
CHECK_ADDRESS(NEL_PFNGLDELETEFRAMEBUFFERSOESPROC, glDeleteFramebuffersOES);
CHECK_ADDRESS(NEL_PFNGLGENFRAMEBUFFERSOESPROC, glGenFramebuffersOES);
CHECK_ADDRESS(NEL_PFNGLCHECKFRAMEBUFFERSTATUSOESPROC, glCheckFramebufferStatusOES);
CHECK_ADDRESS(NEL_PFNGLFRAMEBUFFERRENDERBUFFEROESPROC, glFramebufferRenderbufferOES);
CHECK_ADDRESS(NEL_PFNGLFRAMEBUFFERTEXTURE2DOESPROC, glFramebufferTexture2DOES);
CHECK_ADDRESS(NEL_PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC, glGetFramebufferAttachmentParameterivOES);
CHECK_ADDRESS(NEL_PFNGLGENERATEMIPMAPOESPROC, glGenerateMipmapOES);
#else
CHECK_EXT("GL_EXT_framebuffer_object");
CHECK_ADDRESS(NEL_PFNGLISRENDERBUFFEREXTPROC, glIsRenderbufferEXT);
@ -1236,6 +1412,7 @@ static bool setupFrameBufferObject(const char *glext)
CHECK_ADDRESS(NEL_PFNGLDELETEFRAMEBUFFERSEXTPROC, glDeleteFramebuffersEXT);
CHECK_ADDRESS(NEL_PFNGETRENDERBUFFERPARAMETERIVEXTPROC, glGetRenderbufferParameterivEXT);
CHECK_ADDRESS(NEL_PFNGENERATEMIPMAPEXTPROC, glGenerateMipmapEXT);
#endif
return true;
}
@ -1246,7 +1423,9 @@ static bool setupFrameBufferBlit(const char *glext)
H_AUTO_OGL(setupFrameBufferBlit);
CHECK_EXT("GL_EXT_framebuffer_blit");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLBLITFRAMEBUFFEREXTPROC, glBlitFramebufferEXT);
#endif
return true;
}
@ -1257,7 +1436,9 @@ static bool setupFrameBufferMultisample(const char *glext)
H_AUTO_OGL(setupFrameBufferMultisample);
CHECK_EXT("GL_EXT_framebuffer_multisample");
#ifndef USE_OPENGLES
CHECK_ADDRESS(NEL_PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC, glRenderbufferStorageMultisampleEXT);
#endif
return true;
}
@ -1266,7 +1447,13 @@ static bool setupFrameBufferMultisample(const char *glext)
static bool setupPackedDepthStencil(const char *glext)
{
H_AUTO_OGL(setupPackedDepthStencil);
#ifdef USE_OPENGLES
CHECK_EXT("GL_OES_packed_depth_stencil");
#else
CHECK_EXT("GL_EXT_packed_depth_stencil");
#endif
return true;
}
@ -1305,7 +1492,11 @@ void registerGlExtensions(CGlExtensions &ext)
ext.ARBMultiTexture= setupARBMultiTexture(glext);
if(ext.ARBMultiTexture)
{
#ifdef USE_OPENGLES
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &ntext);
#else
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &ntext);
#endif
// We could have more than IDRV_MAT_MAXTEXTURES but the interface only
// support IDRV_MAT_MAXTEXTURES texture stages so take min
ext.NbTextureStages= (ntext<((GLint)IDRV_MAT_MAXTEXTURES)?ntext:IDRV_MAT_MAXTEXTURES);
@ -1330,8 +1521,10 @@ void registerGlExtensions(CGlExtensions &ext)
if(ext.NVVertexArrayRange)
{
GLint nverts;
GLint nverts = 10;
#ifndef USE_OPENGLES
glGetIntegerv((GLenum)GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV, &nverts);
#endif
ext.NVVertexArrayRangeMaxVertex= nverts;
}
@ -1365,6 +1558,9 @@ void registerGlExtensions(CGlExtensions &ext)
ext.ARBVertexProgram = false;
}
ext.OESDrawTexture = setupOESDrawTexture(glext);
ext.OESMapBuffer = setupOESMapBuffer(glext);
// Check texture shaders
// Disable feature ???
if(!ext.DisableHardwareTextureShader)
@ -1395,6 +1591,7 @@ void registerGlExtensions(CGlExtensions &ext)
// Check NVVertexArrayRange2
ext.NVVertexArrayRange2= setupNVVertexArrayRange2(glext);
#ifdef GL_NV_vertex_array_range2
// if supported
if(ext.NVVertexArrayRange2)
// VBHard swap without flush of the VAR.
@ -1402,6 +1599,7 @@ void registerGlExtensions(CGlExtensions &ext)
else
// VBHard with useless flush of the VAR.
ext.NVStateVARWithoutFlush= GL_VERTEX_ARRAY_RANGE_NV;
#endif
// Check NV_occlusion_query
ext.NVOcclusionQuery = setupNVOcclusionQuery(glext);
@ -1476,9 +1674,11 @@ static bool setupWGLEXTSwapControl(const char *glext)
H_AUTO_OGL(setupWGLEXTSwapControl);
CHECK_EXT("WGL_EXT_swap_control");
#ifndef USE_OPENGLES
#ifdef NL_OS_WINDOWS
CHECK_ADDRESS(PFNWGLSWAPINTERVALEXTPROC, wglSwapIntervalEXT);
CHECK_ADDRESS(PFNWGLGETSWAPINTERVALEXTPROC, wglGetSwapIntervalEXT);
#endif
#endif
return true;
@ -1524,11 +1724,43 @@ static bool setupGLXMESASwapControl(const char *glext)
return true;
}
#ifdef NL_OS_WINDOWS
#ifdef USE_OPENGLES
// ***************************************************************************
bool registerWGlExtensions(CGlExtensions &ext, HDC hDC)
bool registerEGlExtensions(CGlExtensions &ext, EGLDisplay dpy)
{
H_AUTO_OGL(registerEGlExtensions);
// Get extension string
const char *glext = eglQueryString(dpy, EGL_EXTENSIONS);
if (glext == NULL)
{
nlwarning ("neglGetExtensionsStringARB failed");
return false;
}
nldebug("3D: Available EGL Extensions:");
if (DebugLog)
{
vector<string> exts;
explode(string(glext), string(" "), exts);
for(uint i = 0; i < exts.size(); i++)
{
if(i%5==0) DebugLog->displayRaw("3D: ");
DebugLog->displayRaw(string(exts[i]+" ").c_str());
if(i%5==4) DebugLog->displayRaw("\n");
}
DebugLog->displayRaw("\n");
}
return true;
}
#elif defined(NL_OS_WINDOWS)
// ***************************************************************************
bool registerWGlExtensions(CGlExtensions &ext, HDC hDC)
{
H_AUTO_OGL(registerWGlExtensions);
// Get proc address
CHECK_ADDRESS(PFNWGLGETEXTENSIONSSTRINGARBPROC, wglGetExtensionsStringARB);
@ -1569,7 +1801,7 @@ bool registerWGlExtensions(CGlExtensions &ext, HDC hDC)
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
// ***************************************************************************
bool registerGlXExtensions(CGlExtensions &ext, Display *dpy, sint screen)
bool registerGlXExtensions(CGlExtensions &ext, Display *dpy, sint screen)
{
H_AUTO_OGL(registerGlXExtensions);
@ -1609,6 +1841,6 @@ bool registerGlXExtensions(CGlExtensions &ext, Display *dpy, sint screen)
return true;
}
#endif // NL_OS_WINDOWS
#endif // USE_OPENGLES
}

View file

@ -21,31 +21,6 @@
#include "nel/misc/types_nl.h"
#include "nel/misc/string_common.h"
#ifdef NL_OS_WINDOWS
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include <windows.h>
# include <GL/gl.h>
# include <GL/glext.h> // Please download it from http://www.opengl.org/registry/
#elif defined(NL_OS_MAC)
# define GL_GLEXT_LEGACY
# include <OpenGL/gl.h>
# include "mac/glext.h"
#elif defined (NL_OS_UNIX)
# include <GL/gl.h>
# include <GL/glext.h> // Please download it from http://www.opengl.org/registry/
# include <GL/glx.h>
# include <GL/glxext.h>
#endif // NL_OS_UNIX
#ifndef GL_GLEXT_VERSION
# error "I need a newer <GL/glext.h>. Please download it from http://www.opengl.org/registry/"
#endif // GL_nGLEXT_VERSION
#if GL_GLEXT_VERSION < 7
# error "I need a newer <GL/glext.h>. Please download it from http://www.opengl.org/registry/"
#endif // GL_nGLEXT_VERSION < 7
#include "driver_opengl_extension_def.h"
namespace NL3D
@ -121,6 +96,9 @@ struct CGlExtensions
bool ARBTextureNonPowerOfTwo;
bool ARBMultisample;
bool OESDrawTexture;
bool OESMapBuffer;
public:
/// \name Disable Hardware feature. False by default. setuped by IDriver
@ -174,7 +152,11 @@ public:
EXTTextureFilterAnisotropic = false;
EXTTextureFilterAnisotropicMaximum = 1.f;
ARBTextureRectangle = false;
#ifdef USE_OPENGLES
ARBTextureNonPowerOfTwo = true;
#else
ARBTextureNonPowerOfTwo = false;
#endif
ARBMultisample = false;
NVOcclusionQuery = false;
FrameBufferObject = false;
@ -184,6 +166,9 @@ public:
NVVertexArrayRange2 = false;
NVStateVARWithoutFlush = 0;
OESDrawTexture = false;
OESMapBuffer = false;
/// \name Disable Hardware feature. False by default. setuped by IDriver
DisableHardwareVertexProgram= false;
DisableHardwareVertexArrayAGP= false;
@ -266,7 +251,10 @@ public:
// ***************************************************************************
#ifdef NL_OS_WINDOWS
#ifdef USE_OPENGLES
/// This function will test and register EGL functions before than the gl context is created
bool registerEGlExtensions(CGlExtensions &ext, EGLDisplay dpy);
#elif defined(NL_OS_WINDOWS)
/// This function will test and register WGL functions before than the gl context is created
bool registerWGlExtensions(CGlExtensions &ext, HDC hDC);
#elif defined(NL_OS_MAC)
@ -289,6 +277,48 @@ void registerGlExtensions(CGlExtensions &ext);
NB: we do it for all (EXT, NV, ARB extension) even it should be useful only for ARB ones.
*/
#ifdef USE_OPENGLES
// OES_mapbuffer.
//===============
extern NEL_PFNGLMAPBUFFEROESPROC nglMapBufferOES;
extern NEL_PFNGLUNMAPBUFFEROESPROC nglUnmapBufferOES;
extern NEL_PFNGLGETBUFFERPOINTERVOESPROC nglGetBufferPointervOES;
extern NEL_PFNGLBUFFERSUBDATAPROC nglBufferSubData;
extern PFNGLDRAWTEXFOESPROC nglDrawTexfOES;
// GL_OES_framebuffer_object
extern NEL_PFNGLISRENDERBUFFEROESPROC nglIsRenderbufferOES;
extern NEL_PFNGLBINDRENDERBUFFEROESPROC nglBindRenderbufferOES;
extern NEL_PFNGLDELETERENDERBUFFERSOESPROC nglDeleteRenderbuffersOES;
extern NEL_PFNGLGENRENDERBUFFERSOESPROC nglGenRenderbuffersOES;
extern NEL_PFNGLRENDERBUFFERSTORAGEOESPROC nglRenderbufferStorageOES;
extern NEL_PFNGLGETRENDERBUFFERPARAMETERIVOESPROC nglGetRenderbufferParameterivOES;
extern NEL_PFNGLISFRAMEBUFFEROESPROC nglIsFramebufferOES;
extern NEL_PFNGLBINDFRAMEBUFFEROESPROC nglBindFramebufferOES;
extern NEL_PFNGLDELETEFRAMEBUFFERSOESPROC nglDeleteFramebuffersOES;
extern NEL_PFNGLGENFRAMEBUFFERSOESPROC nglGenFramebuffersOES;
extern NEL_PFNGLCHECKFRAMEBUFFERSTATUSOESPROC nglCheckFramebufferStatusOES;
extern NEL_PFNGLFRAMEBUFFERRENDERBUFFEROESPROC nglFramebufferRenderbufferOES;
extern NEL_PFNGLFRAMEBUFFERTEXTURE2DOESPROC nglFramebufferTexture2DOES;
extern NEL_PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC nglGetFramebufferAttachmentParameterivOES;
extern NEL_PFNGLGENERATEMIPMAPOESPROC nglGenerateMipmapOES;
// GL_OES_texture_cube_map
extern NEL_PFNGLTEXGENFOESPROC nglTexGenfOES;
extern NEL_PFNGLTEXGENFVOESPROC nglTexGenfvOES;
extern NEL_PFNGLTEXGENIOESPROC nglTexGeniOES;
extern NEL_PFNGLTEXGENIVOESPROC nglTexGenivOES;
extern NEL_PFNGLTEXGENXOESPROC nglTexGenxOES;
extern NEL_PFNGLTEXGENXVOESPROC nglTexGenxvOES;
extern NEL_PFNGLGETTEXGENFVOESPROC nglGetTexGenfvOES;
extern NEL_PFNGLGETTEXGENIVOESPROC nglGetTexGenivOES;
extern NEL_PFNGLGETTEXGENXVOESPROC nglGetTexGenxvOES;
#else
// ARB_multitexture
//=================
extern NEL_PFNGLACTIVETEXTUREARBPROC nglActiveTextureARB;
@ -741,4 +771,6 @@ extern NEL_PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC nglRenderbufferStorageMul
// GL_ARB_multisample
extern NEL_PFNGLSAMPLECOVERAGEARBPROC nglSampleCoverageARB;
#endif // USE_OPENGLES
#endif // NL_OPENGL_EXTENSION_H

View file

@ -20,23 +20,6 @@
#include "nel/misc/types_nl.h"
#ifdef USE_OPENGLES
# include <GLES/gl.h>
# include <GLES/glext.h>
#else
# ifdef NL_OS_MAC
# define GL_GLEXT_LEGACY
# include <OpenGL/gl.h>
# include "mac/glext.h"
# else
# include <GL/gl.h>
# include <GL/glext.h>
# if defined(NL_OS_WINDOWS)
# include <GL/wglext.h>
# endif
# endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -79,7 +62,8 @@ typedef void (APIENTRY * NEL_PFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname,
typedef void (APIENTRY * NEL_PFNGLGETTEXGENFVOESPROC) (GLenum coord, GLenum pname, GLfloat *params);
typedef void (APIENTRY * NEL_PFNGLGETTEXGENIVOESPROC) (GLenum coord, GLenum pname, GLint *params);
typedef void (APIENTRY * NEL_PFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed *params);
#endif
#else
// ***************************************************************************
// ***************************************************************************
@ -456,6 +440,8 @@ typedef void (APIENTRY * NEL_PFNGLXFREEMEMORYNVPROC) (void *pointer);
#endif // NL_OS_MAC
#endif // USE_OPENGLES
#ifdef __cplusplus
}
#endif

View file

@ -17,11 +17,7 @@
#include "stdopengl.h"
#include "driver_opengl.h"
#ifdef NL_OS_WINDOWS
# include <windowsx.h>
#elif defined(NL_OS_MAC)
#elif defined (NL_OS_UNIX)
# include <GL/glx.h>
#ifdef NL_OS_UNIX
# include <X11/Xatom.h>
# ifdef HAVE_XRENDER
# include <X11/extensions/Xrender.h>

View file

@ -35,12 +35,7 @@ static void convBlend(CMaterial::TBlend blend, GLenum& glenum)
case CMaterial::srccolor: glenum=GL_SRC_COLOR; break;
case CMaterial::invsrccolor:glenum=GL_ONE_MINUS_SRC_COLOR; break;
// Extended Blend modes.
#ifdef USE_OPENGLES
case CMaterial::blendConstantColor: glenum=GL_CONSTANT_COLOR; break;
case CMaterial::blendConstantInvColor: glenum=GL_ONE_MINUS_CONSTANT_COLOR; break;
case CMaterial::blendConstantAlpha: glenum=GL_CONSTANT_ALPHA; break;
case CMaterial::blendConstantInvAlpha: glenum=GL_ONE_MINUS_CONSTANT_ALPHA; break;
#else
#ifndef USE_OPENGLES
case CMaterial::blendConstantColor: glenum=GL_CONSTANT_COLOR_EXT; break;
case CMaterial::blendConstantInvColor: glenum=GL_ONE_MINUS_CONSTANT_COLOR_EXT; break;
case CMaterial::blendConstantAlpha: glenum=GL_CONSTANT_ALPHA_EXT; break;
@ -84,22 +79,30 @@ static inline void convTexAddr(ITexture *tex, CMaterial::TTexAddressingMode mode
nlassert(mode < CMaterial::TexAddrCount);
static const GLenum glTex2dAddrModesNV[] =
{
#ifdef USE_OPENGLES
0, GL_TEXTURE_2D
#else
GL_NONE, GL_TEXTURE_2D, GL_PASS_THROUGH_NV, GL_CULL_FRAGMENT_NV,
GL_OFFSET_TEXTURE_2D_NV, GL_OFFSET_TEXTURE_2D_SCALE_NV,
GL_DEPENDENT_AR_TEXTURE_2D_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV,
GL_DOT_PRODUCT_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV,
GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV,
GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV, GL_DOT_PRODUCT_DEPTH_REPLACE_NV
#endif
};
static const GLenum glTexCubeAddrModesNV[] =
{
#ifdef USE_OPENGLES
0, GL_TEXTURE_CUBE_MAP_OES
#else
GL_NONE, GL_TEXTURE_CUBE_MAP_ARB, GL_PASS_THROUGH_NV, GL_CULL_FRAGMENT_NV,
GL_OFFSET_TEXTURE_2D_NV, GL_OFFSET_TEXTURE_2D_SCALE_NV,
GL_DEPENDENT_AR_TEXTURE_2D_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV,
GL_DOT_PRODUCT_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV,
GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV,
GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV, GL_DOT_PRODUCT_DEPTH_REPLACE_NV
#endif
};
if (!tex || !tex->isTextureCube())
@ -136,17 +139,33 @@ void CDriverGL::setTextureEnvFunction(uint stage, CMaterial& mat)
{
// Cubic or normal ?
if (text->isTextureCube ())
#ifdef USE_OPENGLES
_DriverGLStates.setTexGenMode (stage, GL_REFLECTION_MAP_OES);
#else
_DriverGLStates.setTexGenMode (stage, GL_REFLECTION_MAP_ARB);
#endif
else
#ifdef USE_OPENGLES
_DriverGLStates.setTexGenMode (stage, GL_TEXTURE_CUBE_MAP_OES);
#else
_DriverGLStates.setTexGenMode (stage, GL_SPHERE_MAP);
#endif
}
else if(mode==CMaterial::TexCoordGenObjectSpace)
{
#ifdef USE_OPENGLES
_DriverGLStates.setTexGenMode (stage, GL_NORMAL_MAP_OES);
#else
_DriverGLStates.setTexGenMode (stage, GL_OBJECT_LINEAR);
#endif
}
else if(mode==CMaterial::TexCoordGenEyeSpace)
{
#ifdef USE_OPENGLES
_DriverGLStates.setTexGenMode (stage, GL_NORMAL_MAP_OES);
#else
_DriverGLStates.setTexGenMode (stage, GL_EYE_LINEAR);
#endif
}
}
else
@ -850,6 +869,22 @@ void CDriverGL::setupLightMapPass(uint pass)
// TexEnv is special.
_CurrentTexEnvSpecial[stage] = TexEnvSpecialLightMap;
#ifdef USE_OPENGLES
// What we want to setup is Texture*Constant + Previous.
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
// Operator.
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
// Arg0.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
// Arg1.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
// Arg2.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
#else
if (_Extensions.NVTextureEnvCombine4)
{
// What we want to setup is Texture*Constant + Previous*1.
@ -889,6 +924,7 @@ void CDriverGL::setupLightMapPass(uint pass)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
}
#endif
}
}
@ -1196,6 +1232,58 @@ void CDriverGL::setupSpecularPass(uint pass)
return;
}
#ifdef USE_OPENGLES
#if 0
// Ok we can do it in a single pass
// Set Stage 1
// Special: not the same special env if there is or not texture in stage 0.
CTexEnvSpecial newEnvStage1;
if( mat.getTexture(0) == NULL )
newEnvStage1= TexEnvSpecialSpecularStage1NoText;
else
newEnvStage1= TexEnvSpecialSpecularStage1;
// Test if same env as prec.
if(_CurrentTexEnvSpecial[1] != newEnvStage1)
{
// TexEnv is special.
_CurrentTexEnvSpecial[1] = newEnvStage1;
_DriverGLStates.activeTextureARB(1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
// Operator Add (Arg0*Arg2+Arg1)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
// Arg0.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
// Arg2.
if( newEnvStage1 == TexEnvSpecialSpecularStage1NoText)
{
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_ZERO);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_COLOR);
}
else
{
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
}
// Arg1.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
// Result : Texture*Previous.Alpha+Previous
// Setup Alpha Diffuse Copy
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
// Arg2.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, GL_ZERO);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Arg1.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_ZERO );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
}
#endif
#else
/// Support NVidia combine 4 extension to do specular map in a single pass
if( _Extensions.NVTextureEnvCombine4 )
{ // Ok we can do it in a single pass
@ -1258,7 +1346,7 @@ void CDriverGL::setupSpecularPass(uint pass)
// Ok we can do it in a single pass
// Set Stage 1
// Special: not the same sepcial env if there is or not texture in stage 0.
// Special: not the same special env if there is or not texture in stage 0.
CTexEnvSpecial newEnvStage1;
if( mat.getTexture(0) == NULL )
newEnvStage1= TexEnvSpecialSpecularStage1NoText;
@ -1305,6 +1393,7 @@ void CDriverGL::setupSpecularPass(uint pass)
}
}
else
#endif
{
// We have to do it in 2 passes
// For Both Pass, setup correct Env.
@ -1542,6 +1631,20 @@ void CDriverGL::setupPPLPass(uint pass)
_CurrentTexEnvSpecial[0] = TexEnvSpecialPPLStage0;
_DriverGLStates.activeTextureARB(0);
#ifdef USE_OPENGLES
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
// Arg0 = Diffuse read in cube map
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
// Arg1 = Light color
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
// Arg2 = Primary color (other light diffuse and
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
#else
if (_Extensions.NVTextureEnvCombine4)
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
@ -1575,6 +1678,7 @@ void CDriverGL::setupPPLPass(uint pass)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
}
#endif
}
activateTexEnvColor(0, _PPLightDiffuseColor);
@ -1592,6 +1696,32 @@ void CDriverGL::setupPPLPass(uint pass)
_CurrentTexEnvSpecial[2] = TexEnvSpecialPPLStage2;
_DriverGLStates.activeTextureARB(2);
#ifdef USE_OPENGLES
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
//== colors ==
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
// Arg0 = Specular read in cube map
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
// Arg2 = Light color
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
// Arg1 = Primary color ( + other light diffuse)
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
//== alpha ==
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
// Arg0 = PREVIOUS ALPHA
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_COLOR);
// Arg2 = 1
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, GL_ZERO);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_ONE_MINUS_SRC_COLOR);
// Arg1 = 0
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_ZERO);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_COLOR);
#else
if (_Extensions.NVTextureEnvCombine4)
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
@ -1652,6 +1782,7 @@ void CDriverGL::setupPPLPass(uint pass)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_ZERO);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_COLOR);
}
#endif
}
activateTexEnvColor(2, _PPLightSpecularColor);
@ -1707,6 +1838,20 @@ void CDriverGL::setupPPLNoSpecPass(uint pass)
_CurrentTexEnvSpecial[0] = TexEnvSpecialPPLStage0;
_DriverGLStates.activeTextureARB(0);
#ifdef USE_OPENGLES
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
// Arg0 = Diffuse read in cube map alpha
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
// Arg2 = Light color
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
// Arg1 = Primary color (other light diffuse and
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
#else
if (_Extensions.NVTextureEnvCombine4)
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
@ -1740,6 +1885,7 @@ void CDriverGL::setupPPLNoSpecPass(uint pass)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
}
#endif
}
activateTexEnvColor(0, _PPLightDiffuseColor);
@ -1852,6 +1998,7 @@ void CDriverGL::setupCloudPass (uint /* pass */)
if (_CurrentTexEnvSpecial[0] != TexEnvSpecialCloudStage0)
{
#ifndef USE_OPENGLES
if (_Extensions.NVTextureEnvCombine4)
{
_CurrentTexEnvSpecial[0] = TexEnvSpecialCloudStage0;
@ -1969,6 +2116,7 @@ void CDriverGL::setupCloudPass (uint /* pass */)
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
*/
}
#endif
}
if (_Extensions.NVTextureEnvCombine4)
activateTexEnvColor (1, mat.getColor());

View file

@ -642,6 +642,8 @@ void CDriverGLStates::setTexGenMode (uint stage, GLint mode)
{
_TexGenMode[stage] = mode;
if (!_TextureCubeMapSupported) return;
if(mode==0)
{
#ifdef USE_OPENGLES
@ -655,15 +657,31 @@ void CDriverGLStates::setTexGenMode (uint stage, GLint mode)
}
else
{
#ifdef USE_OPENGLES
// nglTexGeniOES(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE_OES, mode);
#else
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, mode);
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, mode);
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, mode);
#endif
/* Object or Eye Space ? => enable W generation. VERY IMPORTANT because
was a bug with VegetableRender and ShadowRender:
- Vegetable use the TexCoord1.w in his VertexProgram
- Shadow Render don't use any TexCoord in VB (since projected)
=> TexCoord1.w dirty!!
*/
#ifdef USE_OPENGLES
// if(mode==GL_OBJECT_LINEAR || mode==GL_EYE_LINEAR)
// {
nglTexGeniOES(GL_TEXTURE_GEN_STR_OES, GL_TEXTURE_GEN_MODE_OES, mode);
glEnable(GL_TEXTURE_GEN_STR_OES);
// }
// else
// {
// glDisable(GL_TEXTURE_GEN_STR_OES);
// }
#else
if(mode==GL_OBJECT_LINEAR || mode==GL_EYE_LINEAR)
{
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, mode);
@ -673,6 +691,7 @@ void CDriverGLStates::setTexGenMode (uint stage, GLint mode)
{
glDisable( GL_TEXTURE_GEN_Q );
}
#endif
// Enable All.
#ifdef USE_OPENGLES
@ -994,6 +1013,7 @@ void CDriverGLStates::enableVertexAttribArrayARB(uint glIndex,bool enable)
void CDriverGLStates::enableVertexAttribArrayForEXTVertexShader(uint glIndex, bool enable, uint *variants)
{
H_AUTO_OGL(CDriverGLStates_enableVertexAttribArrayForEXTVertexShader)
if(_VertexAttribArrayEnabled[glIndex] != enable)
{
switch(glIndex)
@ -1002,10 +1022,12 @@ void CDriverGLStates::enableVertexAttribArrayForEXTVertexShader(uint glIndex, bo
enableVertexArray(enable);
break;
case 1: // skin weight
#ifndef USE_OPENGLES
if(enable)
nglEnableVariantClientStateEXT(variants[CDriverGL::EVSSkinWeightVariant]);
else
nglDisableVariantClientStateEXT(variants[CDriverGL::EVSSkinWeightVariant]);
#endif
break;
case 2: // normal
enableNormalArray(enable);
@ -1014,22 +1036,28 @@ void CDriverGLStates::enableVertexAttribArrayForEXTVertexShader(uint glIndex, bo
enableColorArray(enable);
break;
case 4: // secondary color
#ifndef USE_OPENGLES
if(enable)
nglEnableVariantClientStateEXT(variants[CDriverGL::EVSSecondaryColorVariant]);
else
nglDisableVariantClientStateEXT(variants[CDriverGL::EVSSecondaryColorVariant]);
#endif
break;
case 5: // fog coordinate
#ifndef USE_OPENGLES
if(enable)
nglEnableVariantClientStateEXT(variants[CDriverGL::EVSFogCoordsVariant]);
else
nglDisableVariantClientStateEXT(variants[CDriverGL::EVSFogCoordsVariant]);
#endif
break;
case 6: // palette skin
#ifndef USE_OPENGLES
if(enable)
nglEnableVariantClientStateEXT(variants[CDriverGL::EVSPaletteSkinVariant]);
else
nglDisableVariantClientStateEXT(variants[CDriverGL::EVSPaletteSkinVariant]);
#endif
break;
case 7: // empty
nlstop;
@ -1051,8 +1079,6 @@ void CDriverGLStates::enableVertexAttribArrayForEXTVertexShader(uint glIndex, bo
}
_VertexAttribArrayEnabled[glIndex]= enable;
}
}

View file

@ -20,18 +20,6 @@
#include "nel/misc/types_nl.h"
#include "nel/3d/vertex_buffer.h"
#ifdef USE_OPENGLES
# include <GLES/gl.h>
#else
# ifdef NL_OS_MAC
# define GL_GLEXT_LEGACY
# include <OpenGL/gl.h>
# else
# include <GL/gl.h>
# endif
#endif
namespace NL3D
{

View file

@ -60,7 +60,11 @@ CTextureDrvInfosGL::CTextureDrvInfosGL(IDriver *drv, ItTexDrvInfoPtrMap it, CDri
// Nb: at Driver dtor, all tex infos are deleted, so _Driver is always valid.
_Driver= drvGl;
#ifdef USE_OPENGLES
TextureMode = GL_TEXTURE_2D;
#else
TextureMode = isRectangleTexture?GL_TEXTURE_RECTANGLE_NV:GL_TEXTURE_2D;
#endif
FBOId = 0;
DepthFBOId = 0;
@ -85,6 +89,15 @@ CTextureDrvInfosGL::~CTextureDrvInfosGL()
if(InitFBO)
{
#ifdef USE_OPENGLES
nglDeleteFramebuffersOES(1, &FBOId);
if(AttachDepthStencil)
{
nglDeleteRenderbuffersOES(1, &DepthFBOId);
if(!UsePackedDepthStencil)
nglDeleteRenderbuffersOES(1, &StencilFBOId);
}
#else
nglDeleteFramebuffersEXT(1, &FBOId);
if(AttachDepthStencil)
{
@ -92,6 +105,7 @@ CTextureDrvInfosGL::~CTextureDrvInfosGL()
if(!UsePackedDepthStencil)
nglDeleteRenderbuffersEXT(1, &StencilFBOId);
}
#endif
}
}
@ -104,6 +118,54 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
{
AttachDepthStencil = !((CTextureBloom*)tex)->isMode2D();
}
#ifdef USE_OPENGLES
// generate IDs
nglGenFramebuffersOES(1, &FBOId);
if(AttachDepthStencil)
{
nglGenRenderbuffersOES(1, &DepthFBOId);
if(UsePackedDepthStencil)
StencilFBOId = DepthFBOId;
else
nglGenRenderbuffersOES(1, &StencilFBOId);
}
//nldebug("3D: using depth %d and stencil %d", DepthFBOId, StencilFBOId);
// initialize FBO
nglBindFramebufferOES(GL_FRAMEBUFFER_OES, FBOId);
nglFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, TextureMode, ID, 0);
// attach depth/stencil render to FBO
// note: for some still unkown reason it's impossible to add
// a stencil buffer as shown in the respective docs (see
// opengl.org extension registry). Until a safe approach to add
// them is found, there will be no attached stencil for the time
// being, aside of using packed depth+stencil buffers.
if(AttachDepthStencil)
{
if(UsePackedDepthStencil)
{
//nldebug("3D: using packed depth stencil");
nglBindRenderbufferOES(GL_RENDERBUFFER_OES, StencilFBOId);
nglRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH24_STENCIL8_OES, tex->getWidth(), tex->getHeight());
}
else
{
nglBindRenderbufferOES(GL_RENDERBUFFER_OES, DepthFBOId);
nglRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT24_OES, tex->getWidth(), tex->getHeight());
/*
nglBindRenderbufferEXT(GL_RENDERBUFFER_OES, StencilFBOId);
nglRenderbufferStorageEXT(GL_RENDERBUFFER_OES, GL_STENCIL_INDEX8_EXT, tex->getWidth(), tex->getHeight());
*/
}
nglFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, DepthFBOId);
nldebug("3D: glFramebufferRenderbufferExt(depth:24) = %X", nglCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
nglFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, StencilFBOId);
nldebug("3D: glFramebufferRenderbufferExt(stencil:8) = %X", nglCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
}
#else
// generate IDs
nglGenFramebuffersEXT(1, &FBOId);
if(AttachDepthStencil)
@ -119,8 +181,7 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
// initialize FBO
nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBOId);
nglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
TextureMode, ID, 0);
nglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TextureMode, ID, 0);
// attach depth/stencil render to FBO
// note: for some still unkown reason it's impossible to add
@ -152,6 +213,7 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
GL_RENDERBUFFER_EXT, StencilFBOId);
nldebug("3D: glFramebufferRenderbufferExt(stencil:8) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
}
#endif
// check status
GLenum status;
@ -161,44 +223,95 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
status = (GLenum) nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
#endif
switch(status) {
#ifdef GL_FRAMEBUFFER_COMPLETE_EXT
case GL_FRAMEBUFFER_COMPLETE_EXT:
InitFBO = true;
break;
#endif
#ifdef GL_FRAMEBUFFER_COMPLETE_OES
case GL_FRAMEBUFFER_COMPLETE_OES:
InitFBO = true;
break;
#endif
#ifdef GL_FRAMEBUFFER_UNSUPPORTED_EXT
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
nlwarning("Unsupported framebuffer format");
break;
#endif
#ifdef GL_FRAMEBUFFER_UNSUPPORTED_OES
case GL_FRAMEBUFFER_UNSUPPORTED_OES:
nlwarning("Unsupported framebuffer format");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
nlwarning("Framebuffer incomplete attachment");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
nlwarning("Framebuffer incomplete attachment");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
nlwarning("Framebuffer incomplete, missing attachment");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
nlwarning("Framebuffer incomplete, missing attachment");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
nlwarning("Framebuffer incomplete, duplicate attachment");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
nlwarning("Framebuffer incomplete, attached images must have same dimensions");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
nlwarning("Framebuffer incomplete, attached images must have same dimensions");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
nlwarning("Framebuffer incomplete, attached images must have same format");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
nlwarning("Framebuffer incomplete, attached images must have same format");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
nlwarning("Framebuffer incomplete, missing draw buffer");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
nlwarning("Framebuffer incomplete, missing read buffer");
break;
#endif
#ifdef GL_FRAMEBUFFER_BINDING_EXT
case GL_FRAMEBUFFER_BINDING_EXT:
nlwarning("Framebuffer BINDING_EXT");
break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
nlwarning("Framebuffer incomplete multisample");
break;
#endif
#ifdef GL_FRAMEBUFFER_BINDING_OES
case GL_FRAMEBUFFER_BINDING_OES:
nlwarning("Framebuffer BINDING_EXT");
break;
#endif
default:
nlwarning("Framebuffer incomplete status %d", (sint)status);
@ -265,7 +378,7 @@ bool CTextureDrvInfosGL::activeFrameBufferObject(ITexture * tex)
// ***************************************************************************
// Get the glText mirror of an existing setuped texture.
static inline CTextureDrvInfosGL* getTextureGl(ITexture& tex)
static inline CTextureDrvInfosGL* getTextureGl(ITexture& tex)
{
H_AUTO_OGL(getTextureGl)
CTextureDrvInfosGL* gltex;
@ -310,10 +423,18 @@ GLint CDriverGL::getGlTextureFormat(ITexture& tex, bool &compressed)
// Try Compressed ones.
switch(texfmt)
{
#ifdef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
case ITexture::DXTC1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
case ITexture::DXTC1Alpha: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
case ITexture::DXTC3: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
case ITexture::DXTC5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
#endif
default: break;
}
}
@ -322,6 +443,16 @@ GLint CDriverGL::getGlTextureFormat(ITexture& tex, bool &compressed)
compressed= false;
switch(texfmt)
{
#ifdef USE_OPENGLES
case ITexture::RGBA8888: return GL_RGBA;
// case ITexture::RGBA4444: return GL_RGBA4_OES;
// case ITexture::RGBA5551: return GL_RGB5_A1_OES;
case ITexture::RGB888: return GL_RGB;
// case ITexture::RGB565: return GL_RGB5_OES;
case ITexture::Luminance: return GL_LUMINANCE;
case ITexture::Alpha: return GL_ALPHA;
case ITexture::AlphaLuminance: return GL_LUMINANCE_ALPHA;
#else
case ITexture::RGBA8888: return GL_RGBA8;
case ITexture::RGBA4444: return GL_RGBA4;
case ITexture::RGBA5551: return GL_RGB5_A1;
@ -342,8 +473,16 @@ GLint CDriverGL::getGlTextureFormat(ITexture& tex, bool &compressed)
return 0;
}
break;
default: return GL_RGBA8;
#endif
default:
break;
}
#ifdef USE_OPENGLES
return GL_RGBA;
#else
return GL_RGBA8;
#endif
}
// ***************************************************************************
@ -352,7 +491,11 @@ static GLint getGlSrcTextureFormat(ITexture &tex, GLint glfmt)
H_AUTO_OGL(getGlSrcTextureFormat)
// Is destination format is alpha or lumiance ?
#ifdef USE_OPENGLES
if ((glfmt==GL_ALPHA)||(glfmt==GL_LUMINANCE_ALPHA)||(glfmt==GL_LUMINANCE))
#else
if ((glfmt==GL_ALPHA8)||(glfmt==GL_LUMINANCE8_ALPHA8)||(glfmt==GL_LUMINANCE8))
#endif
{
switch(tex.getPixelFormat())
{
@ -363,6 +506,7 @@ static GLint getGlSrcTextureFormat(ITexture &tex, GLint glfmt)
}
}
#ifndef USE_OPENGLES
if (glfmt == GL_DSDT_NV)
{
return GL_DSDT_NV;
@ -372,6 +516,7 @@ static GLint getGlSrcTextureFormat(ITexture &tex, GLint glfmt)
{
return GL_DUDV_ATI;
}
#endif
// Else, not a Src format for upload, or RGBA.
return GL_RGBA;
@ -380,7 +525,9 @@ static GLint getGlSrcTextureFormat(ITexture &tex, GLint glfmt)
// ***************************************************************************
static GLenum getGlSrcTextureComponentType(GLint texSrcFormat)
{
H_AUTO_OGL(getGlSrcTextureComponentType)
H_AUTO_OGL(getGlSrcTextureComponentType);
#ifndef USE_OPENGLES
switch (texSrcFormat)
{
case GL_DSDT_NV:
@ -388,10 +535,11 @@ static GLenum getGlSrcTextureComponentType(GLint texSrcFormat)
return GL_BYTE; // these are signed format
break;
default:
return GL_UNSIGNED_BYTE;
break;
}
#endif
return GL_UNSIGNED_BYTE;
}
// ***************************************************************************
@ -400,22 +548,65 @@ uint CDriverGL::computeMipMapMemoryUsage(uint w, uint h, GLint glfmt) const
H_AUTO_OGL(CDriverGL_computeMipMapMemoryUsage)
switch(glfmt)
{
#ifdef GL_RGBA8
case GL_RGBA8: return w*h* 4;
#endif
#ifdef GL_RGBA
case GL_RGBA: return w*h* 4;
#endif
// Well this is ugly, but simple :). GeForce 888 is stored as 32 bits.
#ifdef GL_RGB8
case GL_RGB8: return w*h* 4;
#endif
#ifdef GL_RGB
case GL_RGB: return w*h* 4;
#endif
#ifdef GL_RGBA4
case GL_RGBA4: return w*h* 2;
#endif
#ifdef GL_RGB5_A1
case GL_RGB5_A1: return w*h* 2;
#endif
#ifdef GL_RGB5
case GL_RGB5: return w*h* 2;
#endif
#ifdef GL_LUMINANCE8
case GL_LUMINANCE8: return w*h* 1;
#endif
#ifdef GL_LUMINANCE
case GL_LUMINANCE: return w*h* 1;
#endif
#ifdef GL_ALPHA8
case GL_ALPHA8: return w*h* 1;
#endif
#ifdef GL_ALPHA
case GL_ALPHA: return w*h* 1;
#endif
#ifdef GL_LUMINANCE8_ALPHA8
case GL_LUMINANCE8_ALPHA8: return w*h* 2;
#endif
#ifdef GL_LUMINANCE_ALPHA
case GL_LUMINANCE_ALPHA: return w*h* 2;
#endif
#ifdef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return w*h /2;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return w*h /2;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return w*h* 1;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return w*h* 1;
#endif
#ifdef GL_DU8DV8_ATI
case GL_DU8DV8_ATI:
#endif
#ifdef GL_DSDT_NV
case GL_DSDT_NV: return w*h* 2;
};
#endif
}
// One format has not been coded.
nlstop;
@ -431,13 +622,15 @@ static inline GLenum translateWrapToGl(ITexture::TWrapMode mode, const CGlExtens
H_AUTO_OGL(translateWrapToGl)
if(mode== ITexture::Repeat)
return GL_REPEAT;
else
{
if(extensions.Version1_2)
return GL_CLAMP_TO_EDGE;
else
return GL_CLAMP;
}
#ifdef USE_OPENGLES
return GL_CLAMP_TO_EDGE;
#else
if(extensions.Version1_2)
return GL_CLAMP_TO_EDGE;
return GL_CLAMP;
#endif
}
// ***************************************************************************
@ -506,14 +699,26 @@ static inline GLenum translateMinFilterToGl(CTextureDrvInfosGL *glText)
static inline bool sameDXTCFormat(ITexture &tex, GLint glfmt)
{
H_AUTO_OGL(sameDXTCFormat);
#ifdef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
if(glfmt==GL_COMPRESSED_RGB_S3TC_DXT1_EXT && tex.PixelFormat==CBitmap::DXTC1)
return true;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && tex.PixelFormat==CBitmap::DXTC1Alpha)
return true;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT3_EXT && tex.PixelFormat==CBitmap::DXTC3)
return true;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT5_EXT && tex.PixelFormat==CBitmap::DXTC5)
return true;
#endif
return false;
}
@ -522,14 +727,26 @@ static inline bool sameDXTCFormat(ITexture &tex, GLint glfmt)
static inline bool isDXTCFormat(GLint glfmt)
{
H_AUTO_OGL(isDXTCFormat);
#ifdef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
if(glfmt==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
return true;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
return true;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
return true;
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
return true;
#endif
return false;
}
@ -558,14 +775,20 @@ void CDriverGL::bindTextureWithMode(ITexture &tex)
{
_DriverGLStates.setTextureMode(CDriverGLStates::TextureCubeMap);
// Bind this texture
#ifdef USE_OPENGLES
glBindTexture(GL_TEXTURE_CUBE_MAP_OES, gltext->ID);
#else
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, gltext->ID);
#endif
}
}
else
{
CDriverGLStates::TTextureMode textureMode= CDriverGLStates::Texture2D;
#ifndef USE_OPENGLES
if(gltext->TextureMode == GL_TEXTURE_RECTANGLE_NV)
textureMode = CDriverGLStates::TextureRect;
#endif
_DriverGLStates.setTextureMode(textureMode);
// Bind this texture
@ -591,11 +814,19 @@ void CDriverGL::setupTextureBasicParameters(ITexture &tex)
{
if (_Extensions.ARBTextureCubeMap)
{
#ifdef USE_OPENGLES
glTexParameteri(GL_TEXTURE_CUBE_MAP_OES,GL_TEXTURE_WRAP_S, translateWrapToGl(ITexture::Clamp, _Extensions));
glTexParameteri(GL_TEXTURE_CUBE_MAP_OES,GL_TEXTURE_WRAP_T, translateWrapToGl(ITexture::Clamp, _Extensions));
// glTexParameteri(GL_TEXTURE_CUBE_MAP_OES,GL_TEXTURE_WRAP_R, translateWrapToGl(ITexture::Clamp, _Extensions));
glTexParameteri(GL_TEXTURE_CUBE_MAP_OES,GL_TEXTURE_MAG_FILTER, translateMagFilterToGl(gltext));
glTexParameteri(GL_TEXTURE_CUBE_MAP_OES,GL_TEXTURE_MIN_FILTER, translateMinFilterToGl(gltext));
#else
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_WRAP_S, translateWrapToGl(ITexture::Clamp, _Extensions));
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_WRAP_T, translateWrapToGl(ITexture::Clamp, _Extensions));
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_WRAP_R, translateWrapToGl(ITexture::Clamp, _Extensions));
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MAG_FILTER, translateMagFilterToGl(gltext));
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MIN_FILTER, translateMinFilterToGl(gltext));
#endif
}
}
else
@ -1005,6 +1236,23 @@ bool CDriverGL::setupTextureEx (ITexture& tex, bool bUpload, bool &bAllUploaded,
clamp(x1, x0, w);
clamp(y1, y0, h);
#ifdef USE_OPENGLES
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (!bUpload)
ptr = NULL;
sint pixelSize = 4;
if (glSrcFmt == GL_ALPHA)
pixelSize = 1;
for(sint yy = 0; yy < (y1-y0); yy++)
{
char *row = (char*)ptr + ((yy + y0)*w + x0) * pixelSize;
glTexSubImage2D (GL_TEXTURE_2D, i, x0, y0+yy, x1-x0, 1, glSrcFmt, glSrcType, row );
}
#else
glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
glPixelStorei(GL_UNPACK_SKIP_ROWS, y0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, x0);
@ -1012,6 +1260,7 @@ bool CDriverGL::setupTextureEx (ITexture& tex, bool bUpload, bool &bAllUploaded,
glTexSubImage2D (GL_TEXTURE_2D, i, x0, y0, x1-x0, y1-y0, glSrcFmt,glSrcType, ptr);
else
glTexSubImage2D (GL_TEXTURE_2D, i, x0, y0, x1-x0, y1-y0, glSrcFmt,glSrcType, NULL);
#endif
// Next mipmap!!
// floor .
@ -1024,9 +1273,13 @@ bool CDriverGL::setupTextureEx (ITexture& tex, bool bUpload, bool &bAllUploaded,
}
// Reset the transfer mode...
#ifdef USE_OPENGLES
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
#else
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
#endif
}
}
@ -1081,8 +1334,11 @@ bool CDriverGL::uploadTexture (ITexture& tex, CRect& rect, uint8 nNumMipMap)
// system of "backup the previous binded texture" seems to not work with some drivers....
_DriverGLStates.activeTextureARB (0);
CDriverGLStates::TTextureMode textureMode= CDriverGLStates::Texture2D;
#ifdef GL_TEXTURE_RECTANGLE_NV
if(gltext->TextureMode == GL_TEXTURE_RECTANGLE_NV)
textureMode = CDriverGLStates::TextureRect;
#endif
_DriverGLStates.setTextureMode (textureMode);
// Bind this texture, for reload...
@ -1139,8 +1395,13 @@ bool CDriverGL::uploadTexture (ITexture& tex, CRect& rect, uint8 nNumMipMap)
nlassert (((x0&3) == 0) && ((y0&3) == 0));
if ((w>=4) && (h>=4))
{
nglCompressedTexSubImage2DARB ( GL_TEXTURE_2D, nNumMipMap-decalMipMapResize,
x0, y0, (x1-x0), (y1-y0), glfmt, imageSize, ptr );
#ifdef USE_OPENGLES
glCompressedTexSubImage2D (
#else
nglCompressedTexSubImage2DARB (
#endif
GL_TEXTURE_2D, nNumMipMap-decalMipMapResize,
x0, y0, (x1-x0), (y1-y0), glfmt, imageSize, ptr );
}
else
{
@ -1148,7 +1409,12 @@ bool CDriverGL::uploadTexture (ITexture& tex, CRect& rect, uint8 nNumMipMap)
// of the mipmap is less than 4 pixel so we use the other form. (its not really time critical
// to upload 16 bytes so we can do it twice if texture is cut)
imageSize = tex.getPixels(nNumMipMap).size();
nglCompressedTexImage2DARB (GL_TEXTURE_2D, nNumMipMap-decalMipMapResize,
#ifdef USE_OPENGLES
glCompressedTexImage2D (
#else
nglCompressedTexImage2DARB (
#endif
GL_TEXTURE_2D, nNumMipMap-decalMipMapResize,
glfmt, w, h, 0, imageSize, ptr);
}
}
@ -1158,6 +1424,22 @@ bool CDriverGL::uploadTexture (ITexture& tex, CRect& rect, uint8 nNumMipMap)
nlassert (glSrcFmt!=GL_RGBA || tex.getPixelFormat()==CBitmap::RGBA);
void *ptr= tex.getPixels(nNumMipMap).getPtr();
#ifdef USE_OPENGLES
sint pixelSize = 4;
if (glSrcFmt == GL_ALPHA)
pixelSize = 1;
for(sint yy = 0; yy < (y1-y0); yy++)
{
char *row = (char*)ptr + ((yy + y0)*w + x0) * pixelSize;
glTexSubImage2D (GL_TEXTURE_2D, nNumMipMap, x0, y0+yy, x1-x0, 1, glSrcFmt, glSrcType, row );
}
// Reset the transfer mode...
// glPixelStorei (GL_UNPACK_ALIGNMENT, 0);
#else
glPixelStorei (GL_UNPACK_ROW_LENGTH, w);
glPixelStorei (GL_UNPACK_SKIP_ROWS, y0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, x0);
@ -1167,6 +1449,7 @@ bool CDriverGL::uploadTexture (ITexture& tex, CRect& rect, uint8 nNumMipMap)
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
#endif
}
// Disable texture 0
@ -1227,19 +1510,31 @@ bool CDriverGL::activateTexture(uint stage, ITexture *tex)
_CurrentTextureInfoGL[stage]= gltext;
// setup this texture
#ifdef USE_OPENGLES
glBindTexture(GL_TEXTURE_CUBE_MAP_OES, gltext->ID);
#else
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, gltext->ID);
#endif
// Change parameters of texture, if necessary.
//============================================
if(gltext->MagFilter!= tex->getMagFilter())
{
gltext->MagFilter= tex->getMagFilter();
#ifdef USE_OPENGLES
glTexParameteri(GL_TEXTURE_CUBE_MAP_OES,GL_TEXTURE_MAG_FILTER, translateMagFilterToGl(gltext));
#else
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MAG_FILTER, translateMagFilterToGl(gltext));
#endif
}
if(gltext->MinFilter!= tex->getMinFilter())
{
gltext->MinFilter= tex->getMinFilter();
#ifdef USE_OPENGLES
glTexParameteri(GL_TEXTURE_CUBE_MAP_OES,GL_TEXTURE_MIN_FILTER, translateMinFilterToGl(gltext));
#else
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MIN_FILTER, translateMinFilterToGl(gltext));
#endif
}
}
}
@ -1248,8 +1543,10 @@ bool CDriverGL::activateTexture(uint stage, ITexture *tex)
{
// setup texture mode, after activeTextureARB()
CDriverGLStates::TTextureMode textureMode= CDriverGLStates::Texture2D;
#ifndef USE_OPENGLES
if(gltext->TextureMode == GL_TEXTURE_RECTANGLE_NV)
textureMode = CDriverGLStates::TextureRect;
#endif
_DriverGLStates.setTextureMode(/*CDriverGLStates::Texture2D*/textureMode);
// Activate texture...
@ -1296,11 +1593,14 @@ bool CDriverGL::activateTexture(uint stage, ITexture *tex)
_CurrentTextureInfoGL[stage]= NULL;
// setup texture mode, after activeTextureARB()
_DriverGLStates.setTextureMode(CDriverGLStates::TextureDisabled);
#ifndef USE_OPENGLES
if (_Extensions.ATITextureEnvCombine3)
{
// very strange bug with ATI cards : when a texture is set to NULL at a stage, the stage is still active sometimes...
activateTexEnvMode(stage, _TexEnvReplace); // set the whole stage to replace fix the problem
}
#endif
}
this->_CurrentTexture[stage]= tex;
@ -1311,24 +1611,43 @@ bool CDriverGL::activateTexture(uint stage, ITexture *tex)
// This maps the CMaterial::TTexOperator
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 };
static const GLenum OperatorLUT[9]= { GL_REPLACE, GL_MODULATE, GL_ADD,
#ifdef USE_OPENGLES
GL_ADD_SIGNED, GL_INTERPOLATE, GL_INTERPOLATE, GL_INTERPOLATE, GL_INTERPOLATE
#else
GL_ADD_SIGNED_EXT, GL_INTERPOLATE_EXT, GL_INTERPOLATE_EXT, GL_INTERPOLATE_EXT, GL_INTERPOLATE_EXT, GL_BUMP_ENVMAP_ATI
#endif
};
// This maps the CMaterial::TTexSource
static const GLenum SourceLUT[4]= { GL_TEXTURE, GL_PREVIOUS_EXT, GL_PRIMARY_COLOR_EXT, GL_CONSTANT_EXT };
static const GLenum SourceLUT[4]= { GL_TEXTURE,
#ifdef USE_OPENGLES
GL_PREVIOUS, GL_PRIMARY_COLOR, GL_CONSTANT
#else
GL_PREVIOUS_EXT, GL_PRIMARY_COLOR_EXT, GL_CONSTANT_EXT
#endif
};
// This maps the CMaterial::TTexOperand
static const GLenum OperandLUT[4]= { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA };
// This maps the CMaterial::TTexOperator, used for openGL Arg2 setup.
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 };
static const GLenum InterpolateSrcLUT[8]= { GL_TEXTURE, GL_TEXTURE, GL_TEXTURE, GL_TEXTURE, GL_TEXTURE,
#ifdef USE_OPENGLES
GL_PREVIOUS, GL_PRIMARY_COLOR, GL_CONSTANT
#else
GL_PREVIOUS_EXT, GL_PRIMARY_COLOR_EXT, GL_CONSTANT_EXT
#endif
};
#ifndef USE_OPENGLES
// ***************************************************************************
// Set general tex env using ENV_COMBINE4 for the current setupped stage (used by forceActivateTexEnvMode)
static void forceActivateTexEnvModeEnvCombine4(const CMaterial::CTexEnv &env)
{
H_AUTO_OGL(forceActivateTexEnvModeEnvCombine4)
H_AUTO_OGL(forceActivateTexEnvModeEnvCombine4);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
//== RGB ==
@ -1613,6 +1932,7 @@ static void forceActivateTexEnvModeEnvCombine4(const CMaterial::CTexEnv &env)
}
}
#endif
// ***************************************************************************
void CDriverGL::forceActivateTexEnvMode(uint stage, const CMaterial::CTexEnv &env)
@ -1626,6 +1946,116 @@ void CDriverGL::forceActivateTexEnvMode(uint stage, const CMaterial::CTexEnv &
// Setup the gl env mode.
_DriverGLStates.activeTextureARB(stage);
#ifdef USE_OPENGLES
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
// RGB.
//=====
if (env.Env.OpRGB == CMaterial::Mad)
{
//
if (false)
{
// GL_MODULATE_ADD_ATI
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
// Arg0.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, SourceLUT[env.Env.SrcArg0RGB] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, OperandLUT[env.Env.OpArg0RGB]);
// Arg1.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, SourceLUT[env.Env.SrcArg1RGB] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, OperandLUT[env.Env.OpArg1RGB]);
// Arg2.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, SourceLUT[env.Env.SrcArg2RGB] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, OperandLUT[env.Env.OpArg2RGB]);
}
else
{
// fallback to modulate ..
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
//
// Arg0.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, SourceLUT[env.Env.SrcArg0RGB] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, OperandLUT[env.Env.OpArg0RGB]);
// Arg1.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, SourceLUT[env.Env.SrcArg1RGB] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, OperandLUT[env.Env.OpArg1RGB]);
}
}
else
{
// Operator.
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, OperatorLUT[env.Env.OpRGB] );
// Arg0.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, SourceLUT[env.Env.SrcArg0RGB] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, OperandLUT[env.Env.OpArg0RGB]);
// Arg1.
if(env.Env.OpRGB > CMaterial::Replace)
{
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, SourceLUT[env.Env.SrcArg1RGB] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, OperandLUT[env.Env.OpArg1RGB]);
// Arg2.
if(env.Env.OpRGB >= CMaterial::InterpolateTexture )
{
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, InterpolateSrcLUT[env.Env.OpRGB] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
}
}
}
// Alpha.
//=====
if (env.Env.OpAlpha == CMaterial::Mad)
{
if (true)
{
// GL_MODULATE_ADD_ATI
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
// Arg0.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, SourceLUT[env.Env.SrcArg0Alpha] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, OperandLUT[env.Env.OpArg0Alpha]);
// Arg1.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, SourceLUT[env.Env.SrcArg1Alpha] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, OperandLUT[env.Env.OpArg1Alpha]);
// Arg2.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, SourceLUT[env.Env.SrcArg2Alpha] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, OperandLUT[env.Env.OpArg2Alpha]);
}
else
{
// fallback to modulate ..
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
//
// Arg0.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, SourceLUT[env.Env.SrcArg0RGB] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, OperandLUT[env.Env.OpArg0RGB]);
// Arg1.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, SourceLUT[env.Env.SrcArg1RGB] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, OperandLUT[env.Env.OpArg1RGB]);
}
}
else
{
// Operator.
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, OperatorLUT[env.Env.OpAlpha] );
// Arg0.
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, SourceLUT[env.Env.SrcArg0Alpha] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, OperandLUT[env.Env.OpArg0Alpha]);
// Arg1.
if(env.Env.OpAlpha > CMaterial::Replace)
{
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, SourceLUT[env.Env.SrcArg1Alpha] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, OperandLUT[env.Env.OpArg1Alpha]);
// Arg2.
if(env.Env.OpAlpha >= CMaterial::InterpolateTexture )
{
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA, InterpolateSrcLUT[env.Env.OpAlpha] );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
}
}
}
#else
// if the Mad operator is used, then
// "Normal drivers", setup EnvCombine.
if(_Extensions.EXTTextureEnvCombine)
@ -1746,6 +2176,7 @@ void CDriverGL::forceActivateTexEnvMode(uint stage, const CMaterial::CTexEnv &
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
#endif
}
// ***************************************************************************

View file

@ -1313,6 +1313,7 @@ void CDriverGL::setupGlArraysForARBVertexProgram(CVertexBufferInfo &vb)
_DriverGLStates.bindARBVertexBuffer(vb.VertexObjectId);
}
#ifndef USE_OPENGLES
// special case if the buffer is an ATI_vertex_array_object
if (vb.VBMode == CVertexBufferInfo::HwATI)
{
@ -1346,6 +1347,7 @@ void CDriverGL::setupGlArraysForARBVertexProgram(CVertexBufferInfo &vb)
}
}
else
#endif
{
// For each value
for (uint value=0; value<CVertexBuffer::NumValue; value++)
@ -1367,7 +1369,11 @@ void CDriverGL::setupGlArraysForARBVertexProgram(CVertexBufferInfo &vb)
{
mustNormalize = ARBVertexProgramMustNormalizeAttrib[value];
}
#ifdef USE_OPENGLES
glVertexPointer(NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
#else
nglVertexAttribPointerARB(glIndex, NumCoordinatesType[type], GLType[type], mustNormalize, vb.VertexSize, vb.ValuePtr[value]);
#endif
}
else
{
@ -1415,6 +1421,7 @@ void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb)
if (flags & flag & drvInfo->UsedVertexComponents)
{
_DriverGLStates.enableVertexAttribArrayForEXTVertexShader(glIndex, true, drvInfo->Variants);
#ifndef USE_OPENGLES
// use variant or open gl standard array
if (vb.VBMode == CVertexBufferInfo::HwATI)
{
@ -1487,6 +1494,7 @@ void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb)
}
}
else
#endif
{
switch(value)
{
@ -1499,7 +1507,9 @@ void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb)
case CVertexBuffer::Weight: // skin weight
{
nlassert(NumCoordinatesType[type] == 4); // variant, only 4 component supported
#ifndef USE_OPENGLES
nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSSkinWeightVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
#endif
}
break;
case CVertexBuffer::Normal: // normal
@ -1518,21 +1528,27 @@ void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb)
{
// implemented using a variant, as not available with EXTVertexShader
nlassert(NumCoordinatesType[type] == 4); // variant, only 4 component supported
#ifndef USE_OPENGLES
nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSSecondaryColorVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
#endif
}
break;
case CVertexBuffer::Fog: // fog coordinate
{
// implemented using a variant
nlassert(NumCoordinatesType[type] == 4); // variant, only 4 component supported
#ifndef USE_OPENGLES
nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSFogCoordsVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
#endif
}
break;
case CVertexBuffer::PaletteSkin: // palette skin
{
// implemented using a variant
nlassert(NumCoordinatesType[type] == 4); // variant, only 4 component supported
#ifndef USE_OPENGLES
nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSPaletteSkinVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
#endif
}
break;
case CVertexBuffer::Empty: // empty
@ -1789,6 +1805,7 @@ void CDriverGL::fenceOnCurVBHardIfNeeded(IVertexBufferHardGL *newVBHard)
{
H_AUTO_OGL(CDriverGL_fenceOnCurVBHardIfNeeded);
#ifndef USE_OPENGLES
// If old is not a VBHard, or if not a NVidia VBHard, no-op.
if( _CurrentVertexBufferHard==NULL || !_CurrentVertexBufferHard->VBType == IVertexBufferHardGL::NVidiaVB)
return;
@ -1817,6 +1834,7 @@ void CDriverGL::fenceOnCurVBHardIfNeeded(IVertexBufferHardGL *newVBHard)
vbHardNV->GPURenderingAfterFence= false;
}
}
#endif
}
// ***************************************************************************

View file

@ -43,6 +43,7 @@ CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInf
|| drv->_Extensions.ARBVertexProgram
);
#ifndef USE_OPENGLES
if (drv->_Extensions.NVVertexProgram) // NVIDIA implemntation
{
// Generate a program
@ -56,6 +57,7 @@ CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInf
{
ID = nglGenVertexShadersEXT(1); // ATI implementation
}
#endif
}
@ -79,6 +81,8 @@ bool CDriverGL::isVertexProgramEmulated () const
bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
{
H_AUTO_OGL(CVertexProgamDrvInfosGL_activeNVVertexProgram)
#ifndef USE_OPENGLES
// Setup or unsetup ?
if (program)
{
@ -188,6 +192,9 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
// Ok
return true;
}
#endif
return false;
}
@ -200,10 +207,16 @@ inline GLenum convSwizzleToGLFormat(CVPSwizzle::EComp comp, bool negate)
{
switch(comp)
{
#ifdef USE_OPENGLES
case CVPSwizzle::X: return GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES;
case CVPSwizzle::Y: return GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES;
case CVPSwizzle::Z: return GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES;
#else
case CVPSwizzle::X: return GL_X_EXT;
case CVPSwizzle::Y: return GL_Y_EXT;
case CVPSwizzle::Z: return GL_Z_EXT;
case CVPSwizzle::W: return GL_W_EXT;
#endif
default:
nlstop;
return 0;
@ -214,10 +227,16 @@ inline GLenum convSwizzleToGLFormat(CVPSwizzle::EComp comp, bool negate)
{
switch(comp)
{
#ifdef USE_OPENGLES
case CVPSwizzle::X: return GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES;
case CVPSwizzle::Y: return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES;
case CVPSwizzle::Z: return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES;
#else
case CVPSwizzle::X: return GL_NEGATIVE_X_EXT;
case CVPSwizzle::Y: return GL_NEGATIVE_Y_EXT;
case CVPSwizzle::Z: return GL_NEGATIVE_Z_EXT;
case CVPSwizzle::W: return GL_NEGATIVE_W_EXT;
#endif
default:
nlstop;
return 0;
@ -231,7 +250,9 @@ inline GLenum convSwizzleToGLFormat(CVPSwizzle::EComp comp, bool negate)
*/
static GLuint convOutputRegisterToEXTVertexShader(CVPOperand::EOutputRegister r)
{
H_AUTO_OGL(convOutputRegisterToEXTVertexShader)
H_AUTO_OGL(convOutputRegisterToEXTVertexShader);
#ifndef USE_OPENGLES
switch (r)
{
case CVPOperand::OHPosition: return GL_OUTPUT_VERTEX_EXT;
@ -259,6 +280,8 @@ static GLuint convOutputRegisterToEXTVertexShader(CVPOperand::EOutputRegister r)
nlstop;
break;
}
#endif
return 0;
}
@ -310,6 +333,8 @@ static uint convInputRegisterToVBFlag(uint index)
static void doSwizzle(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW)
{
H_AUTO_OGL(doSwizzle);
#ifndef USE_OPENGLES
nglSwizzleEXT(res, in, outX, outY, outZ, outW);
#ifdef DEBUG_SETUP_EXT_VERTEX_SHADER
std::string swzStr = "Swizzle : ";
@ -353,13 +378,15 @@ static void doSwizzle(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum ou
}
EVS_INFO(swzStr.c_str());
#endif
#endif
}
// Perform write mask and output de bug information
static void doWriteMask(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW)
{
H_AUTO_OGL(doWriteMask);
#ifndef USE_OPENGLES
nglWriteMaskEXT(res, in, outX, outY, outZ, outW);
#ifdef DEBUG_SETUP_EXT_VERTEX_SHADER
nlinfo("3D: Write Mask : %c%c%c%c",
@ -369,6 +396,7 @@ static void doWriteMask(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum
outW ? 'w' : '-'
);
#endif
#endif
}
// ***************************************************************************
@ -377,6 +405,8 @@ static void doWriteMask(GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum
bool CDriverGL::setupEXTVertexShader(const CVPParser::TProgram &program, GLuint id, uint variants[EVSNumVariants], uint16 &usedInputRegisters)
{
H_AUTO_OGL(CDriverGL_setupEXTVertexShader);
#ifndef USE_OPENGLES
// counter to see what is generated
uint numOp = 0;
uint numOpIndex = 0;
@ -1157,7 +1187,9 @@ bool CDriverGL::setupEXTVertexShader(const CVPParser::TProgram &program, GLuint
#endif
return true;
#else
return false;
#endif
}
//=================================================================================================
@ -1315,6 +1347,8 @@ static void ARBVertexProgramDumpInstr(const CVPInstruction &instr, std::string &
bool CDriverGL::setupARBVertexProgram (const CVPParser::TProgram &inParsedProgram, GLuint id, bool &specularWritten)
{
H_AUTO_OGL(CDriverGL_setupARBVertexProgram)
#ifndef USE_OPENGLES
// tmp
CVPParser::TProgram parsedProgram = inParsedProgram;
//
@ -1449,6 +1483,9 @@ bool CDriverGL::setupARBVertexProgram (const CVPParser::TProgram &inParsedProgra
#endif
return true;
#else
return false;
#endif
}
@ -1456,7 +1493,9 @@ bool CDriverGL::setupARBVertexProgram (const CVPParser::TProgram &inParsedProgra
// ***************************************************************************
bool CDriverGL::activeARBVertexProgram (CVertexProgram *program)
{
H_AUTO_OGL(CDriverGL_activeARBVertexProgram)
H_AUTO_OGL(CDriverGL_activeARBVertexProgram);
#ifndef USE_OPENGLES
// Setup or unsetup ?
if (program)
{
@ -1520,13 +1559,18 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program)
_VertexProgramEnabled = false;
}
return true;
#else
return false;
#endif
}
// ***************************************************************************
bool CDriverGL::activeEXTVertexShader (CVertexProgram *program)
{
H_AUTO_OGL(CDriverGL_activeEXTVertexShader)
H_AUTO_OGL(CDriverGL_activeEXTVertexShader);
#ifndef USE_OPENGLES
// Setup or unsetup ?
if (program)
{
@ -1594,6 +1638,9 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program)
_VertexProgramEnabled = false;
}
return true;
#else
return false;
#endif
}
// ***************************************************************************
@ -1623,7 +1670,9 @@ bool CDriverGL::activeVertexProgram (CVertexProgram *program)
void CDriverGL::setConstant (uint index, float f0, float f1, float f2, float f3)
{
H_AUTO_OGL(CDriverGL_setConstant)
H_AUTO_OGL(CDriverGL_setConstant);
#ifndef USE_OPENGLES
// Vertex program exist ?
if (_Extensions.NVVertexProgram)
{
@ -1639,6 +1688,7 @@ void CDriverGL::setConstant (uint index, float f0, float f1, float f2, float f3)
float datas[] = { f0, f1, f2, f3 };
nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas);
}
#endif
}
@ -1646,7 +1696,9 @@ void CDriverGL::setConstant (uint index, float f0, float f1, float f2, float f3)
void CDriverGL::setConstant (uint index, double d0, double d1, double d2, double d3)
{
H_AUTO_OGL(CDriverGL_setConstant)
H_AUTO_OGL(CDriverGL_setConstant);
#ifndef USE_OPENGLES
// Vertex program exist ?
if (_Extensions.NVVertexProgram)
{
@ -1662,6 +1714,7 @@ void CDriverGL::setConstant (uint index, double d0, double d1, double d2, double
double datas[] = { d0, d1, d2, d3 };
nglSetInvariantEXT(_EVSConstantHandle + index, GL_DOUBLE, datas);
}
#endif
}
@ -1669,7 +1722,9 @@ void CDriverGL::setConstant (uint index, double d0, double d1, double d2, double
void CDriverGL::setConstant (uint index, const NLMISC::CVector& value)
{
H_AUTO_OGL(CDriverGL_setConstant)
H_AUTO_OGL(CDriverGL_setConstant);
#ifndef USE_OPENGLES
// Vertex program exist ?
if (_Extensions.NVVertexProgram)
{
@ -1685,6 +1740,7 @@ void CDriverGL::setConstant (uint index, const NLMISC::CVector& value)
float datas[] = { value.x, value.y, value.z, 0 };
nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas);
}
#endif
}
@ -1692,7 +1748,9 @@ void CDriverGL::setConstant (uint index, const NLMISC::CVector& value)
void CDriverGL::setConstant (uint index, const NLMISC::CVectorD& value)
{
H_AUTO_OGL(CDriverGL_setConstant)
H_AUTO_OGL(CDriverGL_setConstant);
#ifndef USE_OPENGLES
// Vertex program exist ?
if (_Extensions.NVVertexProgram)
{
@ -1708,13 +1766,16 @@ void CDriverGL::setConstant (uint index, const NLMISC::CVectorD& value)
double datas[] = { value.x, value.y, value.z, 0 };
nglSetInvariantEXT(_EVSConstantHandle + index, GL_DOUBLE, datas);
}
#endif
}
// ***************************************************************************
void CDriverGL::setConstant (uint index, uint num, const float *src)
{
H_AUTO_OGL(CDriverGL_setConstant)
H_AUTO_OGL(CDriverGL_setConstant);
#ifndef USE_OPENGLES
// Vertex program exist ?
if (_Extensions.NVVertexProgram)
{
@ -1734,12 +1795,15 @@ void CDriverGL::setConstant (uint index, uint num, const float *src)
nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_FLOAT, (void *) (src + 4 * k));
}
}
#endif
}
// ***************************************************************************
void CDriverGL::setConstant (uint index, uint num, const double *src)
{
H_AUTO_OGL(CDriverGL_setConstant)
H_AUTO_OGL(CDriverGL_setConstant);
#ifndef USE_OPENGLES
// Vertex program exist ?
if (_Extensions.NVVertexProgram)
{
@ -1759,6 +1823,7 @@ void CDriverGL::setConstant (uint index, uint num, const double *src)
nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_DOUBLE, (void *) (src + 4 * k));
}
}
#endif
}
// ***************************************************************************
@ -1767,7 +1832,11 @@ const uint CDriverGL::GLMatrix[IDriver::NumMatrix]=
{
GL_MODELVIEW,
GL_PROJECTION,
#ifdef USE_OPENGLES
GL_MODELVIEW
#else
GL_MODELVIEW_PROJECTION_NV
#endif
};
@ -1775,10 +1844,17 @@ const uint CDriverGL::GLMatrix[IDriver::NumMatrix]=
const uint CDriverGL::GLTransform[IDriver::NumTransform]=
{
#ifdef USE_OPENGLES
0,
0,
0,
0
#else
GL_IDENTITY_NV,
GL_INVERSE_NV,
GL_TRANSPOSE_NV,
GL_INVERSE_TRANSPOSE_NV
#endif
};
@ -1786,7 +1862,9 @@ const uint CDriverGL::GLTransform[IDriver::NumTransform]=
void CDriverGL::setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform)
{
H_AUTO_OGL(CDriverGL_setConstantMatrix)
H_AUTO_OGL(CDriverGL_setConstantMatrix);
#ifndef USE_OPENGLES
// Vertex program exist ?
if (_Extensions.NVVertexProgram)
{
@ -1856,6 +1934,7 @@ void CDriverGL::setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver:
nglSetInvariantEXT(_EVSConstantHandle + index + 3, GL_FLOAT, matDatas + 12);
}
}
#endif
}
// ***************************************************************************
@ -1871,7 +1950,9 @@ void CDriverGL::setConstantFog (uint index)
void CDriverGL::enableVertexProgramDoubleSidedColor(bool doubleSided)
{
H_AUTO_OGL(CDriverGL_enableVertexProgramDoubleSidedColor)
H_AUTO_OGL(CDriverGL_enableVertexProgramDoubleSidedColor);
#ifndef USE_OPENGLES
// Vertex program exist ?
if (_Extensions.NVVertexProgram)
{
@ -1889,6 +1970,7 @@ void CDriverGL::enableVertexProgramDoubleSidedColor(bool doubleSided)
else
glDisable (GL_VERTEX_PROGRAM_TWO_SIDE_ARB);
}
#endif
}

View file

@ -22,24 +22,20 @@
// by default, we disable the windows menu keys (F10, ALT and ALT+SPACE key doesn't freeze or open the menu)
#define NL_DISABLE_MENU
#ifdef NL_OS_WINDOWS
# include <windowsx.h>
#elif defined(NL_OS_MAC)
#ifdef NL_OS_MAC
# import "mac/cocoa_window_delegate.h"
# import "mac/cocoa_application_delegate.h"
# import <OpenGL/OpenGL.h>
#elif defined (NL_OS_UNIX)
# include <GL/gl.h>
# include <GL/glx.h>
# ifdef HAVE_XRANDR
# include <X11/extensions/Xrandr.h>
# endif // HAVE_XRANDR
# ifdef HAVE_XRENDER
# include <X11/extensions/Xrender.h>
# endif // HAVE_XRENDER
# include <X11/Xatom.h>
# define _NET_WM_STATE_REMOVE 0
# define _NET_WM_STATE_ADD 1
# ifdef HAVE_XRANDR
# include <X11/extensions/Xrandr.h>
# endif // HAVE_XRANDR
# ifdef HAVE_XRENDER
# include <X11/extensions/Xrender.h>
# endif // HAVE_XRENDER
# include <X11/Xatom.h>
# define _NET_WM_STATE_REMOVE 0
# define _NET_WM_STATE_ADD 1
#endif // NL_OS_UNIX
#include "nel/misc/mouse_device.h"
@ -111,6 +107,7 @@ bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
H_AUTO_OGL(DriverGL_WndProc)
// Get the driver pointer..
CDriverGL *pDriver=(CDriverGL*)GetWindowLongPtr (hWnd, GWLP_USERDATA);
bool trapMessage = false;
@ -444,6 +441,7 @@ bool CDriverGL::unInit()
#ifdef NL_OS_WINDOWS
#ifndef USE_OPENGLES
// Off-screen rendering ?
if (_PBuffer)
{
@ -451,6 +449,7 @@ bool CDriverGL::unInit()
nwglDestroyPbufferARB(_PBuffer);
_PBuffer = NULL;
}
#endif
if (_Registered && !UnregisterClassW(L"NLClass", GetModuleHandle(NULL)))
{
@ -606,14 +605,15 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
#ifdef NL_OS_WINDOWS
// Init pointers
#ifndef USE_OPENGLES
_PBuffer = NULL;
_hRC = NULL;
_hDC = NULL;
#endif
// Driver caps.
//=============
// Retrieve the WGL extensions before init the driver.
int pf;
// Offscreen mode ?
if (_CurrentMode.OffScreen)
@ -652,7 +652,7 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
_pfd.cAlphaBits = 8;
}
_pfd.iLayerType = PFD_MAIN_PLANE;
pf=ChoosePixelFormat(tempHDC,&_pfd);
int pf=ChoosePixelFormat(tempHDC,&_pfd);
if (!pf)
{
nlwarning ("CDriverGL::setDisplay: ChoosePixelFormat failed");
@ -695,7 +695,11 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
}
// Register WGL functions
#ifdef USE_OPENGLES
registerEGlExtensions (_Extensions, tempHDC);
#else
registerWGlExtensions (_Extensions, tempHDC);
#endif
HDC hdc = wglGetCurrentDC ();
@ -854,11 +858,19 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
_CurrentMode.Depth = uint8(GetDeviceCaps (_hDC, BITSPIXEL));
// Destroy the temp gl context
#ifdef USE_OPENGLES
if (!eglDestroyContext(_EglDisplay, _EglContext);)
{
DWORD error = GetLastError ();
nlwarning ("CDriverGL::setDisplay: wglDeleteContext failed: 0x%x", error);
}
#else
if (!wglDeleteContext (tempGLRC))
{
DWORD error = GetLastError ();
nlwarning ("CDriverGL::setDisplay: wglDeleteContext failed: 0x%x", error);
}
#endif
// Destroy the temp windows
if (!DestroyWindow (tmpHWND))
@ -871,9 +883,15 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
{
DWORD error = GetLastError ();
nlwarning ("CDriverGL::setDisplay: wglMakeCurrent failed: 0x%x", error);
#ifdef USE_OPENGLES
eglDestroyContext(_EglDisplay, _EglContext);
#else
wglDeleteContext (_hRC);
nwglReleasePbufferDCARB( _PBuffer, _hDC );
nwglDestroyPbufferARB( _PBuffer );
#endif
DestroyWindow (tmpHWND);
_PBuffer = NULL;
_win = EmptyWindow;
@ -898,43 +916,7 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
// associate OpenGL driver to window
SetWindowLongPtr(_win, GWLP_USERDATA, (LONG_PTR)this);
_hDC=GetDC(_win);
wglMakeCurrent(_hDC,NULL);
_CurrentMode.Depth = uint8(GetDeviceCaps(_hDC,BITSPIXEL));
// ---
memset(&_pfd,0,sizeof(_pfd));
_pfd.nSize = sizeof(_pfd);
_pfd.nVersion = 1;
_pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
_pfd.iPixelType = PFD_TYPE_RGBA;
_pfd.cColorBits = _CurrentMode.Depth;
// Choose best suited Depth Buffer.
if(_CurrentMode.Depth <= 16)
{
_pfd.cDepthBits = 16;
}
else
{
_pfd.cDepthBits = 24;
_pfd.cAlphaBits = 8;
_pfd.cStencilBits = 8;
}
_pfd.iLayerType = PFD_MAIN_PLANE;
pf=ChoosePixelFormat(_hDC,&_pfd);
if (!pf)
{
return false;
}
if ( !SetPixelFormat(_hDC,pf,&_pfd) )
{
return false;
}
_hRC=wglCreateContext(_hDC);
wglMakeCurrent(_hDC,_hRC);
createContext();
}
/// release old emitter
@ -1615,7 +1597,19 @@ bool CDriverGL::destroyWindow()
std::vector<NLMISC::CBitmap> bitmaps;
setWindowIcon(bitmaps);
#ifdef NL_OS_WINDOWS
#ifdef USE_OPENGLES
if (_EglDisplay && _EglContext)
{
eglMakeCurrent(_EglDisplay, _EglSurface, _EglSurface, _EglContext);
if (_DestroyWindow)
{
eglDestroyContext(_EglDisplay, _EglContext);
}
}
#elif defined(NL_OS_WINDOWS)
// Then delete.
// wglMakeCurrent(NULL,NULL);
@ -1633,12 +1627,24 @@ bool CDriverGL::destroyWindow()
{
ReleaseDC(_win, _hDC);
_hDC = NULL;
// don't destroy window if it hasn't been created by our driver
if (_DestroyWindow)
DestroyWindow(_win);
}
#elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX)
if (_DestroyWindow && _ctx)
glXDestroyContext(_dpy, _ctx);
_ctx = NULL;
#endif
#ifdef NL_OS_WINDOWS
// don't destroy window if it hasn't been created by our driver
if (_win && _DestroyWindow)
DestroyWindow(_win);
#elif defined(NL_OS_MAC)
if (_DestroyWindow)
@ -1654,16 +1660,8 @@ bool CDriverGL::destroyWindow()
_EventEmitter.closeIM();
if (_DestroyWindow)
{
if (_ctx)
glXDestroyContext(_dpy, _ctx);
if (_win)
XDestroyWindow(_dpy, _win);
}
_ctx = NULL;
if (_DestroyWindow && _win)
XDestroyWindow(_dpy, _win);
// Ungrab the keyboard (probably not necessary);
// XUnmapWindow(_dpy, _win);
@ -2366,6 +2364,150 @@ emptyProc CDriverGL::getWindowProc()
return (emptyProc)GlWndProc;
}
// --------------------------------------------------
bool CDriverGL::createContext()
{
#ifdef USE_OPENGLES
uint samples = 0;
if (_CurrentMode.AntiAlias > -1)
{
if (_CurrentMode.AntiAlias == 0)
{
samples = 4;
}
else
{
samples = _CurrentMode.AntiAlias;
}
}
EGLint attribList[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 8,
// EGL_SAMPLE_BUFFERS, _CurrentMode.AntiAlias > -1 ? 1:0,
// EGL_SAMPLES, samples,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES_BIT,
EGL_NONE
};
// Get Display
_EglDisplay = EGL_NO_DISPLAY; // eglGetDisplay(_hDC);
if (_EglDisplay == EGL_NO_DISPLAY)
{
_EglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (_EglDisplay == EGL_NO_DISPLAY)
{
nlwarning("3D: failed to get display 0x%x", eglGetError());
return false;
}
}
// Initialize EGL
EGLint majorVersion;
EGLint minorVersion;
if (!eglInitialize(_EglDisplay, &majorVersion, &minorVersion))
{
return EGL_FALSE;
}
const char *extensions = eglQueryString(_EglDisplay, EGL_EXTENSIONS);
// Get configs
EGLint numConfigs;
if (!eglGetConfigs(_EglDisplay, NULL, 0, &numConfigs))
{
return false;
}
// Choose config
EGLConfig config = NULL;
if (!eglChooseConfig(_EglDisplay, attribList, &config, 1, &numConfigs))
{
return false;
}
// Create a surface
_EglSurface = eglCreateWindowSurface(_EglDisplay, config, (EGLNativeWindowType)_win, NULL);
if (_EglSurface == EGL_NO_SURFACE)
{
return false;
}
// Create a GL context
EGLint contextAttribs[] =
{
EGL_CONTEXT_CLIENT_VERSION, 1,
EGL_NONE
};
_EglContext = eglCreateContext(_EglDisplay, config, EGL_NO_CONTEXT, contextAttribs);
if (_EglContext == EGL_NO_CONTEXT)
{
return false;
}
// Make the context current
if (!eglMakeCurrent(_EglDisplay, _EglSurface, _EglSurface, _EglContext))
{
return false;
}
#elif defined(NL_OS_WINDOWS)
_hDC = GetDC(_win);
_CurrentMode.Depth = uint8(GetDeviceCaps(_hDC,BITSPIXEL));
wglMakeCurrent(_hDC,NULL);
// ---
memset(&_pfd,0,sizeof(_pfd));
_pfd.nSize = sizeof(_pfd);
_pfd.nVersion = 1;
_pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
_pfd.iPixelType = PFD_TYPE_RGBA;
_pfd.cColorBits = _CurrentMode.Depth;
// Choose best suited Depth Buffer.
if(_CurrentMode.Depth <= 16)
{
_pfd.cDepthBits = 16;
}
else
{
_pfd.cDepthBits = 24;
_pfd.cAlphaBits = 8;
_pfd.cStencilBits = 8;
}
_pfd.iLayerType = PFD_MAIN_PLANE;
int pf=ChoosePixelFormat(_hDC,&_pfd);
if (!pf)
{
return false;
}
if ( !SetPixelFormat(_hDC,pf,&_pfd) )
{
return false;
}
_hRC=wglCreateContext(_hDC);
wglMakeCurrent(_hDC,_hRC);
#endif
return true;
}
// --------------------------------------------------
bool CDriverGL::activate()
{
@ -2374,7 +2516,20 @@ bool CDriverGL::activate()
if (_win == EmptyWindow)
return false;
#ifdef NL_OS_WINDOWS
#ifdef USE_OPENGLES
EGLContext ctx = eglGetCurrentContext();
if (ctx != _EglContext)
{
// Make the context current
if (!eglMakeCurrent(_EglDisplay, _EglSurface, _EglSurface, _EglContext))
{
return false;
}
}
#elif defined(NL_OS_WINDOWS)
HGLRC hglrc = wglGetCurrentContext();
@ -2393,7 +2548,7 @@ bool CDriverGL::activate()
if (nctx != NULL && nctx != _ctx)
glXMakeCurrent(_dpy, _win, _ctx);
#endif // NL_OS_WINDOWS
#endif // USE_OPENGLES
return true;
}

View file

@ -32,6 +32,36 @@
#include <deque>
#include <limits>
#ifdef NL_OS_WINDOWS
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include <windows.h>
# include <windowsx.h>
#endif
#ifdef USE_OPENGLES
# include <GLES/gl.h>
# include <GLES/glext.h>
# include <EGL/egl.h>
# include <EGL/eglext.h>
#else
# ifdef NL_OS_WINDOWS
# include <GL/gl.h>
# include <GL/glext.h>
# include <GL/wglext.h>
# elif defined(NL_OS_MAC)
# define GL_GLEXT_LEGACY
# include <OpenGL/gl.h>
# include "mac/glext.h"
# elif defined (NL_OS_UNIX)
# define GLX_GLXEXT_PROTOTYPES
# include <GL/gl.h>
# include <GL/glext.h>
# include <GL/glx.h>
# include <GL/glxext.h>
# endif
#endif
#include "nel/misc/common.h"
#include "nel/misc/debug.h"

View file

@ -0,0 +1,72 @@
SET(SOURCE_DIR ${CMAKE_SOURCE_DIR}/nel/src/3d/driver/opengl)
FILE(GLOB SRC ${SOURCE_DIR}/*.cpp ${SOURCE_DIR}/*.h ${SOURCE_DIR}/*.def)
IF(APPLE)
FILE(GLOB MAC_SRC ${SOURCE_DIR}/mac/*.h ${SOURCE_DIR}/mac/*.m ${SOURCE_DIR}/mac/*.mm ${SOURCE_DIR}/mac/*.cpp)
SET(SRC ${SRC} ${MAC_SRC})
SET_SOURCE_FILES_PROPERTIES(${SRC} PROPERTIES COMPILE_FLAGS "-x objective-c++")
ENDIF(APPLE)
ADD_DEFINITIONS(-DUSE_OPENGLES)
IF(WIN32)
SET(NLDRV_OGLES_LIB "nel_drv_opengles_win")
ELSE(WIN32)
SET(NLDRV_OGLES_LIB "nel_drv_opengles")
ENDIF(WIN32)
NL_TARGET_DRIVER(${NLDRV_OGLES_LIB} ${SRC})
INCLUDE_DIRECTORIES(${OPENGLES_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(${NLDRV_OGLES_LIB} nel3d nelmisc ${OPENGL_gles_LIBRARY})
NL_DEFAULT_PROPS(${NLDRV_OGLES_LIB} "NeL, Driver, Video: OpenGL ES")
NL_ADD_LIB_SUFFIX(${NLDRV_OGLES_LIB})
NL_ADD_RUNTIME_FLAGS(${NLDRV_OGLES_LIB})
IF(WIN32)
INCLUDE_DIRECTORIES(${DXSDK_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(${NLDRV_OGLES_LIB} ${DXSDK_DINPUT_LIBRARY} ${DXSDK_GUID_LIBRARY})
ADD_DEFINITIONS(/DDRIVER_OPENGL_EXPORTS)
ENDIF(WIN32)
IF(APPLE)
TARGET_LINK_LIBRARIES(${NLDRV_OGLES_LIB} ${CARBON})
TARGET_LINK_LIBRARIES(${NLDRV_OGLES_LIB} ${COCOA})
ENDIF(APPLE)
IF(UNIX AND NOT APPLE)
TARGET_LINK_LIBRARIES(${NLDRV_OGLES_LIB} ${X11_X11_LIB})
IF(XF86VidMode_FOUND)
INCLUDE_DIRECTORIES(${XF86VidMode_INCLUDE_DIR})
ADD_DEFINITIONS(${XF86VidMode_DEFINITIONS})
TARGET_LINK_LIBRARIES(${NLDRV_OGLES_LIB} ${XF86VidMode_LIBRARY})
ENDIF(XF86VidMode_FOUND)
IF(X11_Xrandr_FOUND)
INCLUDE_DIRECTORIES(${X11_Xrandr_INCLUDE_PATH})
ADD_DEFINITIONS(-DHAVE_XRANDR)
TARGET_LINK_LIBRARIES(${NLDRV_OGLES_LIB} ${X11_Xrandr_LIB})
ENDIF(X11_Xrandr_FOUND)
IF(X11_Xrender_FOUND)
INCLUDE_DIRECTORIES(${X11_Xrender_INCLUDE_PATH})
ADD_DEFINITIONS(-DHAVE_XRENDER)
TARGET_LINK_LIBRARIES(${NLDRV_OGLES_LIB} ${X11_Xrender_LIB})
ENDIF(X11_Xrender_FOUND)
IF(X11_Xcursor_FOUND)
INCLUDE_DIRECTORIES(${X11_Xcursor_INCLUDE_PATH})
ADD_DEFINITIONS(-DHAVE_XCURSOR)
TARGET_LINK_LIBRARIES(${NLDRV_OGLES_LIB} ${X11_Xcursor_LIB})
ENDIF(X11_Xcursor_FOUND)
ENDIF(UNIX AND NOT APPLE)
IF(WITH_PCH)
ADD_NATIVE_PRECOMPILED_HEADER(${NLDRV_OGLES_LIB} ${SOURCE_DIR}/stdopengl.h ${SOURCE_DIR}/stdopengl.cpp)
ENDIF(WITH_PCH)
IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS)
INSTALL(TARGETS ${NLDRV_OGLES_LIB} LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION lib RUNTIME DESTINATION bin COMPONENT drivers3d)
IF(WITH_MAXPLUGIN)
INSTALL(TARGETS ${NLDRV_OGLES_LIB} RUNTIME DESTINATION maxplugin COMPONENT drivers3d)
ENDIF(WITH_MAXPLUGIN)
ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS)