mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 23:12:24 +00:00
- 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:
parent
d74f045004
commit
69af73d9b9
14 changed files with 137 additions and 328 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue