mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-12 09:06:55 -04:00
OpenGL: Try to support very old systems without BGRA support
This commit is contained in:
parent
faf2516d56
commit
f64d0807f4
@ -72,6 +72,7 @@ typedef void (*GL_SetupVBFunc)(void);
|
|||||||
typedef void (*GL_SetupVBRangeFunc)(int startVertex);
|
typedef void (*GL_SetupVBRangeFunc)(int startVertex);
|
||||||
static GL_SetupVBFunc gfx_setupVBFunc;
|
static GL_SetupVBFunc gfx_setupVBFunc;
|
||||||
static GL_SetupVBRangeFunc gfx_setupVBRangeFunc;
|
static GL_SetupVBRangeFunc gfx_setupVBRangeFunc;
|
||||||
|
static cc_bool rgba_only;
|
||||||
|
|
||||||
#include "_GLShared.h"
|
#include "_GLShared.h"
|
||||||
static void GLBackend_Init(void);
|
static void GLBackend_Init(void);
|
||||||
@ -359,6 +360,49 @@ void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Textures--------------------------------------------------------*
|
*---------------------------------------------------------Textures--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
static void ConvertRGBA(void* dst, void* src, int numPixels) {
|
||||||
|
cc_uint8* d = (cc_uint8*)dst;
|
||||||
|
cc_uint8* s = (cc_uint8*)src;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < numPixels; i++, d += 4, s += 4) {
|
||||||
|
d[0] = s[2];
|
||||||
|
d[1] = s[1];
|
||||||
|
d[2] = s[0];
|
||||||
|
d[3] = s[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CallTexSubImage2D(int lvl, int x, int y, int width, int height, void* pixels) {
|
||||||
|
void* tmp;
|
||||||
|
if (!rgba_only) {
|
||||||
|
_glTexSubImage2D(GL_TEXTURE_2D, lvl, x, y, width, height, PIXEL_FORMAT, TRANSFER_FORMAT, pixels);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = Mem_TryAlloc(width * height, 4);
|
||||||
|
if (!tmp) return;
|
||||||
|
|
||||||
|
ConvertRGBA(tmp, pixels, width * height);
|
||||||
|
_glTexSubImage2D(GL_TEXTURE_2D, lvl, x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, tmp);
|
||||||
|
Mem_Free(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CallTexImage2D(int lvl, int width, int height, void* pixels) {
|
||||||
|
void* tmp;
|
||||||
|
if (!rgba_only) {
|
||||||
|
_glTexImage2D(GL_TEXTURE_2D, lvl, GL_RGBA, width, height, 0, PIXEL_FORMAT, TRANSFER_FORMAT, pixels);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = Mem_TryAlloc(width * height, 4);
|
||||||
|
if (!tmp) return;
|
||||||
|
|
||||||
|
ConvertRGBA(tmp, pixels, width * height);
|
||||||
|
_glTexImage2D(GL_TEXTURE_2D, lvl, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp);
|
||||||
|
Mem_Free(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
void Gfx_BindTexture(GfxResourceID texId) {
|
void Gfx_BindTexture(GfxResourceID texId) {
|
||||||
_glBindTexture(GL_TEXTURE_2D, ptr_to_uint(texId));
|
_glBindTexture(GL_TEXTURE_2D, ptr_to_uint(texId));
|
||||||
}
|
}
|
||||||
@ -588,13 +632,7 @@ static void APIENTRY gl10_texImage(GLenum target, GLint level, GLint internalfor
|
|||||||
gl10_tex->height = height;
|
gl10_tex->height = height;
|
||||||
gl10_tex->pixels = Mem_Alloc(width * height, 4, "GL 1.0 pixels");
|
gl10_tex->pixels = Mem_Alloc(width * height, 4, "GL 1.0 pixels");
|
||||||
|
|
||||||
Mem_Copy(gl10_tex->pixels, pixels, width * height * 4);
|
ConvertRGBA(gl10_tex->pixels, pixels, width * height);
|
||||||
for (i = 0; i < width * height * 4; i += 4)
|
|
||||||
{
|
|
||||||
cc_uint8 t = gl10_tex->pixels[i + 2];
|
|
||||||
gl10_tex->pixels[i + 2] = gl10_tex->pixels[i + 0];
|
|
||||||
gl10_tex->pixels[i + 0] = t;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void APIENTRY gl10_texSubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
|
static void APIENTRY gl10_texSubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
|
||||||
@ -708,7 +746,9 @@ static void GLBackend_Init(void) {
|
|||||||
DynamicLib_ReqSym2("glGenBuffersARB", glGenBuffers), DynamicLib_ReqSym2("glBufferDataARB", glBufferData),
|
DynamicLib_ReqSym2("glGenBuffersARB", glGenBuffers), DynamicLib_ReqSym2("glBufferDataARB", glBufferData),
|
||||||
DynamicLib_ReqSym2("glBufferSubDataARB", glBufferSubData)
|
DynamicLib_ReqSym2("glBufferSubDataARB", glBufferSubData)
|
||||||
};
|
};
|
||||||
|
|
||||||
static const cc_string vboExt = String_FromConst("GL_ARB_vertex_buffer_object");
|
static const cc_string vboExt = String_FromConst("GL_ARB_vertex_buffer_object");
|
||||||
|
static const cc_string bgraExt = String_FromConst("GL_EXT_bgra");
|
||||||
cc_string extensions = String_FromReadonly((const char*)_glGetString(GL_EXTENSIONS));
|
cc_string extensions = String_FromReadonly((const char*)_glGetString(GL_EXTENSIONS));
|
||||||
const GLubyte* ver = _glGetString(GL_VERSION);
|
const GLubyte* ver = _glGetString(GL_VERSION);
|
||||||
|
|
||||||
@ -721,6 +761,8 @@ static void GLBackend_Init(void) {
|
|||||||
} else if (String_CaselessContains(&extensions, &vboExt)) {
|
} else if (String_CaselessContains(&extensions, &vboExt)) {
|
||||||
GLContext_GetAll(arbVboFuncs, Array_Elems(arbVboFuncs));
|
GLContext_GetAll(arbVboFuncs, Array_Elems(arbVboFuncs));
|
||||||
} else {
|
} else {
|
||||||
|
/* Some old IRIX cards don't support BGRA */
|
||||||
|
rgba_only = major == 1 && minor <= 1 && String_CaselessContains(&extensions, &bgraExt);
|
||||||
FallbackOpenGL();
|
FallbackOpenGL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,6 +441,14 @@ static void SwitchProgram(void) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Textures--------------------------------------------------------*
|
*---------------------------------------------------------Textures--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
static int CallTexSubImage2D(int lvl, int x, int y, int width, int height, void* pixels) {
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, lvl, x, y, width, height, PIXEL_FORMAT, TRANSFER_FORMAT, pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CallTexImage2D(int lvl, int width, int height, void* pixels) {
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, lvl, GL_RGBA, width, height, 0, PIXEL_FORMAT, TRANSFER_FORMAT, pixels);
|
||||||
|
}
|
||||||
|
|
||||||
void Gfx_BindTexture(GfxResourceID texId) {
|
void Gfx_BindTexture(GfxResourceID texId) {
|
||||||
/* Texture 0 has different behaviour depending on backend */
|
/* Texture 0 has different behaviour depending on backend */
|
||||||
/* Desktop OpenGL - pure white 1x1 texture */
|
/* Desktop OpenGL - pure white 1x1 texture */
|
||||||
|
@ -67,6 +67,9 @@ static void* FastAllocTempMem(int size) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Textures--------------------------------------------------------*
|
*---------------------------------------------------------Textures--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
static void CallTexSubImage2D(int lvl, int x, int y, int width, int height, void* pixels);
|
||||||
|
static void CallTexImage2D(int lvl, int width, int height, void* pixels);
|
||||||
|
|
||||||
static void Gfx_DoMipmaps(int x, int y, struct Bitmap* bmp, int rowWidth, cc_bool partial) {
|
static void Gfx_DoMipmaps(int x, int y, struct Bitmap* bmp, int rowWidth, cc_bool partial) {
|
||||||
BitmapCol* prev = bmp->scan0;
|
BitmapCol* prev = bmp->scan0;
|
||||||
BitmapCol* cur;
|
BitmapCol* cur;
|
||||||
@ -83,9 +86,9 @@ static void Gfx_DoMipmaps(int x, int y, struct Bitmap* bmp, int rowWidth, cc_boo
|
|||||||
GenMipmaps(width, height, cur, prev, rowWidth);
|
GenMipmaps(width, height, cur, prev, rowWidth);
|
||||||
|
|
||||||
if (partial) {
|
if (partial) {
|
||||||
_glTexSubImage2D(GL_TEXTURE_2D, lvl, x, y, width, height, PIXEL_FORMAT, TRANSFER_FORMAT, cur);
|
CallTexSubImage2D(lvl, x, y, width, height, cur);
|
||||||
} else {
|
} else {
|
||||||
_glTexImage2D(GL_TEXTURE_2D, lvl, GL_RGBA, width, height, 0, PIXEL_FORMAT, TRANSFER_FORMAT, cur);
|
CallTexImage2D(lvl, width, height, cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev != bmp->scan0) Mem_Free(prev);
|
if (prev != bmp->scan0) Mem_Free(prev);
|
||||||
@ -111,9 +114,9 @@ static CC_NOINLINE void UpdateTextureSlow(int x, int y, struct Bitmap* part, int
|
|||||||
part, rowWidth * BITMAPCOLOR_SIZE);
|
part, rowWidth * BITMAPCOLOR_SIZE);
|
||||||
|
|
||||||
if (full) {
|
if (full) {
|
||||||
_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, part->width, part->height, 0, PIXEL_FORMAT, TRANSFER_FORMAT, ptr);
|
CallTexImage2D(0, part->width, part->height, ptr);
|
||||||
} else {
|
} else {
|
||||||
_glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, part->width, part->height, PIXEL_FORMAT, TRANSFER_FORMAT, ptr);
|
CallTexSubImage2D(0, x, y, part->width, part->height, ptr);
|
||||||
}
|
}
|
||||||
if (count > UPDATE_FAST_SIZE) Mem_Free(ptr);
|
if (count > UPDATE_FAST_SIZE) Mem_Free(ptr);
|
||||||
}
|
}
|
||||||
@ -135,7 +138,7 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bmp->width == rowWidth) {
|
if (bmp->width == rowWidth) {
|
||||||
_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmp->width, bmp->height, 0, PIXEL_FORMAT, TRANSFER_FORMAT, bmp->scan0);
|
CallTexImage2D(0, bmp->width, bmp->height, bmp->scan0);
|
||||||
} else {
|
} else {
|
||||||
UpdateTextureSlow(0, 0, bmp, rowWidth, true);
|
UpdateTextureSlow(0, 0, bmp, rowWidth, true);
|
||||||
}
|
}
|
||||||
@ -148,7 +151,7 @@ void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, i
|
|||||||
_glBindTexture(GL_TEXTURE_2D, ptr_to_uint(texId));
|
_glBindTexture(GL_TEXTURE_2D, ptr_to_uint(texId));
|
||||||
|
|
||||||
if (part->width == rowWidth) {
|
if (part->width == rowWidth) {
|
||||||
_glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, part->width, part->height, PIXEL_FORMAT, TRANSFER_FORMAT, part->scan0);
|
CallTexSubImage2D(0, x, y, part->width, part->height, part->scan0);
|
||||||
} else {
|
} else {
|
||||||
UpdateTextureSlow(x, y, part, rowWidth, false);
|
UpdateTextureSlow(x, y, part, rowWidth, false);
|
||||||
}
|
}
|
||||||
|
@ -170,6 +170,12 @@ void GLContext_Create(void) {
|
|||||||
}
|
}
|
||||||
if (!ctx_config) Window_ShowDialog("Warning", "Failed to choose EGL config, ClassiCube may be unable to start");
|
if (!ctx_config) Window_ShowDialog("Warning", "Failed to choose EGL config, ClassiCube may be unable to start");
|
||||||
|
|
||||||
|
#if CC_WIN_BACKEND == CC_WIN_BACKEND_X11
|
||||||
|
EGLint visualID;
|
||||||
|
eglGetConfigAttrib(ctx_display, &ctx_config, EGL_NATIVE_VISUAL_ID, &visualID);
|
||||||
|
Platform_Log1("EGL visual ID: %h", &visualID);
|
||||||
|
#endif
|
||||||
|
|
||||||
ctx_context = eglCreateContext(ctx_display, ctx_config, EGL_NO_CONTEXT, context_attribs);
|
ctx_context = eglCreateContext(ctx_display, ctx_config, EGL_NO_CONTEXT, context_attribs);
|
||||||
if (!ctx_context) Process_Abort2(eglGetError(), "Failed to create EGL context");
|
if (!ctx_context) Process_Abort2(eglGetError(), "Failed to create EGL context");
|
||||||
GLContext_InitSurface();
|
GLContext_InitSurface();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user