- alternative configuration using GLEW to get extension functions. This requires GL 2.0, though so it won't be promoted to the mainline for the time being.

- removed all pre GL 2.0 support.
This commit is contained in:
Christoph Oelckers 2014-04-06 14:35:44 +02:00
parent d74f045004
commit 69af73d9b9
14 changed files with 137 additions and 328 deletions

View file

@ -238,6 +238,30 @@ endif( NOT OPENGL_GLU_FOUND )
set( ZDOOM_LIBS ${ZDOOM_LIBS} ${OPENGL_LIBRARIES} ) set( ZDOOM_LIBS ${ZDOOM_LIBS} ${OPENGL_LIBRARIES} )
include_directories( ${OPENGL_INCLUDE_DIR} ) include_directories( ${OPENGL_INCLUDE_DIR} )
# check for GLEW
find_path( GLEW_INCLUDE_DIR GL/glew.h
PATHS "/usr/include"
"/usr/local/include" )
if( GLEW_INCLUDE_DIR )
message( STATUS "GLEW include files found at ${GLEW_INCLUDE_DIR}" )
else( GLEW_INCLUDE_DIR )
message( SEND_ERROR "Could not find GLEW include files" )
endif( GLEW_INCLUDE_DIR )
# GLEW include directory
include_directories( "${GLEW_INCLUDE_DIR}" )
find_library( GLEW_LIBRARY glew32 )
if( NOT GLEW_LIBRARY )
message( SEND_ERROR "Could not find GLEW library files" )
endif( NOT GLEW_LIBRARY )
set( ZDOOM_LIBS ${ZDOOM_LIBS} ${GLEW_LIBRARY} )
# Decide on the name of the FMOD library we want to use. # Decide on the name of the FMOD library we want to use.
if( NOT FMOD_LIB_NAME AND MSVC ) if( NOT FMOD_LIB_NAME AND MSVC )
@ -395,20 +419,6 @@ if( NOT NO_ASM )
ENDMACRO( ADD_ASM_FILE ) ENDMACRO( ADD_ASM_FILE )
endif( NOT NO_ASM ) endif( NOT NO_ASM )
# OpenGL on OS X: Search for GLEW include files
if( APPLE )
find_path( GLEW_INCLUDE_DIR GL/glew.h
PATHS "/usr/include"
"/usr/local/include" )
if( GLEW_INCLUDE_DIR )
message( STATUS "GLEW include files found at ${GLEW_INCLUDE_DIR}" )
else( GLEW_INCLUDE_DIR )
message( SEND_ERROR "Could not find GLEW include files" )
endif( GLEW_INCLUDE_DIR )
endif( APPLE )
# Decide on SSE setup # Decide on SSE setup
set( SSE_MATTERS NO ) set( SSE_MATTERS NO )
@ -565,12 +575,6 @@ else( NOT DYN_FLUIDSYNTH )
set( ZDOOM_LIBS ${ZDOOM_LIBS} ${CMAKE_DL_LIBS} ) set( ZDOOM_LIBS ${ZDOOM_LIBS} ${CMAKE_DL_LIBS} )
endif( NOT DYN_FLUIDSYNTH ) endif( NOT DYN_FLUIDSYNTH )
# OpenGL on OS X: GLEW include directory
if( APPLE )
include_directories( "${GLEW_INCLUDE_DIR}" )
endif( APPLE )
# Start defining source files for ZDoom # Start defining source files for ZDoom
set( PLAT_WIN32_SOURCES set( PLAT_WIN32_SOURCES
win32/eaxedit.cpp win32/eaxedit.cpp

View file

@ -7,6 +7,7 @@
#define __EXTERN extern #define __EXTERN extern
#endif #endif
#if 0
__EXTERN PFNGLBLENDEQUATIONPROC glBlendEquation; __EXTERN PFNGLBLENDEQUATIONPROC glBlendEquation;
// ARB_SHADER_OBJECTS // ARB_SHADER_OBJECTS
@ -98,3 +99,5 @@ __EXTERN PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
__EXTERN PFNGLTEXBUFFERARBPROC glTexBufferARB; __EXTERN PFNGLTEXBUFFERARBPROC glTexBufferARB;
#undef __EXTERN #undef __EXTERN
#endif

View file

@ -51,7 +51,7 @@
CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{ {
if (self < -1 || self > 2 || !(gl.flags&RFL_VBO)) if (self < -1 || self > 2)
{ {
self = 0; self = 0;
} }
@ -75,11 +75,8 @@ CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCA
FVertexBuffer::FVertexBuffer() FVertexBuffer::FVertexBuffer()
{ {
vbo_id = 0; vbo_id = 0;
if (gl.flags&RFL_VBO) if (gl_usevbo == -1) gl_usevbo.Callback();
{ glGenBuffers(1, &vbo_id);
if (gl_usevbo == -1) gl_usevbo.Callback();
glGenBuffers(1, &vbo_id);
}
} }
FVertexBuffer::~FVertexBuffer() FVertexBuffer::~FVertexBuffer()
@ -99,14 +96,7 @@ FVertexBuffer::~FVertexBuffer()
FFlatVertexBuffer::FFlatVertexBuffer() FFlatVertexBuffer::FFlatVertexBuffer()
: FVertexBuffer() : FVertexBuffer()
{ {
if (!(gl.flags&RFL_VBO)) vbo_arg = gl_usevbo;
{
vbo_arg = 0;
}
else
{
vbo_arg = gl_usevbo;
}
map = NULL; map = NULL;
} }

View file

@ -232,29 +232,26 @@ public:
FVoxelVertexBuffer::FVoxelVertexBuffer(TArray<FVoxelVertex> &verts, TArray<unsigned int> &indices) FVoxelVertexBuffer::FVoxelVertexBuffer(TArray<FVoxelVertex> &verts, TArray<unsigned int> &indices)
{ {
ibo_id = 0; ibo_id = 0;
if (gl.flags&RFL_VBO) glGenBuffers(1, &ibo_id);
{
glGenBuffers(1, &ibo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferData(GL_ARRAY_BUFFER, verts.Size() * sizeof(FVoxelVertex), &verts[0], GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, verts.Size() * sizeof(FVoxelVertex), &verts[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
if (verts.Size() > 65535) if (verts.Size() > 65535)
{
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.Size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
isint = true;
}
else
{
unsigned short *sbuffer = new unsigned short[indices.Size()];
for(unsigned i=0;i<indices.Size();i++)
{ {
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.Size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); sbuffer[i] = (unsigned short)indices[i];
isint = true;
}
else
{
unsigned short *sbuffer = new unsigned short[indices.Size()];
for(unsigned i=0;i<indices.Size();i++)
{
sbuffer[i] = (unsigned short)indices[i];
}
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.Size() * sizeof(unsigned short), sbuffer, GL_STATIC_DRAW);
delete [] sbuffer;
isint = false;
} }
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.Size() * sizeof(unsigned short), sbuffer, GL_STATIC_DRAW);
delete [] sbuffer;
isint = false;
} }
} }
@ -470,10 +467,7 @@ bool FVoxelModel::Load(const char * fn, int lumpnum, const char * buffer, int le
void FVoxelModel::MakeGLData() void FVoxelModel::MakeGLData()
{ {
if (gl.flags&RFL_VBO) mVBO = new FVoxelVertexBuffer(mVertices, mIndices);
{
mVBO = new FVoxelVertexBuffer(mVertices, mIndices);
}
} }
//=========================================================================== //===========================================================================
@ -514,16 +508,13 @@ void FVoxelModel::RenderFrame(FTexture * skin, int frame, int cm, int translatio
tex->Bind(cm, 0, translation); tex->Bind(cm, 0, translation);
gl_RenderState.Apply(); gl_RenderState.Apply();
if (gl.flags&RFL_VBO) if (mVBO == NULL) MakeGLData();
if (mVBO != NULL)
{ {
if (mVBO == NULL) MakeGLData(); mVBO->BindVBO();
if (mVBO != NULL) glDrawElements(GL_QUADS, mIndices.Size(), mVBO->IsInt()? GL_UNSIGNED_INT:GL_UNSIGNED_SHORT, 0);
{ GLRenderer->mVBO->BindVBO();
mVBO->BindVBO(); return;
glDrawElements(GL_QUADS, mIndices.Size(), mVBO->IsInt()? GL_UNSIGNED_INT:GL_UNSIGNED_SHORT, 0);
GLRenderer->mVBO->BindVBO();
return;
}
} }
glBegin(GL_QUADS); glBegin(GL_QUADS);

View file

@ -198,23 +198,16 @@ bool GLPortal::Start(bool usestencil, bool doquery)
else if (gl_noquery) doquery = false; else if (gl_noquery) doquery = false;
// If occlusion query is supported let's use it to avoid rendering portals that aren't visible // If occlusion query is supported let's use it to avoid rendering portals that aren't visible
if (doquery && gl.flags&RFL_OCCLUSION_QUERY) if (!QueryObject) glGenQueries(1, &QueryObject);
if (QueryObject)
{ {
if (!QueryObject) glGenQueries(1, &QueryObject); glBeginQuery(GL_SAMPLES_PASSED_ARB, QueryObject);
if (QueryObject)
{
glBeginQuery(GL_SAMPLES_PASSED_ARB, QueryObject);
}
else doquery = false; // some kind of error happened
} }
else doquery = false; // some kind of error happened
DrawPortalStencil(); DrawPortalStencil();
if (doquery && gl.flags&RFL_OCCLUSION_QUERY) glEndQuery(GL_SAMPLES_PASSED_ARB);
{
glEndQuery(GL_SAMPLES_PASSED_ARB);
}
// Clear Z-buffer // Clear Z-buffer
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil
@ -230,20 +223,17 @@ bool GLPortal::Start(bool usestencil, bool doquery)
glColorMask(1,1,1,1); glColorMask(1,1,1,1);
glDepthRange(0,1); glDepthRange(0,1);
if (doquery && gl.flags&RFL_OCCLUSION_QUERY) GLuint sampleCount;
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT_ARB, &sampleCount);
if (sampleCount==0) // not visible
{ {
GLuint sampleCount; // restore default stencil op.
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT_ARB, &sampleCount); glStencilFunc(GL_EQUAL,recursion,~0); // draw sky into stencil
PortalAll.Unclock();
if (sampleCount==0) // not visible return false;
{
// restore default stencil op.
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
glStencilFunc(GL_EQUAL,recursion,~0); // draw sky into stencil
PortalAll.Unclock();
return false;
}
} }
FDrawInfo::StartDrawInfo(); FDrawInfo::StartDrawInfo();
} }

View file

@ -247,13 +247,36 @@ void FGLRenderer::SetCameraPos(fixed_t viewx, fixed_t viewy, fixed_t viewz, angl
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void setPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
{
GLdouble m[4][4];
double sine, cotangent, deltaZ;
double radians = fovy / 2 * M_PI / 180;
deltaZ = zFar - zNear;
sine = sin(radians);
if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
return;
}
cotangent = cos(radians) / sine;
memset(m, 0, sizeof(m));
m[0][0] = cotangent / aspect;
m[1][1] = cotangent;
m[2][2] = -(zFar + zNear) / deltaZ;
m[2][3] = -1;
m[3][2] = -2 * zNear * zFar / deltaZ;
m[3][3] = 0;
glLoadMatrixd(&m[0][0]);
}
void FGLRenderer::SetProjection(float fov, float ratio, float fovratio) void FGLRenderer::SetProjection(float fov, float ratio, float fovratio)
{ {
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovratio)); float fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovratio));
gluPerspective(fovy, ratio, 5.f, 65536.f); setPerspective(fovy, ratio, 5.f, 65536.f);
gl_RenderState.Set2DMode(false); gl_RenderState.Set2DMode(false);
} }

View file

@ -584,39 +584,19 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
gltexture=FMaterial::ValidateTexture(patch, false); gltexture=FMaterial::ValidateTexture(patch, false);
if (!gltexture) return; if (!gltexture) return;
if (gl.flags & RFL_NPOT_TEXTURE) // trimming only works if non-power-of-2 textures are supported vt = gltexture->GetSpriteVT();
vb = gltexture->GetSpriteVB();
gltexture->GetRect(&r, GLUSE_SPRITE);
if (mirror)
{ {
vt = gltexture->GetSpriteVT(); r.left=-r.width-r.left; // mirror the sprite's x-offset
vb = gltexture->GetSpriteVB(); ul = gltexture->GetSpriteUL();
gltexture->GetRect(&r, GLUSE_SPRITE); ur = gltexture->GetSpriteUR();
if (mirror)
{
r.left=-r.width-r.left; // mirror the sprite's x-offset
ul = gltexture->GetSpriteUL();
ur = gltexture->GetSpriteUR();
}
else
{
ul = gltexture->GetSpriteUR();
ur = gltexture->GetSpriteUL();
}
} }
else else
{ {
vt = gltexture->GetVT(); ul = gltexture->GetSpriteUR();
vb = gltexture->GetVB(); ur = gltexture->GetSpriteUL();
gltexture->GetRect(&r, GLUSE_PATCH);
if (mirror)
{
r.left=-r.width-r.left; // mirror the sprite's x-offset
ul = gltexture->GetUL();
ur = gltexture->GetUR();
}
else
{
ul = gltexture->GetUR();
ur = gltexture->GetUL();
}
} }
r.Scale(FIXED2FLOAT(spritescaleX),FIXED2FLOAT(spritescaleY)); r.Scale(FIXED2FLOAT(spritescaleX),FIXED2FLOAT(spritescaleY));

View file

@ -164,7 +164,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
error << "Linking:\n" << buffer << "\n"; error << "Linking:\n" << buffer << "\n";
} }
int linked; int linked;
glGetObjectParameteriv(hShader, GL_LINK_STATUS, &linked); glGetShaderiv(hShader, GL_LINK_STATUS, &linked);
if (linked == 0) if (linked == 0)
{ {
// only print message if there's an error. // only print message if there's an error.

View file

@ -118,6 +118,11 @@ void OpenGLFrameBuffer::InitializeState()
{ {
static bool first=true; static bool first=true;
if (first)
{
glewInit();
}
gl_LoadExtensions(); gl_LoadExtensions();
Super::InitializeState(); Super::InitializeState();
if (first) if (first)
@ -128,14 +133,6 @@ void OpenGLFrameBuffer::InitializeState()
gl_PrintStartupLog(); gl_PrintStartupLog();
#endif #endif
if (gl.flags&RFL_NPOT_TEXTURE)
{
Printf("Support for non power 2 textures enabled.\n");
}
if (gl.flags&RFL_OCCLUSION_QUERY)
{
Printf("Occlusion query enabled.\n");
}
} }
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f); glClearDepth(1.0f);

View file

@ -126,7 +126,6 @@ static bool CheckExtension(const char *ext)
static void InitContext() static void InitContext()
{ {
gl.flags=0; gl.flags=0;
glBlendEquation = glBlendEquationDummy;
} }
//========================================================================== //==========================================================================
@ -143,15 +142,9 @@ void gl_LoadExtensions()
const char *version = (const char*)glGetString(GL_VERSION); const char *version = (const char*)glGetString(GL_VERSION);
// Don't even start if it's lower than 1.3 // Don't even start if it's lower than 1.3
if (strcmp(version, "1.3") < 0) if (strcmp(version, "2.0") < 0)
{ {
I_FatalError("Unsupported OpenGL version.\nAt least GL 1.3 is required to run " GAMENAME ".\n"); I_FatalError("Unsupported OpenGL version.\nAt least GL 2.0 is required to run " GAMENAME ".\n");
}
else if (strcmp(version, "1.4") < 0)
{
// The engine will still assume 1.4 but the only 1.4 feature being used is GL_GENERATE_MIPMAP which should be supported as an extension
// on most 1.3 cards this is present but let's print a warning that not everything may work as intended.
Printf(TEXTCOLOR_RED "The current graphics driver implements a OpenGL version lower than 1.4 and may not support all features " GAMENAME " requires.\n");
} }
// This loads any function pointers and flags that require a vaild render context to // This loads any function pointers and flags that require a vaild render context to
@ -160,14 +153,6 @@ void gl_LoadExtensions()
gl.shadermodel = 0; // assume no shader support gl.shadermodel = 0; // assume no shader support
gl.vendorstring=(char*)glGetString(GL_VENDOR); gl.vendorstring=(char*)glGetString(GL_VENDOR);
// First try the regular function
glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation");
// If that fails try the EXT version
if (!glBlendEquation) glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquationEXT");
// If that fails use a no-op dummy
if (!glBlendEquation) glBlendEquation = glBlendEquationDummy;
if (CheckExtension("GL_ARB_texture_non_power_of_two")) gl.flags|=RFL_NPOT_TEXTURE;
if (CheckExtension("GL_ARB_texture_compression")) gl.flags|=RFL_TEXTURE_COMPRESSION; if (CheckExtension("GL_ARB_texture_compression")) gl.flags|=RFL_TEXTURE_COMPRESSION;
if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags|=RFL_TEXTURE_COMPRESSION_S3TC; if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags|=RFL_TEXTURE_COMPRESSION_S3TC;
if (strstr(gl.vendorstring, "NVIDIA")) gl.flags|=RFL_NVIDIA; if (strstr(gl.vendorstring, "NVIDIA")) gl.flags|=RFL_NVIDIA;
@ -182,65 +167,6 @@ void gl_LoadExtensions()
if (gl.flags & RFL_GL_20) if (gl.flags & RFL_GL_20)
{ {
glDeleteShader = (PFNGLDELETESHADERPROC)myGetProcAddress("glDeleteShader");
glDeleteProgram = (PFNGLDELETEPROGRAMPROC)myGetProcAddress("glDeleteProgram");
glDetachShader = (PFNGLDETACHSHADERPROC)myGetProcAddress("glDetachShader");
glCreateShader = (PFNGLCREATESHADERPROC)myGetProcAddress("glCreateShader");
glShaderSource = (PFNGLSHADERSOURCEPROC)myGetProcAddress("glShaderSource");
glCompileShader = (PFNGLCOMPILESHADERPROC)myGetProcAddress("glCompileShader");
glCreateProgram = (PFNGLCREATEPROGRAMPROC)myGetProcAddress("glCreateProgram");
glAttachShader = (PFNGLATTACHSHADERPROC)myGetProcAddress("glAttachShader");
glLinkProgram = (PFNGLLINKPROGRAMPROC)myGetProcAddress("glLinkProgram");
glUseProgram = (PFNGLUSEPROGRAMPROC)myGetProcAddress("glUseProgram");
glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)myGetProcAddress("glValidateProgram");
glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)myGetProcAddress("glVertexAttrib1f");
glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)myGetProcAddress("glVertexAttrib2f");
glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)myGetProcAddress("glVertexAttrib4f");
glVertexAttrib2fv = (PFNGLVERTEXATTRIB4FVPROC)myGetProcAddress("glVertexAttrib2fv");
glVertexAttrib3fv = (PFNGLVERTEXATTRIB4FVPROC)myGetProcAddress("glVertexAttrib3fv");
glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)myGetProcAddress("glVertexAttrib4fv");
glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)myGetProcAddress("glVertexAttrib4ubv");
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)myGetProcAddress("glGetAttribLocation");
glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)myGetProcAddress("glBindAttribLocation");
glUniform1f = (PFNGLUNIFORM1FPROC)myGetProcAddress("glUniform1f");
glUniform2f = (PFNGLUNIFORM2FPROC)myGetProcAddress("glUniform2f");
glUniform3f = (PFNGLUNIFORM3FPROC)myGetProcAddress("glUniform3f");
glUniform4f = (PFNGLUNIFORM4FPROC)myGetProcAddress("glUniform4f");
glUniform1i = (PFNGLUNIFORM1IPROC)myGetProcAddress("glUniform1i");
glUniform2i = (PFNGLUNIFORM2IPROC)myGetProcAddress("glUniform2i");
glUniform3i = (PFNGLUNIFORM3IPROC)myGetProcAddress("glUniform3i");
glUniform4i = (PFNGLUNIFORM4IPROC)myGetProcAddress("glUniform4i");
glUniform1fv = (PFNGLUNIFORM1FVPROC)myGetProcAddress("glUniform1fv");
glUniform2fv = (PFNGLUNIFORM2FVPROC)myGetProcAddress("glUniform2fv");
glUniform3fv = (PFNGLUNIFORM3FVPROC)myGetProcAddress("glUniform3fv");
glUniform4fv = (PFNGLUNIFORM4FVPROC)myGetProcAddress("glUniform4fv");
glUniform1iv = (PFNGLUNIFORM1IVPROC)myGetProcAddress("glUniform1iv");
glUniform2iv = (PFNGLUNIFORM2IVPROC)myGetProcAddress("glUniform2iv");
glUniform3iv = (PFNGLUNIFORM3IVPROC)myGetProcAddress("glUniform3iv");
glUniform4iv = (PFNGLUNIFORM4IVPROC)myGetProcAddress("glUniform4iv");
glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)myGetProcAddress("glUniformMatrix2fv");
glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)myGetProcAddress("glUniformMatrix3fv");
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)myGetProcAddress("glUniformMatrix4fv");
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)myGetProcAddress("glGetProgramInfoLog");
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)myGetProcAddress("glGetShaderInfoLog");
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)myGetProcAddress("glGetUniformLocation");
glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)myGetProcAddress("glGetActiveUniform");
glGetUniformfv = (PFNGLGETUNIFORMFVPROC)myGetProcAddress("glGetUniformfv");
glGetUniformiv = (PFNGLGETUNIFORMIVPROC)myGetProcAddress("glGetUniformiv");
glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)myGetProcAddress("glGetShaderSource");
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)myGetProcAddress("glEnableVertexAttribArray");
glDisableVertexAttribArray= (PFNGLDISABLEVERTEXATTRIBARRAYPROC)myGetProcAddress("glDisableVertexAttribArray");
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)myGetProcAddress("glVertexAttribPointer");
// what'S the equivalent of this in GL 2.0???
glGetObjectParameteriv = (PFNGLGETOBJECTPARAMETERIVARBPROC)myGetProcAddress("glGetObjectParameterivARB");
// Rules: // Rules:
// SM4 will always use shaders. No option to switch them off is needed here. // SM4 will always use shaders. No option to switch them off is needed here.
// SM3 has shaders optional but they are off by default (they will have a performance impact // SM3 has shaders optional but they are off by default (they will have a performance impact
@ -258,78 +184,16 @@ void gl_LoadExtensions()
else if (Args->CheckParm("-sm3") && gl.shadermodel > 3) gl.shadermodel = 3; else if (Args->CheckParm("-sm3") && gl.shadermodel > 3) gl.shadermodel = 3;
} }
if (CheckExtension("GL_ARB_occlusion_query"))
{
glGenQueries = (PFNGLGENQUERIESARBPROC)myGetProcAddress("glGenQueriesARB");
glDeleteQueries = (PFNGLDELETEQUERIESARBPROC)myGetProcAddress("glDeleteQueriesARB");
glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVARBPROC)myGetProcAddress("glGetQueryObjectuivARB");
glBeginQuery = (PFNGLBEGINQUERYARBPROC)myGetProcAddress("glBeginQueryARB");
glEndQuery = (PFNGLENDQUERYPROC)myGetProcAddress("glEndQueryARB");
gl.flags|=RFL_OCCLUSION_QUERY;
}
if (gl.flags & RFL_GL_21)
{
glBindBuffer = (PFNGLBINDBUFFERPROC)myGetProcAddress("glBindBuffer");
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)myGetProcAddress("glDeleteBuffers");
glGenBuffers = (PFNGLGENBUFFERSPROC)myGetProcAddress("glGenBuffers");
glBufferData = (PFNGLBUFFERDATAPROC)myGetProcAddress("glBufferData");
glBufferSubData = (PFNGLBUFFERSUBDATAPROC)myGetProcAddress("glBufferSubData");
glMapBuffer = (PFNGLMAPBUFFERPROC)myGetProcAddress("glMapBuffer");
glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)myGetProcAddress("glUnmapBuffer");
gl.flags |= RFL_VBO;
}
else if (CheckExtension("GL_ARB_vertex_buffer_object"))
{
glBindBuffer = (PFNGLBINDBUFFERPROC)myGetProcAddress("glBindBufferARB");
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)myGetProcAddress("glDeleteBuffersARB");
glGenBuffers = (PFNGLGENBUFFERSPROC)myGetProcAddress("glGenBuffersARB");
glBufferData = (PFNGLBUFFERDATAPROC)myGetProcAddress("glBufferDataARB");
glBufferSubData = (PFNGLBUFFERSUBDATAPROC)myGetProcAddress("glBufferSubDataARB");
glMapBuffer = (PFNGLMAPBUFFERPROC)myGetProcAddress("glMapBufferARB");
glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)myGetProcAddress("glUnmapBufferARB");
gl.flags |= RFL_VBO;
}
if (CheckExtension("GL_ARB_map_buffer_range")) if (CheckExtension("GL_ARB_map_buffer_range"))
{ {
glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)myGetProcAddress("glMapBufferRange");
glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)myGetProcAddress("glFlushMappedBufferRange");
gl.flags|=RFL_MAP_BUFFER_RANGE; gl.flags|=RFL_MAP_BUFFER_RANGE;
} }
if (CheckExtension("GL_ARB_framebuffer_object")) if (gl.flags & RFL_GL_30)
{ {
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)myGetProcAddress("glGenFramebuffers");
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)myGetProcAddress("glDeleteFramebuffers");
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)myGetProcAddress("glBindFramebuffer");
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)myGetProcAddress("glFramebufferTexture2D");
glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)myGetProcAddress("glGenRenderbuffers");
glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)myGetProcAddress("glDeleteRenderbuffers");
glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)myGetProcAddress("glBindRenderbuffer");
glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)myGetProcAddress("glRenderbufferStorage");
glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)myGetProcAddress("glFramebufferRenderbuffer");
gl.flags|=RFL_FRAMEBUFFER; gl.flags|=RFL_FRAMEBUFFER;
} }
#if 0
if (CheckExtension("GL_ARB_texture_buffer_object") &&
CheckExtension("GL_ARB_texture_float") &&
CheckExtension("GL_EXT_GPU_Shader4") &&
CheckExtension("GL_ARB_texture_rg") &&
gl.shadermodel == 4)
{
glTexBufferARB = (PFNGLTEXBUFFERARBPROC)myGetProcAddress("glTexBufferARB");
gl.flags|=RFL_TEXTUREBUFFER;
}
#endif
glActiveTexture = (PFNGLACTIVETEXTUREPROC)myGetProcAddress("glActiveTextureARB");
glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC) myGetProcAddress("glMultiTexCoord2fARB");
glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC) myGetProcAddress("glMultiTexCoord2fvARB");
} }
//========================================================================== //==========================================================================
@ -347,6 +211,8 @@ void gl_PrintStartupLog()
Printf ("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS)); Printf ("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));
int v; int v;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &v);
Printf("Max. texture size: %d\n", v);
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &v); glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &v);
Printf ("Max. texture units: %d\n", v); Printf ("Max. texture units: %d\n", v);
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v); glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v);

View file

@ -5,13 +5,10 @@
enum RenderFlags enum RenderFlags
{ {
RFL_NPOT_TEXTURE=1,
RFL_OCCLUSION_QUERY=4,
// [BB] Added texture compression flags. // [BB] Added texture compression flags.
RFL_TEXTURE_COMPRESSION=8, RFL_TEXTURE_COMPRESSION=8,
RFL_TEXTURE_COMPRESSION_S3TC=16, RFL_TEXTURE_COMPRESSION_S3TC=16,
RFL_VBO = 32,
RFL_MAP_BUFFER_RANGE = 64, RFL_MAP_BUFFER_RANGE = 64,
RFL_FRAMEBUFFER = 128, RFL_FRAMEBUFFER = 128,
RFL_TEXTUREBUFFER = 256, RFL_TEXTUREBUFFER = 256,

View file

@ -67,22 +67,21 @@
#include <fcntl.h> #include <fcntl.h>
//GL headers //GL headers
#include <GL/glew.h>
#if defined(__APPLE__) #if defined(__APPLE__)
#include <GL/glew.h> #include <OpenGL/OpenGL.h>
#include <OpenGL/OpenGL.h>
#elif defined(__unix__) #elif defined(__unix__)
#include <GL/glew.h> #include <GL/glxew.h>
#include "gl/api/glext.h"
#else // !__APPLE__ && !__unix__ #else // !__APPLE__ && !__unix__
#include <GL/gl.h> #define DWORD WINDOWS_DWORD // I don't want to depend on this throughout the GL code!
#include <GL/glu.h> #include <GL/wglew.h>
#include "gl/api/glext.h" #undef DWORD
#endif #endif
#include "gl/api/gl_api.h"
#ifdef _WIN32 #ifdef _WIN32
#define DWORD WINDOWS_DWORD // I don't want to depend on this throughout the GL code! #define DWORD WINDOWS_DWORD // I don't want to depend on this throughout the GL code!
#include "gl/api/wglext.h" //#include "gl/api/wglext.h"
#ifndef __WINE__ #ifndef __WINE__
#undef DWORD #undef DWORD
#endif #endif

View file

@ -72,11 +72,7 @@ unsigned int FHardwareTexture::lastbound[FHardwareTexture::MAX_TEXTURES];
int FHardwareTexture::GetTexDimension(int value) int FHardwareTexture::GetTexDimension(int value)
{ {
if (value > gl.max_texturesize) return gl.max_texturesize; if (value > gl.max_texturesize) return gl.max_texturesize;
if (gl.flags&RFL_NPOT_TEXTURE) return value; return value;
int i=1;
while (i<value) i+=i;
return i;
} }
//=========================================================================== //===========================================================================
@ -122,12 +118,9 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (mipmap && use_mipmapping && !forcenofiltering)); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (mipmap && use_mipmapping && !forcenofiltering));
if (rw == w && rh == h) if (rw < w || rh < h)
{ {
} // The texture is larger than what the hardware can handle so scale it down.
else if (wrapparam==GL_REPEAT || rw < w || rh < h)
{
// The image must be scaled to fit the texture
unsigned char * scaledbuffer=(unsigned char *)calloc(4,rw * (rh+1)); unsigned char * scaledbuffer=(unsigned char *)calloc(4,rw * (rh+1));
if (scaledbuffer) if (scaledbuffer)
{ {
@ -136,27 +129,6 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i
buffer=scaledbuffer; buffer=scaledbuffer;
} }
} }
else
{
// The image must be copied to a larger buffer
unsigned char * scaledbuffer=(unsigned char *)calloc(4,rw * (rh+1));
if (scaledbuffer)
{
for(int y=0;y<h;y++)
{
memcpy(scaledbuffer + rw * y * 4, buffer + w * y * 4, w * 4);
// duplicate the last row to eliminate texture filtering artifacts on borders!
if (rw>w)
memcpy( scaledbuffer + rw * y * 4 + w * 4,
scaledbuffer + rw * y * 4 + w * 4 -4, 4);
}
// also duplicate the last line for the same reason!
memcpy( scaledbuffer + rw * h * 4, scaledbuffer + rw * (h-1) * 4, w*4 + 4);
deletebuffer=true;
buffer=scaledbuffer;
}
}
} }
glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

