mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-24 13:01:48 +00:00
- rewrote vertex buffer code to require GL_ARB_BUFFER_STORAGE extension.
This means it won't work anymore on anything that doesn't support OpenGL 4.0, but I don't think this is a problem. On older NVidia cards performance gains could not be seen and on older AMDs using the vertex buffer was even worse as long as it got mixed with immediate mode rendering.
This commit is contained in:
parent
b09405a8bd
commit
7d3beb665b
9 changed files with 97 additions and 132 deletions
|
@ -49,20 +49,18 @@
|
||||||
#include "gl/data/gl_vertexbuffer.h"
|
#include "gl/data/gl_vertexbuffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
const int BUFFER_SIZE = 2000000;
|
||||||
|
|
||||||
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)
|
if (self < -1 || self > 1 || !(gl.flags & RFL_BUFFER_STORAGE))
|
||||||
{
|
{
|
||||||
self = 0;
|
self = 0;
|
||||||
}
|
}
|
||||||
else if (self == -1)
|
else if (self == -1)
|
||||||
{
|
{
|
||||||
if (!(gl.flags & RFL_NVIDIA)) self = 0;
|
if (!(gl.flags & RFL_BUFFER_STORAGE)) self = 0;
|
||||||
else self = 2;
|
else self = 1;
|
||||||
}
|
|
||||||
else if (GLRenderer != NULL && GLRenderer->mVBO != NULL && GLRenderer->mVBO->vbo_arg != self)
|
|
||||||
{
|
|
||||||
Printf("Vertex buffer use will be changed for the next level.\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,13 +94,24 @@ FVertexBuffer::~FVertexBuffer()
|
||||||
FFlatVertexBuffer::FFlatVertexBuffer()
|
FFlatVertexBuffer::FFlatVertexBuffer()
|
||||||
: FVertexBuffer()
|
: FVertexBuffer()
|
||||||
{
|
{
|
||||||
vbo_arg = gl_usevbo;
|
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||||
map = NULL;
|
{
|
||||||
|
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||||
|
glBufferStorage(GL_ARRAY_BUFFER, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||||
|
map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
map = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FFlatVertexBuffer::~FFlatVertexBuffer()
|
FFlatVertexBuffer::~FFlatVertexBuffer()
|
||||||
{
|
{
|
||||||
UnmapVBO();
|
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -118,7 +127,6 @@ void FFlatVertex::SetFlatVertex(vertex_t *vt, const secplane_t & plane)
|
||||||
z = plane.ZatPoint(vt->fx, vt->fy);
|
z = plane.ZatPoint(vt->fx, vt->fy);
|
||||||
u = vt->fx/64.f;
|
u = vt->fx/64.f;
|
||||||
v = -vt->fy/64.f;
|
v = -vt->fy/64.f;
|
||||||
w = /*dc = df =*/ 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -260,58 +268,18 @@ void FFlatVertexBuffer::CreateFlatVBO()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void FFlatVertexBuffer::MapVBO()
|
|
||||||
{
|
|
||||||
if (map == NULL)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
|
||||||
map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, vbo_shadowdata.Size() * sizeof(FFlatVertex),
|
|
||||||
GL_MAP_WRITE_BIT|GL_MAP_FLUSH_EXPLICIT_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FFlatVertexBuffer::UnmapVBO()
|
|
||||||
{
|
|
||||||
if (map != NULL)
|
|
||||||
{
|
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
||||||
map = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane)
|
void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane)
|
||||||
{
|
{
|
||||||
int startvt = sec->vboindex[plane];
|
int startvt = sec->vboindex[plane];
|
||||||
int countvt = sec->vbocount[plane];
|
int countvt = sec->vbocount[plane];
|
||||||
secplane_t &splane = sec->GetSecPlane(plane);
|
secplane_t &splane = sec->GetSecPlane(plane);
|
||||||
FFlatVertex *vt = &vbo_shadowdata[startvt];
|
FFlatVertex *vt = &vbo_shadowdata[startvt];
|
||||||
|
FFlatVertex *mapvt = &map[startvt];
|
||||||
for(int i=0; i<countvt; i++, vt++)
|
for(int i=0; i<countvt; i++, vt++)
|
||||||
{
|
{
|
||||||
vt->z = splane.ZatPoint(vt->x, vt->y);
|
vt->z = splane.ZatPoint(vt->x, vt->y);
|
||||||
if (plane == sector_t::floor && sec->transdoor) vt->z -= 1;
|
if (plane == sector_t::floor && sec->transdoor) vt->z -= 1;
|
||||||
}
|
mapvt->z = vt->z;
|
||||||
if (gl.flags & RFL_MAP_BUFFER_RANGE)
|
|
||||||
{
|
|
||||||
MapVBO();
|
|
||||||
if (map == NULL) return; // Error
|
|
||||||
memcpy(&map[startvt], &vbo_shadowdata[startvt], countvt * sizeof(FFlatVertex));
|
|
||||||
glFlushMappedBufferRange(GL_ARRAY_BUFFER, startvt * sizeof(FFlatVertex), countvt * sizeof(FFlatVertex));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, startvt * sizeof(FFlatVertex), countvt * sizeof(FFlatVertex), &vbo_shadowdata[startvt]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,11 +292,10 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane)
|
||||||
void FFlatVertexBuffer::CreateVBO()
|
void FFlatVertexBuffer::CreateVBO()
|
||||||
{
|
{
|
||||||
vbo_shadowdata.Clear();
|
vbo_shadowdata.Clear();
|
||||||
if (vbo_arg > 0)
|
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||||
{
|
{
|
||||||
CreateFlatVBO();
|
CreateFlatVBO();
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex));
|
||||||
glBufferData(GL_ARRAY_BUFFER, vbo_shadowdata.Size() * sizeof(FFlatVertex), &vbo_shadowdata[0], GL_DYNAMIC_DRAW);
|
|
||||||
}
|
}
|
||||||
else if (sectors)
|
else if (sectors)
|
||||||
{
|
{
|
||||||
|
@ -350,16 +317,14 @@ void FFlatVertexBuffer::CreateVBO()
|
||||||
|
|
||||||
void FFlatVertexBuffer::BindVBO()
|
void FFlatVertexBuffer::BindVBO()
|
||||||
{
|
{
|
||||||
if (vbo_arg > 0)
|
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||||
{
|
{
|
||||||
UnmapVBO();
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
glVertexPointer(3,GL_FLOAT, sizeof(FFlatVertex), &VTO->x);
|
glVertexPointer(3,GL_FLOAT, sizeof(FFlatVertex), &VTO->x);
|
||||||
glTexCoordPointer(2,GL_FLOAT, sizeof(FFlatVertex), &VTO->u);
|
glTexCoordPointer(2,GL_FLOAT, sizeof(FFlatVertex), &VTO->u);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glDisableClientState(GL_INDEX_ARRAY);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,20 +336,23 @@ void FFlatVertexBuffer::BindVBO()
|
||||||
|
|
||||||
void FFlatVertexBuffer::CheckPlanes(sector_t *sector)
|
void FFlatVertexBuffer::CheckPlanes(sector_t *sector)
|
||||||
{
|
{
|
||||||
if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling])
|
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||||
{
|
{
|
||||||
if (sector->ceilingdata == NULL) // only update if there's no thinker attached
|
if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling])
|
||||||
{
|
{
|
||||||
UpdatePlaneVertices(sector, sector_t::ceiling);
|
//if (sector->ceilingdata == NULL) // only update if there's no thinker attached
|
||||||
sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling);
|
{
|
||||||
|
UpdatePlaneVertices(sector, sector_t::ceiling);
|
||||||
|
sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[sector_t::floor])
|
||||||
if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[sector_t::floor])
|
|
||||||
{
|
|
||||||
if (sector->floordata == NULL) // only update if there's no thinker attached
|
|
||||||
{
|
{
|
||||||
UpdatePlaneVertices(sector, sector_t::floor);
|
//if (sector->floordata == NULL) // only update if there's no thinker attached
|
||||||
sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(sector_t::floor);
|
{
|
||||||
|
UpdatePlaneVertices(sector, sector_t::floor);
|
||||||
|
sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(sector_t::floor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,10 @@ public:
|
||||||
virtual void BindVBO() = 0;
|
virtual void BindVBO() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FFlatVertex // exactly 32 bytes large
|
struct FFlatVertex
|
||||||
{
|
{
|
||||||
float x,z,y,w; // w only for padding to make one vertex 32 bytes - maybe it will find some use later
|
float x,z,y; // world position
|
||||||
float u,v; // texture coordinates
|
float u,v; // texture coordinates
|
||||||
//float dc, df; // distance to floor and ceiling on walls - used for glowing
|
|
||||||
|
|
||||||
void SetFlatVertex(vertex_t *vt, const secplane_t &plane);
|
void SetFlatVertex(vertex_t *vt, const secplane_t &plane);
|
||||||
};
|
};
|
||||||
|
@ -35,27 +34,27 @@ struct FFlatVertex // exactly 32 bytes large
|
||||||
class FFlatVertexBuffer : public FVertexBuffer
|
class FFlatVertexBuffer : public FVertexBuffer
|
||||||
{
|
{
|
||||||
FFlatVertex *map;
|
FFlatVertex *map;
|
||||||
|
unsigned int mIndex;
|
||||||
|
|
||||||
void MapVBO();
|
|
||||||
void CheckPlanes(sector_t *sector);
|
void CheckPlanes(sector_t *sector);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int vbo_arg;
|
int vbo_arg;
|
||||||
TArray<FFlatVertex> vbo_shadowdata; // this is kept around for non-VBO rendering
|
TArray<FFlatVertex> vbo_shadowdata; // this is kept around for updating the actual (non-readable) buffer
|
||||||
|
|
||||||
public:
|
|
||||||
FFlatVertexBuffer();
|
FFlatVertexBuffer();
|
||||||
~FFlatVertexBuffer();
|
~FFlatVertexBuffer();
|
||||||
|
|
||||||
|
void CreateVBO();
|
||||||
|
void BindVBO();
|
||||||
|
void CheckUpdate(sector_t *sector);
|
||||||
|
|
||||||
|
private:
|
||||||
int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor);
|
int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor);
|
||||||
int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor);
|
int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor);
|
||||||
int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor);
|
int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor);
|
||||||
void CreateFlatVBO();
|
void CreateFlatVBO();
|
||||||
void CreateVBO();
|
|
||||||
void UpdatePlaneVertices(sector_t *sec, int plane);
|
void UpdatePlaneVertices(sector_t *sec, int plane);
|
||||||
void BindVBO();
|
|
||||||
void CheckUpdate(sector_t *sector);
|
|
||||||
void UnmapVBO();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -506,25 +506,27 @@ void FVoxelModel::RenderFrame(FTexture * skin, int frame, int cm, int translatio
|
||||||
{
|
{
|
||||||
FMaterial * tex = FMaterial::ValidateTexture(skin);
|
FMaterial * tex = FMaterial::ValidateTexture(skin);
|
||||||
tex->Bind(cm, 0, translation);
|
tex->Bind(cm, 0, translation);
|
||||||
gl_RenderState.Apply();
|
|
||||||
|
|
||||||
if (mVBO == NULL) MakeGLData();
|
if (mVBO == NULL) MakeGLData();
|
||||||
if (mVBO != NULL)
|
if (mVBO != NULL)
|
||||||
{
|
{
|
||||||
mVBO->BindVBO();
|
gl_RenderState.SetVertexBuffer(mVBO);
|
||||||
glDrawElements(GL_QUADS, mIndices.Size(), mVBO->IsInt()? GL_UNSIGNED_INT:GL_UNSIGNED_SHORT, 0);
|
gl_RenderState.Apply();
|
||||||
GLRenderer->mVBO->BindVBO();
|
glDrawElements(GL_QUADS, mIndices.Size(), mVBO->IsInt() ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
|
||||||
return;
|
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
glBegin(GL_QUADS);
|
|
||||||
for(unsigned i=0;i < mIndices.Size(); i++)
|
|
||||||
{
|
{
|
||||||
FVoxelVertex *vert = &mVertices[mIndices[i]];
|
gl_RenderState.Apply();
|
||||||
glTexCoord2fv(&vert->u);
|
glBegin(GL_QUADS);
|
||||||
glVertex3fv(&vert->x);
|
for (unsigned i = 0; i < mIndices.Size(); i++)
|
||||||
|
{
|
||||||
|
FVoxelVertex *vert = &mVertices[mIndices[i]];
|
||||||
|
glTexCoord2fv(&vert->u);
|
||||||
|
glVertex3fv(&vert->x);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
}
|
}
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "gl/system/gl_system.h"
|
#include "gl/system/gl_system.h"
|
||||||
#include "gl/system/gl_interface.h"
|
#include "gl/system/gl_interface.h"
|
||||||
#include "gl/data/gl_data.h"
|
#include "gl/data/gl_data.h"
|
||||||
|
#include "gl/data/gl_vertexbuffer.h"
|
||||||
#include "gl/system/gl_cvars.h"
|
#include "gl/system/gl_cvars.h"
|
||||||
#include "gl/shaders/gl_shader.h"
|
#include "gl/shaders/gl_shader.h"
|
||||||
#include "gl/renderer/gl_renderer.h"
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
@ -79,6 +80,7 @@ void FRenderState::Reset()
|
||||||
mBlendEquation = GL_FUNC_ADD;
|
mBlendEquation = GL_FUNC_ADD;
|
||||||
glBlendEquation = -1;
|
glBlendEquation = -1;
|
||||||
m2D = true;
|
m2D = true;
|
||||||
|
mVertexBuffer = mCurrentVertexBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -300,6 +302,12 @@ void FRenderState::Apply(bool forcenoshader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mVertexBuffer != mCurrentVertexBuffer)
|
||||||
|
{
|
||||||
|
if (mVertexBuffer == NULL) glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
else mVertexBuffer->BindVBO();
|
||||||
|
mCurrentVertexBuffer = mVertexBuffer;
|
||||||
|
}
|
||||||
if (forcenoshader || !ApplyShader())
|
if (forcenoshader || !ApplyShader())
|
||||||
{
|
{
|
||||||
GLRenderer->mShaderManager->SetActiveShader(NULL);
|
GLRenderer->mShaderManager->SetActiveShader(NULL);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
|
|
||||||
|
class FVertexBuffer;
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, gl_direct_state_change)
|
EXTERN_CVAR(Bool, gl_direct_state_change)
|
||||||
|
|
||||||
struct FStateAttr
|
struct FStateAttr
|
||||||
|
@ -104,6 +106,8 @@ class FRenderState
|
||||||
int mBlendEquation;
|
int mBlendEquation;
|
||||||
bool m2D;
|
bool m2D;
|
||||||
|
|
||||||
|
FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer;
|
||||||
|
|
||||||
FStateVec3 mCameraPos;
|
FStateVec3 mCameraPos;
|
||||||
FStateVec4 mGlowTop, mGlowBottom;
|
FStateVec4 mGlowTop, mGlowBottom;
|
||||||
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
|
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
|
||||||
|
@ -140,6 +144,11 @@ public:
|
||||||
int SetupShader(bool cameratexture, int &shaderindex, int &cm, float warptime);
|
int SetupShader(bool cameratexture, int &shaderindex, int &cm, float warptime);
|
||||||
void Apply(bool forcenoshader = false);
|
void Apply(bool forcenoshader = false);
|
||||||
|
|
||||||
|
void SetVertexBuffer(FVertexBuffer *vb)
|
||||||
|
{
|
||||||
|
mVertexBuffer = vb;
|
||||||
|
}
|
||||||
|
|
||||||
void SetTextureMode(int mode)
|
void SetTextureMode(int mode)
|
||||||
{
|
{
|
||||||
mTextureMode = mode;
|
mTextureMode = mode;
|
||||||
|
|
|
@ -272,7 +272,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (vboindex >= 0)
|
if (gl_usevbo && vboindex >= 0)
|
||||||
{
|
{
|
||||||
//glColor3f( 1.f,.5f,.5f);
|
//glColor3f( 1.f,.5f,.5f);
|
||||||
int index = vboindex;
|
int index = vboindex;
|
||||||
|
|
|
@ -353,7 +353,6 @@ void FGLRenderer::CreateScene()
|
||||||
gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water
|
gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water
|
||||||
gl_drawinfo->ProcessSectorStacks(); // merge visplanes of sector stacks
|
gl_drawinfo->ProcessSectorStacks(); // merge visplanes of sector stacks
|
||||||
|
|
||||||
GLRenderer->mVBO->UnmapVBO ();
|
|
||||||
ProcessAll.Unclock();
|
ProcessAll.Unclock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -931,7 +930,7 @@ void FGLRenderer::RenderView (player_t* player)
|
||||||
LastCamera=player->camera;
|
LastCamera=player->camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
mVBO->BindVBO();
|
gl_RenderState.SetVertexBuffer(mVBO);
|
||||||
|
|
||||||
// reset statistics counters
|
// reset statistics counters
|
||||||
ResetProfilingData();
|
ResetProfilingData();
|
||||||
|
|
|
@ -155,41 +155,28 @@ void gl_LoadExtensions()
|
||||||
|
|
||||||
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 (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE;
|
||||||
else if (strstr(gl.vendorstring, "ATI Technologies")) gl.flags|=RFL_ATI;
|
|
||||||
|
|
||||||
if (strcmp(version, "2.0") >= 0) gl.flags|=RFL_GL_20;
|
gl.version = strtod((char*)glGetString(GL_VERSION), NULL);
|
||||||
if (strcmp(version, "2.1") >= 0) gl.flags|=RFL_GL_21;
|
|
||||||
if (strcmp(version, "3.0") >= 0) gl.flags|=RFL_GL_30;
|
|
||||||
|
|
||||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize);
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
if (gl.flags & RFL_GL_20)
|
// Rules:
|
||||||
{
|
// SM4 will always use shaders. No option to switch them off is needed here.
|
||||||
// Rules:
|
// SM3 has shaders optional but they are off by default (they will have a performance impact
|
||||||
// SM4 will always use shaders. No option to switch them off is needed here.
|
// SM2 only uses shaders for colormaps on camera textures and has no option to use them in general.
|
||||||
// SM3 has shaders optional but they are off by default (they will have a performance impact
|
// On SM2 cards the shaders will be too slow and show visual bugs (at least on GF 6800.)
|
||||||
// SM2 only uses shaders for colormaps on camera textures and has no option to use them in general.
|
if (strcmp((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION), "1.3") >= 0) gl.shadermodel = 4;
|
||||||
// On SM2 cards the shaders will be too slow and show visual bugs (at least on GF 6800.)
|
else if (CheckExtension("GL_NV_vertex_program3")) gl.shadermodel = 3;
|
||||||
if (strcmp((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION), "1.3") >= 0) gl.shadermodel = 4;
|
else if (!strstr(gl.vendorstring, "NVIDIA")) gl.shadermodel = 3;
|
||||||
else if (CheckExtension("GL_NV_GPU_shader4")) gl.shadermodel = 4; // for pre-3.0 drivers that support GF8xxx.
|
else gl.shadermodel = 2; // Only for older NVidia cards which had notoriously bad shader support.
|
||||||
else if (CheckExtension("GL_EXT_GPU_shader4")) gl.shadermodel = 4; // for pre-3.0 drivers that support GF8xxx.
|
|
||||||
else if (CheckExtension("GL_NV_vertex_program3")) gl.shadermodel = 3;
|
|
||||||
else if (!strstr(gl.vendorstring, "NVIDIA")) gl.shadermodel = 3;
|
|
||||||
else gl.shadermodel = 2; // Only for older NVidia cards which had notoriously bad shader support.
|
|
||||||
|
|
||||||
// Command line overrides for testing and problem cases.
|
// Command line overrides for testing and problem cases.
|
||||||
if (Args->CheckParm("-sm2") && gl.shadermodel > 2) gl.shadermodel = 2;
|
if (Args->CheckParm("-sm2") && gl.shadermodel > 2) gl.shadermodel = 2;
|
||||||
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_map_buffer_range"))
|
if (gl.version >= 3.f)
|
||||||
{
|
|
||||||
gl.flags|=RFL_MAP_BUFFER_RANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gl.flags & RFL_GL_30)
|
|
||||||
{
|
{
|
||||||
gl.flags|=RFL_FRAMEBUFFER;
|
gl.flags|=RFL_FRAMEBUFFER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,16 +9,8 @@ enum RenderFlags
|
||||||
RFL_TEXTURE_COMPRESSION=8,
|
RFL_TEXTURE_COMPRESSION=8,
|
||||||
RFL_TEXTURE_COMPRESSION_S3TC=16,
|
RFL_TEXTURE_COMPRESSION_S3TC=16,
|
||||||
|
|
||||||
RFL_MAP_BUFFER_RANGE = 64,
|
RFL_FRAMEBUFFER = 32,
|
||||||
RFL_FRAMEBUFFER = 128,
|
RFL_BUFFER_STORAGE = 64,
|
||||||
RFL_TEXTUREBUFFER = 256,
|
|
||||||
RFL_NVIDIA = 512,
|
|
||||||
RFL_ATI = 1024,
|
|
||||||
|
|
||||||
|
|
||||||
RFL_GL_20 = 0x10000000,
|
|
||||||
RFL_GL_21 = 0x20000000,
|
|
||||||
RFL_GL_30 = 0x40000000,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TexMode
|
enum TexMode
|
||||||
|
@ -40,6 +32,7 @@ struct RenderContext
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
unsigned int shadermodel;
|
unsigned int shadermodel;
|
||||||
unsigned int maxuniforms;
|
unsigned int maxuniforms;
|
||||||
|
float version;
|
||||||
int max_texturesize;
|
int max_texturesize;
|
||||||
char * vendorstring;
|
char * vendorstring;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue