mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-12 02:01:29 -10:00
newer OpenGL extension support add GL_ARB_texture_rectangle support for non-power-of-2 textures as interface graphics add cubemap reading and writing support to DDS loader fix bug in DDS loader that made compressed images with mipmaps use more memory than they really required add support for a default envmap named "cubemap.dds" new mission flag "$Environment Map:" to use a pre-existing envmap minor cleanup of compiler warning messages get rid of wasteful math from gr_set_proj_matrix() remove extra gr_set_*_matrix() calls from starfield.cpp as there was no longer a reason for them to be there clean up bmpman flags in reguards to cubemaps and render targets disable D3D envmap code until it can be upgraded to current level of code remove bumpmap code from OpenGL stuff (sorry but it was getting in the way, if it was more than copy-paste it would be worth keeping) replace gluPerspective() call with glFrustum() call, it's a lot less math this way and saves the extra function call
387 lines
14 KiB
C++
387 lines
14 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
|
|
/*
|
|
* $Logfile: /Freespace2/code/Graphics/GrOpenGLExtension.cpp $
|
|
* $Revision: 1.15 $
|
|
* $Date: 2006-05-13 07:29:52 $
|
|
* $Author: taylor $
|
|
*
|
|
* source for extension implementation in OpenGL
|
|
*
|
|
* $Log: not supported by cvs2svn $
|
|
* Revision 1.14 2006/03/22 18:14:52 taylor
|
|
* if -mipmap is used with -img2dds to then have compressed image also contain mipmaps
|
|
* use nicest hints for texture compression, should improve quality a little
|
|
* when reporting compressed sizes to debug log make ani size be total, not per frame
|
|
*
|
|
* Revision 1.13 2006/02/24 07:35:48 taylor
|
|
* add v-sync support for OGL (I skimmped on this a bit but will go back to do something better, "special" extension wise, at a later date)
|
|
*
|
|
* Revision 1.12 2005/12/28 22:28:44 taylor
|
|
* add support for glCompressedTexSubImage2D(), we don't use it yet but there is nothing wrong with adding it already
|
|
* better support for mipmaps and mipmap filtering
|
|
* add reg option "TextureFilter" to set bilinear or trilinear filter
|
|
* clean up bitmap_id/bitmap_handle/texture_handle madness that made things difficult to understand
|
|
* small fix for using 24-bit images on 16-bit bpp visual (untested)
|
|
*
|
|
* Revision 1.11 2005/12/08 15:10:07 taylor
|
|
* add APPLE_client_storage support to improve texture performance and reduce memory usage a tiny bit on OS X
|
|
*
|
|
* Revision 1.10 2005/11/13 06:44:18 taylor
|
|
* small bit of EFF cleanup
|
|
* add -img2dds support
|
|
* cleanup some D3D stuff (missing a lot since the old code is so unstable I couldn't get it working like I wanted)
|
|
* some minor OGL cleanup and small performance changes
|
|
* converge the various pcx_read_bitmap* functions into one
|
|
* cleanup/rename/remove some cmdline options
|
|
*
|
|
* Revision 1.9 2005/06/19 02:37:02 taylor
|
|
* general cleanup, remove some old code
|
|
* speed up gr_opengl_flip() just a tad
|
|
* inverted gamma slider fix that Sticks made to D3D
|
|
* possible fix for ATI green screens
|
|
* move opengl_check_for_errors() out of gropentnl so we can use it everywhere
|
|
* fix logged OGL info from debug builds to be a little more readable
|
|
* if an extension is found but required function is not then fail
|
|
* try to optimize glDrawRangeElements so we are not rendering more than the card is optimized for
|
|
* some 2d matrix usage checks
|
|
*
|
|
* Revision 1.8 2005/05/12 17:49:12 taylor
|
|
* use vm_malloc(), vm_free(), vm_realloc(), vm_strdup() rather than system named macros
|
|
* fixes various problems and is past time to make the switch
|
|
*
|
|
* Revision 1.7 2005/04/13 23:24:21 phreak
|
|
* Updated the message of a required extension that hasn't been found.
|
|
* It was referencing the old Glide engine.
|
|
*
|
|
* Revision 1.6 2005/02/04 23:29:31 taylor
|
|
* merge with Linux/OSX tree - p0204-3
|
|
*
|
|
* Revision 1.5 2005/01/21 08:25:14 taylor
|
|
* fill in gr_opengl_set_texture_addressing()
|
|
* add support for non-power-of-two textures for cards that have it
|
|
* temporary crash fix from multiple mipmap levels in uncompressed formats
|
|
*
|
|
* Revision 1.4 2004/10/31 21:45:13 taylor
|
|
* Linux tree merge, single array for VBOs/HTL
|
|
*
|
|
* Revision 1.3 2004/07/26 20:47:32 Kazan
|
|
* remove MCD complete
|
|
*
|
|
* Revision 1.2 2004/07/12 16:32:48 Kazan
|
|
* MCD - define _MCD_CHECK to use memory tracking
|
|
*
|
|
* Revision 1.1 2004/05/24 07:25:32 taylor
|
|
* filename case change
|
|
*
|
|
* Revision 2.3 2004/04/13 01:55:41 phreak
|
|
* put in the correct fields for the CVS comments to register
|
|
* fixed a glowmap problem that occured when rendering glowmapped and non-glowmapped ships
|
|
*
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
#include "globalincs/pstypes.h"
|
|
#include "graphics/gropengl.h"
|
|
#include "graphics/gropenglextension.h"
|
|
|
|
#include "osapi/outwnd.h"
|
|
|
|
|
|
|
|
char *OGL_extension_string;
|
|
|
|
// ogl_extension is:
|
|
// - required for game flag
|
|
// - enabled flag
|
|
// - number of extensions to check for
|
|
// - extension name(s) (max is 3 variants)
|
|
// - number of functions that extension needs/wants
|
|
// - function names that extension needs (max is 15)
|
|
|
|
// OpenGL extensions that we will want to use
|
|
ogl_extension GL_Extensions[NUM_OGL_EXTENSIONS] =
|
|
{
|
|
// allows for per vertex fog coordinate
|
|
{ 0, 0, 1, { "GL_EXT_fog_coord" }, 2, {
|
|
"glFogCoordfEXT", "glFogCoordPointerEXT" } },
|
|
|
|
// provides multiple texture units for rendering more than one texture in a single pass
|
|
// (NOTE: this was included in OpenGL 1.2.1 standard, but we still need to check for it or require > 1.2 OGL)
|
|
{ 1, 0, 1, { "GL_ARB_multitexture" } , 3, {
|
|
"glMultiTexCoord2fARB", "glActiveTextureARB", "glClientActiveTextureARB" } },
|
|
|
|
// "ADD" function for texture environment
|
|
{ 1, 0, 2, { "GL_ARB_texture_env_add", "GL_EXT_texture_env_add" }, 0, { NULL } },
|
|
|
|
// framework for using compressed textures (don't provide actual compression formats we use)
|
|
{ 0, 0, 1, { "GL_ARB_texture_compression" }, 3, {
|
|
"glCompressedTexImage2D", "glCompressedTexSubImage2D", "glGetCompressedTexImageARB" } },
|
|
|
|
// S3TC texture compression/decompression support (DXT? encoded DDS images)
|
|
{ 0, 0, 1, { "GL_EXT_texture_compression_s3tc" }, 0, { NULL } },
|
|
|
|
// allows for setting of anisotropic filter (for mipmap texture filtering)
|
|
{ 0, 0, 1, { "GL_EXT_texture_filter_anisotropic" }, 0, { NULL } },
|
|
|
|
// provides app support to control how distance is calculated in fog computations
|
|
{ 0, 0, 1, { "GL_NV_fog_distance" }, 0, { NULL } },
|
|
|
|
// specify RGB values for secondary color
|
|
{ 0, 0, 1, { "GL_EXT_secondary_color" }, 2, {
|
|
"glSecondaryColor3fvEXT", "glSecondaryColor3ubvEXT" } },
|
|
|
|
// "COMBINE" function for texture environment, these two are basically the same
|
|
{ 0, 0, 2, { "GL_ARB_texture_env_combine", "GL_EXT_texture_env_combine" }, 0, { NULL } },
|
|
|
|
// lock a vertex array buffer so that OGL can transform it just once with multiple draws
|
|
{ 0, 0, 1, { "GL_EXT_compiled_vertex_array" }, 2, {
|
|
"glLockArraysEXT", "glUnlockArraysEXT" } },
|
|
|
|
// allows for row major order matrices rather than the standard column major order
|
|
{ 1, 0, 1, { "GL_ARB_transpose_matrix" }, 2, {
|
|
"glLoadTransposeMatrixfARB", "glMultTransposeMatrixfARB" } },
|
|
|
|
// this is obsolete with OGL 1.2, which is why the function name is the standard, but we check for the orginal extension name
|
|
{ 1, 0, 1, { "GL_EXT_draw_range_elements" }, 1, {
|
|
"glDrawRangeElements" } },
|
|
|
|
// extra texture wrap repeat mode
|
|
{ 0, 0, 1, { "GL_ARB_texture_mirrored_repeat" }, 0, { NULL } },
|
|
|
|
// allows for non-power-of-two textures, but without any cost to normal functionality or usage
|
|
{ 0, 0, 1, { "GL_ARB_texture_non_power_of_two" }, 0, { NULL } },
|
|
|
|
// creates buffer objects (cached in hi-speed video card memory) for vertex data
|
|
{ 0, 0, 1, { "GL_ARB_vertex_buffer_object" }, 6, {
|
|
"glBindBufferARB", "glDeleteBuffersARB", "glGenBuffersARB", "glBufferDataARB",
|
|
"glMapBufferARB", "glUnmapBufferARB" } },
|
|
|
|
// allows pixel data to use buffer objects
|
|
{ 0, 0, 1, { "GL_ARB_pixel_buffer_object" }, 6, {
|
|
"glBindBufferARB", "glDeleteBuffersARB", "glGenBuffersARB", "glBufferDataARB",
|
|
"glMapBufferARB", "glUnmapBufferARB" } },
|
|
|
|
// Mac-only extension that allows use of system copy of texture to avoid an additional API copy
|
|
{ 0, 0, 1, { "GL_APPLE_client_storage" }, 0, { NULL } },
|
|
|
|
// make me some mipmaps!
|
|
{ 0, 0, 1, { "GL_SGIS_generate_mipmap" }, 0, { NULL } },
|
|
|
|
// framebuffer object gives us render-to-texture support, among other things
|
|
{ 0, 0, 1, { "GL_EXT_framebuffer_object" }, 15, {
|
|
"glIsRenderbufferEXT", "glBindRenderbufferEXT", "glDeleteRenderbuffersEXT", "glGenRenderbuffersEXT",
|
|
"glRenderbufferStorageEXT", "glGetRenderbufferParameterivEXT", "glIsFramebufferEXT", "glBindFramebufferEXT",
|
|
"glDeleteFramebuffersEXT", "glGenFramebuffersEXT", "glCheckFramebufferStatusEXT", "glFramebufferTexture2DEXT",
|
|
"glFramebufferRenderbufferEXT", "glGetFramebufferAttachmentParameterivEXT", "glGenerateMipmapEXT" } },
|
|
|
|
// these next three are almost exactly the same, just different stages of naming.
|
|
// allows for non-power-of-textures, but at a cost of functionality
|
|
// (NOTE: the EXT version is usually found only on the Mac)
|
|
{ 0, 0, 3, { "GL_ARB_texture_rectangle", "GL_EXT_texture_rectangle", "GL_NV_texture_rectangle" }, 0, { NULL } },
|
|
|
|
// for BGRA rather than RGBA support (it's faster in most cases)
|
|
{ 1, 0, 1, { "GL_EXT_bgra" }, 0, { NULL } },
|
|
|
|
// cube map support (for environment maps, normal maps, bump maps, etc.)
|
|
{ 0, 0, 2, { "GL_ARB_texture_cube_map", "GL_EXT_texture_cube_map" }, 0, { NULL } }
|
|
};
|
|
|
|
// ogl_funcion is:
|
|
// - function name
|
|
// - pointer for extension
|
|
|
|
// All of the OpenGL functions that the extensions need
|
|
ogl_function GL_Functions[NUM_OGL_FUNCTIONS] =
|
|
{
|
|
{ "glFogCoordfEXT", 0 },
|
|
{ "glFogCoordPointerEXT", 0 },
|
|
{ "glMultiTexCoord2fARB", 0 },
|
|
{ "glActiveTextureARB", 0 },
|
|
{ "glClientActiveTextureARB", 0 },
|
|
{ "glCompressedTexImage2D", 0 },
|
|
{ "glCompressedTexSubImage2D", 0 },
|
|
{ "glGetCompressedTexImageARB", 0 },
|
|
{ "glSecondaryColor3fvEXT", 0 },
|
|
{ "glSecondaryColor3ubvEXT", 0 },
|
|
{ "glLockArraysEXT", 0 },
|
|
{ "glUnlockArraysEXT", 0 },
|
|
{ "glLoadTransposeMatrixfARB", 0 },
|
|
{ "glMultTransposeMatrixfARB", 0 },
|
|
{ "glDrawRangeElements", 0 },
|
|
{ "glBindBufferARB", 0 },
|
|
{ "glDeleteBuffersARB", 0 },
|
|
{ "glGenBuffersARB", 0 },
|
|
{ "glBufferDataARB", 0 },
|
|
{ "glMapBufferARB", 0 },
|
|
{ "glUnmapBufferARB", 0 },
|
|
{ "glIsRenderbufferEXT", 0 },
|
|
{ "glBindRenderbufferEXT", 0 },
|
|
{ "glDeleteRenderbuffersEXT", 0 },
|
|
{ "glGenRenderbuffersEXT", 0 },
|
|
{ "glRenderbufferStorageEXT", 0 },
|
|
{ "glGetRenderbufferParameterivEXT", 0 },
|
|
{ "glIsFramebufferEXT", 0 },
|
|
{ "glBindFramebufferEXT", 0 },
|
|
{ "glDeleteFramebuffersEXT", 0 },
|
|
{ "glGenFramebuffersEXT", 0 },
|
|
{ "glCheckFramebufferStatusEXT", 0 },
|
|
{ "glFramebufferTexture2DEXT", 0 },
|
|
{ "glFramebufferRenderbufferEXT", 0 },
|
|
{ "glGetFramebufferAttachmentParameterivEXT", 0 },
|
|
{ "glGenerateMipmapEXT", 0 }
|
|
};
|
|
|
|
// special extensions (only special functions are supported at the moment)
|
|
ogl_function GL_EXT_Special[NUM_OGL_EXT_SPECIAL] = {
|
|
{ "wglSwapIntervalEXT", 0 },
|
|
{ "glXSwapIntervalSGI", 0 }
|
|
};
|
|
|
|
|
|
|
|
//tries to find a certain extension
|
|
static inline int opengl_find_extension(const char* ext_to_find)
|
|
{
|
|
return ( strstr(OGL_extension_string, ext_to_find) != NULL );
|
|
}
|
|
|
|
// these extensions may not be listed the normal way so we don't check the extension string for them
|
|
static int opengl_get_extensions_special()
|
|
{
|
|
int i, num_found = 0;
|
|
ogl_function *func = NULL;
|
|
|
|
for (i = 0; i < NUM_OGL_EXT_SPECIAL; i++) {
|
|
func = &GL_EXT_Special[i];
|
|
|
|
Assert( func->function_name != NULL );
|
|
|
|
#ifdef _WIN32
|
|
func->function_ptr = (ptr_u)wglGetProcAddress(func->function_name);
|
|
#else
|
|
func->function_ptr = (ptr_u)SDL_GL_GetProcAddress(func->function_name);
|
|
#endif
|
|
|
|
if (func->function_ptr) {
|
|
mprintf((" Found special extension function \"%s\".\n", func->function_name));
|
|
num_found++;
|
|
}
|
|
}
|
|
|
|
return num_found;
|
|
}
|
|
|
|
ogl_function *get_ogl_function( const char *name )
|
|
{
|
|
if (name == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
for (int i = 0; i < NUM_OGL_FUNCTIONS; i++) {
|
|
if ( !strcmp(GL_Functions[i].function_name, name) ) {
|
|
return &GL_Functions[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//finds OGL extension functions
|
|
//returns number found
|
|
int opengl_get_extensions()
|
|
{
|
|
OGL_extension_string = (char*)glGetString(GL_EXTENSIONS);
|
|
int i, j, k, num_found = 0;
|
|
ogl_extension *ext = NULL;
|
|
ogl_function *func = NULL;
|
|
|
|
for (i = 0; i < NUM_OGL_EXTENSIONS; i++) {
|
|
ext = &GL_Extensions[i];
|
|
k = 0;
|
|
|
|
while ( !ext->enabled && (k < ext->num_extensions) ) {
|
|
if ( opengl_find_extension(ext->extension_name[k]) ) {
|
|
// some extensions do not have functions
|
|
if (!ext->num_functions) {
|
|
mprintf((" Using extension \"%s\".\n", ext->extension_name[k]));
|
|
ext->enabled = 1;
|
|
num_found++;
|
|
goto Next;
|
|
}
|
|
|
|
// we do have functions so check any/all of them
|
|
for (j = 0; j < ext->num_functions; j++) {
|
|
func = get_ogl_function( ext->function_names[j] );
|
|
|
|
if (func == NULL)
|
|
break;
|
|
|
|
if (!func->function_ptr) {
|
|
#ifdef _WIN32
|
|
func->function_ptr = (ptr_u)wglGetProcAddress(func->function_name);
|
|
#else
|
|
func->function_ptr = (ptr_u)SDL_GL_GetProcAddress(func->function_name);
|
|
#endif
|
|
}
|
|
|
|
if (!func->function_ptr)
|
|
break;
|
|
}
|
|
|
|
if ( j != ext->num_functions ) {
|
|
mprintf((" Found extension \"%s\", but can't find the required function \"%s()\". Extension will be disabled!\n", ext->extension_name[k], ext->function_names[j]));
|
|
|
|
if (ext->required_to_run) {
|
|
#ifdef _WIN32
|
|
Error( LOCATION, "The required OpenGL extension '%s' is not fully supported by your current driver version or graphics card. You can either use the Direct3D rendering engine (non-FRED builds only) or update your video card drivers.\n\n", ext->extension_name[k] );
|
|
#else
|
|
Error( LOCATION, "The required OpenGL extension '%s' is not fully supported by your current driver version or graphics card.\n", ext->extension_name[k] );
|
|
#endif
|
|
}
|
|
} else {
|
|
mprintf((" Using extension \"%s\".\n", ext->extension_name[k]));
|
|
ext->enabled = 1;
|
|
num_found++;
|
|
}
|
|
} else {
|
|
// only report if unable to find when we have checked all available extension name variants
|
|
if ( k+1 >= ext->num_extensions ) {
|
|
mprintf((" Unable to find extension \"%s\".\n", ext->extension_name[k]));
|
|
|
|
if (ext->required_to_run) {
|
|
#ifdef _WIN32
|
|
Error( LOCATION, "The required OpenGL extension '%s' is not supported by your current driver version or graphics card. You can either use the Direct3D rendering engine (non-FRED builds only) or update your video card drivers.\n\n", ext->extension_name );
|
|
#else
|
|
Error( LOCATION, "The required OpenGL extension '%s' is not supported by your current driver version or graphics card.\n", ext->extension_name );
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
// now move the the next extension name
|
|
Next:
|
|
k++;
|
|
}
|
|
}
|
|
|
|
num_found += opengl_get_extensions_special();
|
|
|
|
mprintf(( "\n" ));
|
|
|
|
return num_found;
|
|
}
|