View file

@ -705,22 +705,19 @@ FMaterial::FMaterial(FTexture * tx, bool forceexpand)
mBaseLayer = ValidateSysTexture(tx, true); mBaseLayer = ValidateSysTexture(tx, true);
if (gl.flags & RFL_NPOT_TEXTURE) // trimming only works if non-power-of-2 textures are supported int trim[4];
if (TrimBorders(trim))
{ {
int trim[4]; Width[GLUSE_SPRITE] = trim[2] + 2;
Height[GLUSE_SPRITE] = trim[3] + 2;
LeftOffset[GLUSE_SPRITE] -= trim[0];
TopOffset[GLUSE_SPRITE] -= trim[1];
if (TrimBorders(trim)) SpriteU[0] = SpriteU[1] * (trim[0] / (float)Width[GLUSE_PATCH]);
{ SpriteV[0] = SpriteV[1] * (trim[1] / (float)Height[GLUSE_PATCH]);
Width[GLUSE_SPRITE] = trim[2] + 2; SpriteU[1] *= (trim[0]+trim[2]+2) / (float)Width[GLUSE_PATCH];
Height[GLUSE_SPRITE] = trim[3] + 2; SpriteV[1] *= (trim[1]+trim[3]+2) / (float)Height[GLUSE_PATCH];
LeftOffset[GLUSE_SPRITE] -= trim[0];
TopOffset[GLUSE_SPRITE] -= trim[1];
SpriteU[0] = SpriteU[1] * (trim[0] / (float)Width[GLUSE_PATCH]);
SpriteV[0] = SpriteV[1] * (trim[1] / (float)Height[GLUSE_PATCH]);
SpriteU[1] *= (trim[0]+trim[2]+2) / (float)Width[GLUSE_PATCH];
SpriteV[1] *= (trim[1]+trim[3]+2) / (float)Height[GLUSE_PATCH];
}
} }
} }
} }