int gl_support_fragment_shader = false;
//GL_ARB_vertex_buffer_object
int gl_support_arb_vertex_buffer_object = false;
+//GL_EXT_framebuffer_object
+int gl_support_ext_framebuffer_object = false;
//GL_ARB_texture_compression
int gl_support_texture_compression = false;
//GL_ARB_occlusion_query
void (GLAPIENTRY *qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
void (GLAPIENTRY *qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+//GL_EXT_framebuffer_object
+GLboolean (GLAPIENTRY *qglIsRenderbufferEXT)(GLuint renderbuffer);
+void (GLAPIENTRY *qglBindRenderbufferEXT)(GLenum target, GLuint renderbuffer);
+void (GLAPIENTRY *qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint *renderbuffers);
+void (GLAPIENTRY *qglGenRenderbuffersEXT)(GLsizei n, GLuint *renderbuffers);
+void (GLAPIENTRY *qglRenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+void (GLAPIENTRY *qglGetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint *params);
+GLboolean (GLAPIENTRY *qglIsFramebufferEXT)(GLuint framebuffer);
+void (GLAPIENTRY *qglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
+void (GLAPIENTRY *qglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
+void (GLAPIENTRY *qglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers);
+GLenum (GLAPIENTRY *qglCheckFramebufferStatusEXT)(GLenum target);
+void (GLAPIENTRY *qglFramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+void (GLAPIENTRY *qglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+void (GLAPIENTRY *qglFramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+void (GLAPIENTRY *qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+void (GLAPIENTRY *qglGetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
+void (GLAPIENTRY *qglGenerateMipmapEXT)(GLenum target);
+
void (GLAPIENTRY *qglCompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
void (GLAPIENTRY *qglCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
void (GLAPIENTRY *qglCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data);
{NULL, NULL}
};
+static dllfunction_t fbofuncs[] =
+{
+ {"glIsRenderbufferEXT" , (void **) &qglIsRenderbufferEXT},
+ {"glBindRenderbufferEXT" , (void **) &qglBindRenderbufferEXT},
+ {"glDeleteRenderbuffersEXT" , (void **) &qglDeleteRenderbuffersEXT},
+ {"glGenRenderbuffersEXT" , (void **) &qglGenRenderbuffersEXT},
+ {"glRenderbufferStorageEXT" , (void **) &qglRenderbufferStorageEXT},
+ {"glGetRenderbufferParameterivEXT" , (void **) &qglGetRenderbufferParameterivEXT},
+ {"glIsFramebufferEXT" , (void **) &qglIsFramebufferEXT},
+ {"glBindFramebufferEXT" , (void **) &qglBindFramebufferEXT},
+ {"glDeleteFramebuffersEXT" , (void **) &qglDeleteFramebuffersEXT},
+ {"glGenFramebuffersEXT" , (void **) &qglGenFramebuffersEXT},
+ {"glCheckFramebufferStatusEXT" , (void **) &qglCheckFramebufferStatusEXT},
+ {"glFramebufferTexture1DEXT" , (void **) &qglFramebufferTexture1DEXT},
+ {"glFramebufferTexture2DEXT" , (void **) &qglFramebufferTexture2DEXT},
+ {"glFramebufferTexture3DEXT" , (void **) &qglFramebufferTexture3DEXT},
+ {"glFramebufferRenderbufferEXT" , (void **) &qglFramebufferRenderbufferEXT},
+ {"glGetFramebufferAttachmentParameterivEXT" , (void **) &qglGetFramebufferAttachmentParameterivEXT},
+ {"glGenerateMipmapEXT" , (void **) &qglGenerateMipmapEXT},
+ {NULL, NULL}
+};
+
static dllfunction_t texturecompressionfuncs[] =
{
{"glCompressedTexImage3DARB", (void **) &qglCompressedTexImage3DARB},
gl_support_vertex_shader = false;
gl_support_fragment_shader = false;
gl_support_arb_vertex_buffer_object = false;
+ gl_support_ext_framebuffer_object = false;
gl_support_texture_compression = false;
gl_support_arb_occlusion_query = false;
// COMMANDLINEOPTION: GL: -novbo disables GL_ARB_vertex_buffer_object (which accelerates rendering)
gl_support_arb_vertex_buffer_object = GL_CheckExtension("GL_ARB_vertex_buffer_object", vbofuncs, "-novbo", false);
+// COMMANDLINEOPTION: GL: -nofbo disables GL_EXT_framebuffer_object (which accelerates rendering)
+ gl_support_ext_framebuffer_object = GL_CheckExtension("GL_EXT_framebuffer_object", fbofuncs, "-nofbo", false);
+
// we don't care if it's an extension or not, they are identical functions, so keep it simple in the rendering code
if (qglDrawRangeElements == NULL)
qglDrawRangeElements = qglDrawRangeElementsEXT;
Con_Printf("Initializing Video Mode: %s %dx%dx%dx%dhz%s%s\n", fullscreen ? "fullscreen" : "window", width, height, bpp, refreshrate, stereobuffer ? " stereo" : "", samples > 1 ? va(" (%ix AA)", samples) : "");
if (VID_InitMode(fullscreen, &width, &height, bpp, vid_userefreshrate.integer ? max(1, refreshrate) : 0, stereobuffer, samples))
{
- vid.fullscreen = fullscreen;
+ vid.fullscreen = fullscreen != 0;
vid.width = width;
vid.height = height;
vid.bitsperpixel = bpp;
vid.samples = samples;
vid.refreshrate = refreshrate;
- vid.stereobuffer = stereobuffer;
- vid.userefreshrate = vid_userefreshrate.integer;
+ vid.stereobuffer = stereobuffer != 0;
+ vid.userefreshrate = vid_userefreshrate.integer != 0;
Cvar_SetValueQuick(&vid_fullscreen, fullscreen);
Cvar_SetValueQuick(&vid_width, width);
Cvar_SetValueQuick(&vid_height, height);
VID_OpenSystems();
}
-int VID_SortModes_Compare(void *a_, void *b_)
+int VID_SortModes_Compare(const void *a_, const void *b_)
{
vid_mode_t *a = (vid_mode_t *) a_;
vid_mode_t *b = (vid_mode_t *) b_;
{
size_t i;
if(count == 0)
- return;
+ return 0;
// 1. sort them
qsort(modes, count, sizeof(*modes), VID_SortModes_Compare);
// 2. remove duplicates
- for(i = 1; i < count; ++i)
+ for(i = 0; i < count; ++i)
{
- if(modes[i].width != modes[i-1].width)
- continue;
- if(modes[i].height != modes[i-1].height)
- continue;
- if(userefreshrate)
- if(modes[i].refreshrate != modes[i-1].refreshrate)
+ if(modes[i].width && modes[i].height)
+ {
+ if(i == 0)
continue;
- if(usebpp)
- if(modes[i].bpp != modes[i-1].bpp)
+ if(modes[i].width != modes[i-1].width)
continue;
- if(useaspect)
- if(modes[i].pixelheight_num * modes[i-1].pixelheight_denom != modes[i].pixelheight_denom * modes[i-1].pixelheight_num)
+ if(modes[i].height != modes[i-1].height)
continue;
- // a dupe!
+ if(userefreshrate)
+ if(modes[i].refreshrate != modes[i-1].refreshrate)
+ continue;
+ if(usebpp)
+ if(modes[i].bpp != modes[i-1].bpp)
+ continue;
+ if(useaspect)
+ if(modes[i].pixelheight_num * modes[i-1].pixelheight_denom != modes[i].pixelheight_denom * modes[i-1].pixelheight_num)
+ continue;
+ }
+ // a dupe, or a bogus mode!
if(i < count-1)
memmove(&modes[i], &modes[i+1], sizeof(*modes) * (count-1 - i));
--i; // check this index again, as mode i+1 is now here