diff --git a/src/Builder.c b/src/Builder.c index 005e9352e..1cbbfca8c 100644 --- a/src/Builder.c +++ b/src/Builder.c @@ -102,7 +102,7 @@ static void AddVertices(BlockID block, Face face) { part->faces.count[face] += 4; } -#ifdef CC_BUILD_GL11 +#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL11 static void BuildPartVbs(struct ChunkPartInfo* info) { /* Sprites vertices are stored before chunk face sides */ int i, count, offset = info->offset + info->spriteCount; @@ -420,7 +420,7 @@ void Builder_MakeChunk(struct ChunkInfo* info) { info.occlusionFlags = (cc_uint8)ComputeOcclusion(); #endif -#ifndef CC_BUILD_GL11 +#if CC_GFX_BACKEND != CC_GFX_BACKEND_GL11 /* add an extra element to fix crashing on some GPUs */ info->vb = Gfx_CreateVb(VERTEX_FORMAT_TEXTURED, totalVerts + 1); Builder_Vertices = (struct VertexTextured*)Gfx_LockVb(info->vb, @@ -448,7 +448,7 @@ void Builder_MakeChunk(struct ChunkInfo* info) { } } -#ifdef CC_BUILD_GL11 +#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL11 cIndex = World_ChunkPack(x1 >> CHUNK_SHIFT, y1 >> CHUNK_SHIFT, z1 >> CHUNK_SHIFT); for (index = 0; index < MapRenderer_1DUsedCount; index++) { diff --git a/src/Core.h b/src/Core.h index 9394a0264..577eeacae 100644 --- a/src/Core.h +++ b/src/Core.h @@ -145,6 +145,7 @@ typedef cc_uint8 cc_bool; #define CC_GFX_BACKEND_D3D9 4 #define CC_GFX_BACKEND_D3D11 5 #define CC_GFX_BACKEND_VULKAN 6 +#define CC_GFX_BACKEND_GL11 7 #define CC_SSL_BACKEND_NONE 1 #define CC_SSL_BACKEND_BEARSSL 2 @@ -161,7 +162,7 @@ typedef cc_uint8 cc_bool; #define CC_AUD_BACKEND_OPENSLES 3 #define CC_AUD_BACKEND_NULL 4 -#define CC_GFX_BACKEND_IS_GL() (CC_GFX_BACKEND == CC_GFX_BACKEND_GL1 || CC_GFX_BACKEND == CC_GFX_BACKEND_GL2) +#define CC_GFX_BACKEND_IS_GL() (CC_GFX_BACKEND == CC_GFX_BACKEND_GL1 || CC_GFX_BACKEND == CC_GFX_BACKEND_GL2 || CC_GFX_BACKEND == CC_GFX_BACKEND_GL11) #define CC_BUILD_NETWORKING #define CC_BUILD_FREETYPE diff --git a/src/Graphics.h b/src/Graphics.h index a16bce418..d91413e3a 100644 --- a/src/Graphics.h +++ b/src/Graphics.h @@ -306,7 +306,7 @@ CC_API void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count); CC_API void Gfx_UnlockVb(GfxResourceID vb); /* TODO: How to make LockDynamicVb work with OpenGL 1.1 Builder stupidity. */ -#ifdef CC_BUILD_GL11 +#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL11 /* Special case of Gfx_Create/LockVb for building chunks in Builder.c */ GfxResourceID Gfx_CreateVb2(void* vertices, VertexFormat fmt, int count); #endif diff --git a/src/Graphics_GL1.c b/src/Graphics_GL1.c index 8b29cfe86..c7189dcd5 100644 --- a/src/Graphics_GL1.c +++ b/src/Graphics_GL1.c @@ -13,8 +13,10 @@ #endif /* The OpenGL backend is a bit of a mess, since it's really 2 backends in one: - * - OpenGL 1.1 (completely lacking GPU, fallbacks to say Windows built-in software rasteriser) * - OpenGL 1.5 or OpenGL 1.2 + GL_ARB_vertex_buffer_object (default desktop backend) + * - OpenGL 1.1 (completely lacking GPU, fallbacks to say Windows built-in software rasteriser) + + NOTE: Make sure when changing this or Graphics_GL11.c, to keep things in sync */ #include "../misc/opengl/GLCommon.h" @@ -25,27 +27,20 @@ #include "../misc/opengl/GL2Funcs.h" #endif -#if defined CC_BUILD_GL11 -static GLuint activeList; -#define gl_DYNAMICLISTID 1234567891 -static void* dynamicListData; -static cc_uint16 gl_indices[GFX_MAX_INDICES]; -#define GL_INDICES -#else #if CC_BUILD_MAXSTACK <= (64 * 1024) static cc_uint16 gl_indices[GFX_MAX_INDICES]; #define GL_INDICES #endif + /* OpenGL functions use stdcall instead of cdecl on Windows */ static void (APIENTRY *_glBindBuffer)(GLenum target, GfxResourceID buffer); /* NOTE: buffer is actually a GLuint in OpenGL */ static void (APIENTRY *_glDeleteBuffers)(GLsizei n, const GLuint *buffers); static void (APIENTRY *_glGenBuffers)(GLsizei n, GLuint *buffers); static void (APIENTRY *_glBufferData)(GLenum target, cc_uintptr size, const GLvoid* data, GLenum usage); static void (APIENTRY *_glBufferSubData)(GLenum target, cc_uintptr offset, cc_uintptr size, const GLvoid* data); -#endif -#if defined CC_BUILD_GL11_FALLBACK && !defined CC_BUILD_GL11 +#if defined CC_BUILD_GL11_FALLBACK /* Note the following about calling OpenGL functions on Windows */ /* 1) wglGetProcAddress returns a context specific address */ /* 2) dllimport functions are implemented using indirect function pointers */ @@ -102,7 +97,6 @@ void Gfx_Create(void) { /*########################################################################################################################* *-------------------------------------------------------Index buffers-----------------------------------------------------* *#########################################################################################################################*/ -#ifndef CC_BUILD_GL11 GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { #ifndef GL_INDICES cc_uint16 gl_indices[GFX_MAX_INDICES]; @@ -126,17 +120,11 @@ void Gfx_DeleteIb(GfxResourceID* ib) { _glDeleteBuffers(1, (GLuint*)&id); *ib = 0; } -#else -GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { return 0; } -void Gfx_BindIb(GfxResourceID ib) { } -void Gfx_DeleteIb(GfxResourceID* ib) { } -#endif /*########################################################################################################################* *------------------------------------------------------Vertex buffers-----------------------------------------------------* *#########################################################################################################################*/ -#ifndef CC_BUILD_GL11 static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) { GfxResourceID id = NULL; _glGenBuffers(1, (GLuint*)&id); @@ -161,60 +149,11 @@ void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) { void Gfx_UnlockVb(GfxResourceID vb) { _glBufferData(GL_ARRAY_BUFFER, tmpSize, tmpData, GL_STATIC_DRAW); } -#else -static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) { - return glGenLists(1); -} -void Gfx_BindVb(GfxResourceID vb) { activeList = ptr_to_uint(vb); } - -void Gfx_DeleteVb(GfxResourceID* vb) { - GLuint id = ptr_to_uint(*vb); - if (id) glDeleteLists(id, 1); - *vb = 0; -} - -static void UpdateDisplayList(GLuint list, void* vertices, VertexFormat fmt, int count) { - /* We need to restore client state afer building the list */ - int realFormat = gfx_format; - void* dyn_data = dynamicListData; - Gfx_SetVertexFormat(fmt); - dynamicListData = vertices; - - glNewList(list, GL_COMPILE); - gfx_setupVBFunc(); - glDrawElements(GL_TRIANGLES, ICOUNT(count), GL_UNSIGNED_SHORT, gl_indices); - glEndList(); - - Gfx_SetVertexFormat(realFormat); - dynamicListData = dyn_data; -} - -/* NOTE! Building chunk in Builder.c relies on vb being ignored */ -/* If that changes, you must fix Builder.c to properly call Gfx_LockVb */ -static VertexFormat tmpFormat; -static int tmpCount; -void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) { - tmpFormat = fmt; - tmpCount = count; - return FastAllocTempMem(count * strideSizes[fmt]); -} - -void Gfx_UnlockVb(GfxResourceID vb) { - UpdateDisplayList((GLuint)vb, tmpData, tmpFormat, tmpCount); -} - -GfxResourceID Gfx_CreateVb2(void* vertices, VertexFormat fmt, int count) { - GLuint list = glGenLists(1); - UpdateDisplayList(list, vertices, fmt, count); - return list; -} -#endif /*########################################################################################################################* *--------------------------------------------------Dynamic vertex buffers-------------------------------------------------* *#########################################################################################################################*/ -#ifndef CC_BUILD_GL11 static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) { GfxResourceID id = NULL; cc_uint32 size = maxVertices * strideSizes[fmt]; @@ -249,44 +188,14 @@ void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { _glBindBuffer(GL_ARRAY_BUFFER, vb); _glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices); } -#else -static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) { - return (GfxResourceID)Mem_TryAlloc(maxVertices, strideSizes[fmt]); -} - -void Gfx_BindDynamicVb(GfxResourceID vb) { - activeList = gl_DYNAMICLISTID; - dynamicListData = vb; -} - -void Gfx_DeleteDynamicVb(GfxResourceID* vb) { - void* addr = *vb; - if (addr) Mem_Free(addr); - *vb = 0; -} - -void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { return vb; } -void Gfx_UnlockDynamicVb(GfxResourceID vb) { Gfx_BindDynamicVb(vb); } - -void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { - Gfx_BindDynamicVb(vb); - Mem_Copy(vb, vertices, vCount * gfx_stride); -} -#endif /*########################################################################################################################* *----------------------------------------------------------Drawing--------------------------------------------------------* *#########################################################################################################################*/ -#ifdef CC_BUILD_GL11 - /* point to client side dynamic array */ - #define VB_PTR ((cc_uint8*)dynamicListData) - #define IB_PTR gl_indices -#else - /* no client side array, use vertex buffer object */ - #define VB_PTR 0 - #define IB_PTR NULL -#endif +/* no client side array, use vertex buffer object */ +#define VB_PTR 0 +#define IB_PTR NULL static void GL_SetupVbColoured(void) { _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, VB_PTR + 0); @@ -338,24 +247,15 @@ void Gfx_DrawVb_Lines(int verticesCount) { } void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex, DrawHints hints) { -#ifdef CC_BUILD_GL11 - if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; } -#endif gfx_setupVBRangeFunc(startVertex); _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR); } void Gfx_DrawVb_IndexedTris(int verticesCount) { -#ifdef CC_BUILD_GL11 - if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; } -#endif gfx_setupVBFunc(); _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR); } -#ifdef CC_BUILD_GL11 -void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { glCallList(activeList); } -#else void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED; _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, VB_PTR + offset + 0); @@ -363,7 +263,6 @@ void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { _glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, VB_PTR + offset + 16); _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, IB_PTR); } -#endif /* !CC_BUILD_GL11 */ /*########################################################################################################################* @@ -499,12 +398,6 @@ static void Gfx_RestoreState(void) { cc_bool Gfx_WarnIfNecessary(void) { cc_string renderer = String_FromReadonly((const char*)_glGetString(GL_RENDERER)); - -#ifdef CC_BUILD_GL11 - Chat_AddRaw("&cYou are using the very outdated OpenGL backend."); - Chat_AddRaw("&cAs such you may experience poor performance."); - Chat_AddRaw("&cIt is likely you need to install video card drivers."); -#endif if (String_ContainsConst(&renderer, "llvmpipe")) { Chat_AddRaw("&cSoftware rendering is being used, performance will greatly suffer."); @@ -540,10 +433,6 @@ void Gfx_GetApiInfo(cc_string* info) { /*########################################################################################################################* *-------------------------------------------------------Compatibility-----------------------------------------------------* *#########################################################################################################################*/ -#ifdef CC_BUILD_GL11 -static void GLBackend_Init(void) { MakeIndices(gl_indices, GFX_MAX_INDICES, NULL); } -#else - #ifdef CC_BUILD_GL11_FALLBACK static FP_glDrawElements _realDrawElements; static FP_glColorPointer _realColorPointer; @@ -770,4 +659,4 @@ static void GLBackend_Init(void) { #endif } #endif -#endif + diff --git a/src/Graphics_GL11.c b/src/Graphics_GL11.c new file mode 100644 index 000000000..24d2114a5 --- /dev/null +++ b/src/Graphics_GL11.c @@ -0,0 +1,342 @@ +#include "Core.h" +#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL11 +#include "_GraphicsBase.h" +#include "Errors.h" +#include "Window.h" + +/* + This is the OpenGL 1.1 specific backend, that uses display lists for static geometry. + Although the normal OpenGL can fallback to a 1.1 mode, it uses client side vertex arrays. + So this backend may potentially be faster on a small number of old GPUs. + + NOTE: Make sure when changing this or Graphics_GL1.c, to keep things in sync +*/ +#include "../misc/opengl/GLCommon.h" + +/* e.g. GLAPI void APIENTRY glFunction(int value); */ +#define GL_FUNC(retType, name, args) GLAPI retType APIENTRY name args; +#include "../misc/opengl/GL1Funcs.h" + +static GLuint activeList; +#define gl_DYNAMICLISTID 1234567891 +static void* dynamicListData; +static cc_uint16 gl_indices[GFX_MAX_INDICES]; + +#include "../misc/opengl/GL1Macros.h" +#include "_GLShared.h" + +typedef void (*GL_SetupVBFunc)(void); +typedef void (*GL_SetupVBRangeFunc)(int startVertex); +static GL_SetupVBFunc gfx_setupVBFunc; +static GL_SetupVBRangeFunc gfx_setupVBRangeFunc; + +void Gfx_Create(void) { + GLContext_Create(); + customMipmapsLevels = true; + Gfx.BackendType = CC_GFX_BACKEND_GL1; + + GL_InitCommon(); + MakeIndices(gl_indices, GFX_MAX_INDICES, NULL); + Gfx_RestoreState(); + GLContext_SetVSync(gfx_vsync); +} + + +/*########################################################################################################################* +*-------------------------------------------------------Index buffers-----------------------------------------------------* +*#########################################################################################################################*/ +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { return 0; } +void Gfx_BindIb(GfxResourceID ib) { } +void Gfx_DeleteIb(GfxResourceID* ib) { } + + +/*########################################################################################################################* +*------------------------------------------------------Vertex buffers-----------------------------------------------------* +*#########################################################################################################################*/ +static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) { + return uint_to_ptr(glGenLists(1)); +} + +void Gfx_BindVb(GfxResourceID vb) { + activeList = ptr_to_uint(vb); +} + +void Gfx_DeleteVb(GfxResourceID* vb) { + GLuint id = ptr_to_uint(*vb); + if (id) glDeleteLists(id, 1); + *vb = 0; +} + +static void UpdateDisplayList(GLuint list, void* vertices, VertexFormat fmt, int count) { + /* We need to restore client state afer building the list */ + int realFormat = gfx_format; + void* dyn_data = dynamicListData; + Gfx_SetVertexFormat(fmt); + dynamicListData = vertices; + + glNewList(list, GL_COMPILE); + gfx_setupVBFunc(); + glDrawElements(GL_TRIANGLES, ICOUNT(count), GL_UNSIGNED_SHORT, gl_indices); + glEndList(); + + Gfx_SetVertexFormat(realFormat); + dynamicListData = dyn_data; +} + +/* NOTE! Building chunk in Builder.c relies on vb being ignored */ +/* If that changes, you must fix Builder.c to properly call Gfx_LockVb */ +static VertexFormat tmpFormat; +static int tmpCount; +void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) { + tmpFormat = fmt; + tmpCount = count; + return FastAllocTempMem(count * strideSizes[fmt]); +} + +void Gfx_UnlockVb(GfxResourceID vb) { + UpdateDisplayList(ptr_to_uint(vb), tmpData, tmpFormat, tmpCount); +} + +GfxResourceID Gfx_CreateVb2(void* vertices, VertexFormat fmt, int count) { + GLuint list = glGenLists(1); + UpdateDisplayList(list, vertices, fmt, count); + return uint_to_ptr(list); +} + + +/*########################################################################################################################* +*--------------------------------------------------Dynamic vertex buffers-------------------------------------------------* +*#########################################################################################################################*/ +static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) { + return (GfxResourceID)Mem_TryAlloc(maxVertices, strideSizes[fmt]); +} + +void Gfx_BindDynamicVb(GfxResourceID vb) { + activeList = gl_DYNAMICLISTID; + dynamicListData = vb; +} + +void Gfx_DeleteDynamicVb(GfxResourceID* vb) { + void* addr = *vb; + if (addr) Mem_Free(addr); + *vb = 0; +} + +void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { return vb; } +void Gfx_UnlockDynamicVb(GfxResourceID vb) { Gfx_BindDynamicVb(vb); } + +void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { + Gfx_BindDynamicVb(vb); + Mem_Copy(vb, vertices, vCount * gfx_stride); +} + + +/*########################################################################################################################* +*----------------------------------------------------------Drawing--------------------------------------------------------* +*#########################################################################################################################*/ +#define VB_PTR ((cc_uint8*)dynamicListData) + +static void GL_SetupVbColoured(void) { + _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, (GLpointer)(VB_PTR + 0)); + _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_COLOURED, (GLpointer)(VB_PTR + 12)); +} + +static void GL_SetupVbTextured(void) { + _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (GLpointer)(VB_PTR + 0)); + _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (GLpointer)(VB_PTR + 12)); + _glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (GLpointer)(VB_PTR + 16)); +} + +static void GL_SetupVbColoured_Range(int startVertex) { + cc_uint32 offset = startVertex * SIZEOF_VERTEX_COLOURED; + _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_COLOURED, (GLpointer)(VB_PTR + offset + 0)); + _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_COLOURED, (GLpointer)(VB_PTR + offset + 12)); +} + +static void GL_SetupVbTextured_Range(int startVertex) { + cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED; + _glVertexPointer(3, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (GLpointer)(VB_PTR + offset + 0)); + _glColorPointer(4, GL_UNSIGNED_BYTE, SIZEOF_VERTEX_TEXTURED, (GLpointer)(VB_PTR + offset + 12)); + _glTexCoordPointer(2, GL_FLOAT, SIZEOF_VERTEX_TEXTURED, (GLpointer)(VB_PTR + offset + 16)); +} + +void Gfx_SetVertexFormat(VertexFormat fmt) { + if (fmt == gfx_format) return; + gfx_format = fmt; + gfx_stride = strideSizes[fmt]; + + if (fmt == VERTEX_FORMAT_TEXTURED) { + _glEnableClientState(GL_TEXTURE_COORD_ARRAY); + _glEnable(GL_TEXTURE_2D); + + gfx_setupVBFunc = GL_SetupVbTextured; + gfx_setupVBRangeFunc = GL_SetupVbTextured_Range; + } else { + _glDisableClientState(GL_TEXTURE_COORD_ARRAY); + _glDisable(GL_TEXTURE_2D); + + gfx_setupVBFunc = GL_SetupVbColoured; + gfx_setupVBRangeFunc = GL_SetupVbColoured_Range; + } +} + +void Gfx_DrawVb_Lines(int verticesCount) { + gfx_setupVBFunc(); + _glDrawArrays(GL_LINES, 0, verticesCount); +} + +void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex, DrawHints hints) { + if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; } + + gfx_setupVBRangeFunc(startVertex); + _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, gl_indices); +} + +void Gfx_DrawVb_IndexedTris(int verticesCount) { + if (activeList != gl_DYNAMICLISTID) { glCallList(activeList); return; } + + gfx_setupVBFunc(); + _glDrawElements(GL_TRIANGLES, ICOUNT(verticesCount), GL_UNSIGNED_SHORT, gl_indices); +} + +void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { + glCallList(activeList); +} + + +/*########################################################################################################################* +*---------------------------------------------------------Textures--------------------------------------------------------* +*#########################################################################################################################*/ +void Gfx_BindTexture(GfxResourceID texId) { + _glBindTexture(GL_TEXTURE_2D, ptr_to_uint(texId)); +} + + +/*########################################################################################################################* +*-----------------------------------------------------State management----------------------------------------------------* +*#########################################################################################################################*/ +static PackedCol gfx_fogColor; +static float gfx_fogEnd, gfx_fogDensity; +static int gfx_fogMode; + +void Gfx_SetFog(cc_bool enabled) { + gfx_fogEnabled = enabled; + if (enabled) { _glEnable(GL_FOG); } else { _glDisable(GL_FOG); } +} + +void Gfx_SetFogCol(PackedCol color) { + float rgba[4]; + if (color == gfx_fogColor) return; + + rgba[0] = PackedCol_R(color) / 255.0f; + rgba[1] = PackedCol_G(color) / 255.0f; + rgba[2] = PackedCol_B(color) / 255.0f; + rgba[3] = PackedCol_A(color) / 255.0f; + + _glFogfv(GL_FOG_COLOR, rgba); + gfx_fogColor = color; +} + +void Gfx_SetFogDensity(float value) { + if (value == gfx_fogDensity) return; + _glFogf(GL_FOG_DENSITY, value); + gfx_fogDensity = value; +} + +void Gfx_SetFogEnd(float value) { + if (value == gfx_fogEnd) return; + _glFogf(GL_FOG_END, value); + gfx_fogEnd = value; +} + +void Gfx_SetFogMode(FogFunc func) { + static GLint modes[3] = { GL_LINEAR, GL_EXP, GL_EXP2 }; + if (func == gfx_fogMode) return; + + _glFogi(GL_FOG_MODE, modes[func]); + gfx_fogMode = func; +} + +static void SetAlphaTest(cc_bool enabled) { + if (enabled) { _glEnable(GL_ALPHA_TEST); } else { _glDisable(GL_ALPHA_TEST); } +} + +void Gfx_DepthOnlyRendering(cc_bool depthOnly) { + cc_bool enabled = !depthOnly; + SetColorWrite(enabled & gfx_colorMask[0], enabled & gfx_colorMask[1], + enabled & gfx_colorMask[2], enabled & gfx_colorMask[3]); + + if (enabled) { _glEnable(GL_TEXTURE_2D); } else { _glDisable(GL_TEXTURE_2D); } +} + + +/*########################################################################################################################* +*---------------------------------------------------------Matrices--------------------------------------------------------* +*#########################################################################################################################*/ +static GLenum matrix_modes[] = { GL_PROJECTION, GL_MODELVIEW, GL_TEXTURE }; +static int lastMatrix; + +void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) { + if (type != lastMatrix) { lastMatrix = type; _glMatrixMode(matrix_modes[type]); } + + if (matrix == &Matrix_Identity) { + _glLoadIdentity(); + } else { + _glLoadMatrixf((const float*)matrix); + } +} + +void Gfx_LoadMVP(const struct Matrix* view, const struct Matrix* proj, struct Matrix* mvp) { + Gfx_LoadMatrix(MATRIX_VIEW, view); + Gfx_LoadMatrix(MATRIX_PROJ, proj); + Matrix_Mul(mvp, view, proj); +} + +static struct Matrix texMatrix = Matrix_IdentityValue; +void Gfx_EnableTextureOffset(float x, float y) { + texMatrix.row4.x = x; texMatrix.row4.y = y; + Gfx_LoadMatrix(2, &texMatrix); +} + +void Gfx_DisableTextureOffset(void) { Gfx_LoadMatrix(2, &Matrix_Identity); } + + +/*########################################################################################################################* +*-------------------------------------------------------State setup-------------------------------------------------------* +*#########################################################################################################################*/ +static void Gfx_FreeState(void) { FreeDefaultResources(); } +static void Gfx_RestoreState(void) { + InitDefaultResources(); + _glEnableClientState(GL_VERTEX_ARRAY); + _glEnableClientState(GL_COLOR_ARRAY); + + gfx_format = -1; + lastMatrix = -1; + + gfx_clearColor = 0; + gfx_fogColor = 0; + gfx_fogEnd = -1.0f; + gfx_fogDensity = -1.0f; + gfx_fogMode = -1; + + _glAlphaFunc(GL_GREATER, 0.5f); + _glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + _glDepthFunc(GL_LEQUAL); +} + +cc_bool Gfx_WarnIfNecessary(void) { + Chat_AddRaw("&cYou are using the very outdated OpenGL backend."); + Chat_AddRaw("&cAs such you may experience poor performance."); + Chat_AddRaw("&cIt is likely you need to install video card drivers."); + return false; +} + +cc_bool Gfx_GetUIOptions(struct MenuOptionsScreen* s) { return false; } + +void Gfx_GetApiInfo(cc_string* info) { + int pointerSize = sizeof(void*) * 8; + + String_Format1(info, "-- Using OpenGL (%i bit) --\n", &pointerSize); + GetGLApiInfo(info); +} +#endif diff --git a/src/MapRenderer.c b/src/MapRenderer.c index 992563bbd..79b92003f 100644 --- a/src/MapRenderer.c +++ b/src/MapRenderer.c @@ -50,7 +50,7 @@ static int chunksCount; static void ChunkInfo_Init(struct ChunkInfo* chunk, int x, int y, int z) { chunk->centreX = x + HALF_CHUNK_SIZE; chunk->centreY = y + HALF_CHUNK_SIZE; chunk->centreZ = z + HALF_CHUNK_SIZE; -#ifndef CC_BUILD_GL11 +#if CC_GFX_BACKEND != CC_GFX_BACKEND_GL11 chunk->vb = 0; #endif @@ -106,12 +106,12 @@ static void CheckWeather(float delta) { Gfx_SetAlphaBlending(false); } -#ifdef CC_BUILD_GL11 -#define DrawFace(face, ign) Gfx_BindVb(part.vbs[face]); Gfx_DrawIndexedTris_T2fC4b(0, 0); -#define DrawFaces(f1, f2, ign) DrawFace(f1, ign); DrawFace(f2, ign); +#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL11 + #define DrawFace(face, ign) Gfx_BindVb(part.vbs[face]); Gfx_DrawIndexedTris_T2fC4b(0, 0); + #define DrawFaces(f1, f2, ign) DrawFace(f1, ign); DrawFace(f2, ign); #else -#define DrawFace(face, offset) Gfx_DrawIndexedTris_T2fC4b(part.counts[face], offset); -#define DrawFaces(f1, f2, offset) Gfx_DrawIndexedTris_T2fC4b(part.counts[f1] + part.counts[f2], offset); + #define DrawFace(face, offset) Gfx_DrawIndexedTris_T2fC4b(part.counts[face], offset); + #define DrawFaces(f1, f2, offset) Gfx_DrawIndexedTris_T2fC4b(part.counts[f1] + part.counts[f2], offset); #endif #define DrawNormalFaces(minFace, maxFace) \ @@ -143,7 +143,7 @@ static void RenderNormalBatch(int batch) { if (part.offset < 0) continue; hasNormParts[batch] = true; -#ifndef CC_BUILD_GL11 +#if CC_GFX_BACKEND != CC_GFX_BACKEND_GL11 Gfx_BindVb_Textured(info->vb); #endif @@ -168,7 +168,7 @@ static void RenderNormalBatch(int batch) { Gfx_SetFaceCulling(true); /* TODO: fix to not render them all */ -#ifdef CC_BUILD_GL11 +#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL11 Gfx_BindVb(part.vbs[FACE_COUNT]); Gfx_DrawIndexedTris_T2fC4b(0, 0); Game_Vertices += count * 4; @@ -247,7 +247,7 @@ static void RenderTranslucentBatch(int batch) { if (part.offset < 0) continue; hasTranParts[batch] = true; -#ifndef CC_BUILD_GL11 +#if CC_GFX_BACKEND != CC_GFX_BACKEND_GL11 Gfx_BindVb_Textured(info->vb); #endif @@ -322,7 +322,7 @@ void MapRenderer_RenderTranslucent(float delta) { static void DeleteChunk(struct ChunkInfo* info) { struct ChunkPartInfo* ptr; int i; -#ifdef CC_BUILD_GL11 +#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL11 int j; #else Gfx_DeleteVb(&info->vb); @@ -343,7 +343,7 @@ static void DeleteChunk(struct ChunkInfo* info) { for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += chunksCount) { if (ptr->offset < 0) continue; normPartsCount[i]--; -#ifdef CC_BUILD_GL11 +#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL11 for (j = 0; j < CHUNKPART_MAX_VBS; j++) Gfx_DeleteVb(&ptr->vbs[j]); #endif } @@ -355,7 +355,7 @@ static void DeleteChunk(struct ChunkInfo* info) { for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += chunksCount) { if (ptr->offset < 0) continue; tranPartsCount[i]--; -#ifdef CC_BUILD_GL11 +#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL11 for (j = 0; j < CHUNKPART_MAX_VBS; j++) Gfx_DeleteVb(&ptr->vbs[j]); #endif } diff --git a/src/MapRenderer.h b/src/MapRenderer.h index 69d4b8110..1d8546aa1 100644 --- a/src/MapRenderer.h +++ b/src/MapRenderer.h @@ -22,7 +22,7 @@ extern struct ChunkPartInfo* MapRenderer_PartsTranslucent; /* Describes a portion of the data needed for rendering a chunk. */ struct ChunkPartInfo { -#ifdef CC_BUILD_GL11 +#if CC_GFX_BACKEND == CC_GFX_BACKEND_GL11 /* 1 VB per face, another VB for sprites */ #define CHUNKPART_MAX_VBS (FACE_COUNT + 1) GfxResourceID vbs[CHUNKPART_MAX_VBS]; @@ -54,7 +54,7 @@ struct ChunkInfo { public cc_bool Visited = false, Occluded = false; public byte OcclusionFlags, OccludedFlags, DistanceFlags; #endif -#ifndef CC_BUILD_GL11 +#if CC_GFX_BACKEND != CC_GFX_BACKEND_GL11 GfxResourceID vb; #endif struct ChunkPartInfo* normalParts;