diff --git a/src/opengl_ext.c b/src/opengl_ext.c index e697496a41..94ae8ddae0 100644 --- a/src/opengl_ext.c +++ b/src/opengl_ext.c @@ -24,22 +24,48 @@ /* * Prototypes */ +static void* gl_extGetProc( const char *proc ); static int gl_extVBO (void); static int gl_extMultitexture (void); +static int gl_extMipmaps (void); +/** + * @brief Tries to load an opengl function pointer. + * + * This function will generate a warning if fails, if you want to test to see + * if it's available use SDL_GL_GetProcAddress directly. + * + * @param proc Function to find. + * @return Function pointer to proc or NULL on error. + */ +static void* gl_extGetProc( const char *proc ) +{ + void *procGL; + + procGL = SDL_GL_GetProcAddress( proc ); + if (procGL == NULL) + WARN("OpenGL function pointer to '%s' not found.", proc); + + return procGL; +} + + +/** + * @brief Tries to load the multitexture extensions. + */ static int gl_extMultitexture (void) { /* Multitexture. */ if (gl_hasVersion( 1, 3 )) { - nglActiveTexture = SDL_GL_GetProcAddress("glActiveTexture"); - nglClientActiveTexture = SDL_GL_GetProcAddress("glClientActiveTexture"); - nglMultiTexCoord2d = SDL_GL_GetProcAddress("glMultiTexCoord2d"); + nglActiveTexture = gl_extGetProc("glActiveTexture"); + nglClientActiveTexture = gl_extGetProc("glClientActiveTexture"); + nglMultiTexCoord2d = gl_extGetProc("glMultiTexCoord2d"); } else if (gl_hasExt("GL_ARB_multitexture")) { - nglActiveTexture = SDL_GL_GetProcAddress("glActiveTextureARB"); - nglClientActiveTexture = SDL_GL_GetProcAddress("glClientActiveTextureARB"); - nglMultiTexCoord2d = SDL_GL_GetProcAddress("glMultiTexCoord2dARB"); + nglActiveTexture = gl_extGetProc("glActiveTextureARB"); + nglClientActiveTexture = gl_extGetProc("glClientActiveTextureARB"); + nglMultiTexCoord2d = gl_extGetProc("glMultiTexCoord2dARB"); } else { nglActiveTexture = NULL; @@ -50,26 +76,30 @@ static int gl_extMultitexture (void) return 0; } + +/** + * @brief Loads the VBO extensions. + */ static int gl_extVBO (void) { /* Vertex Buffers. */ if (conf.vbo && gl_hasVersion( 1, 5 )) { - nglGenBuffers = SDL_GL_GetProcAddress("glGenBuffers"); - nglBindBuffer = SDL_GL_GetProcAddress("glBindBuffer"); - nglBufferData = SDL_GL_GetProcAddress("glBufferData"); - nglBufferSubData = SDL_GL_GetProcAddress("glBufferSubData"); - nglMapBuffer = SDL_GL_GetProcAddress("glMapBuffer"); - nglUnmapBuffer = SDL_GL_GetProcAddress("glUnmapBuffer"); - nglDeleteBuffers = SDL_GL_GetProcAddress("glDeleteBuffers"); + nglGenBuffers = gl_extGetProc("glGenBuffers"); + nglBindBuffer = gl_extGetProc("glBindBuffer"); + nglBufferData = gl_extGetProc("glBufferData"); + nglBufferSubData = gl_extGetProc("glBufferSubData"); + nglMapBuffer = gl_extGetProc("glMapBuffer"); + nglUnmapBuffer = gl_extGetProc("glUnmapBuffer"); + nglDeleteBuffers = gl_extGetProc("glDeleteBuffers"); } else if (conf.vbo && gl_hasExt("GL_ARB_vertex_buffer_object")) { - nglGenBuffers = SDL_GL_GetProcAddress("glGenBuffersARB"); - nglBindBuffer = SDL_GL_GetProcAddress("glBindBufferARB"); - nglBufferData = SDL_GL_GetProcAddress("glBufferDataARB"); - nglBufferSubData = SDL_GL_GetProcAddress("glBufferSubDataARB"); - nglMapBuffer = SDL_GL_GetProcAddress("glMapBufferARB"); - nglUnmapBuffer = SDL_GL_GetProcAddress("glUnmapBufferARB"); - nglDeleteBuffers = SDL_GL_GetProcAddress("glDeleteBuffersARB"); + nglGenBuffers = gl_extGetProc("glGenBuffersARB"); + nglBindBuffer = gl_extGetProc("glBindBufferARB"); + nglBufferData = gl_extGetProc("glBufferDataARB"); + nglBufferSubData = gl_extGetProc("glBufferSubDataARB"); + nglMapBuffer = gl_extGetProc("glMapBufferARB"); + nglUnmapBuffer = gl_extGetProc("glUnmapBufferARB"); + nglDeleteBuffers = gl_extGetProc("glDeleteBuffersARB"); } else { nglGenBuffers = NULL; @@ -88,6 +118,20 @@ static int gl_extVBO (void) } +/** + * @brief Tries to initialize the mipmap extension. + */ +static int gl_extMipmaps (void) +{ + nglGenerateMipmap = SDL_GL_GetProcAddress("glGenerateMipmap"); + if (nglGenerateMipmap==NULL) + nglGenerateMipmap = SDL_GL_GetProcAddress("glGenerateMipmapEXT"); + if (nglGenerateMipmap==NULL) + WARN("glGenerateMipmap not found."); + return 0; +} + + /** * @brief Initializes opengl extensions. * @@ -97,6 +141,7 @@ int gl_initExtensions (void) { gl_extMultitexture(); gl_extVBO(); + gl_extMipmaps(); return 0; } diff --git a/src/opengl_ext.h b/src/opengl_ext.h index 4e922ad32c..0f50ad7537 100644 --- a/src/opengl_ext.h +++ b/src/opengl_ext.h @@ -9,6 +9,8 @@ #include "SDL_opengl.h" +/* GL_SGIS_generate_mipmap */ +void (APIENTRY *nglGenerateMipmap)(GLenum target); /* GL_ARB_multitexture */ void (APIENTRY *nglActiveTexture)(GLenum texture); diff --git a/src/opengl_tex.c b/src/opengl_tex.c index f43ce0870a..cf4c67a24b 100644 --- a/src/opengl_tex.c +++ b/src/opengl_tex.c @@ -277,7 +277,7 @@ static GLuint gl_loadSurface( SDL_Surface* surface, int *rw, int *rh, unsigned i /* Filtering, LINEAR is better for scaling, nearest looks nicer, LINEAR * also seems to create a bit of artifacts around the edges */ - if (gl_screen.scale != 1.) { + if ((gl_screen.scale != 1.) || (flags & OPENGL_TEX_MIPMAPS)) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } @@ -286,19 +286,6 @@ static GLuint gl_loadSurface( SDL_Surface* surface, int *rw, int *rh, unsigned i glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } - /* Generate mipmaps if needed. */ - if (flags & OPENGL_TEX_MIPMAPS) { - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - if (gl_hasExt("GL_EXT_texture_filter_anisotropic")) { - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, ¶m); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, param); - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 9); - } - /* Always wrap just in case. */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -309,12 +296,18 @@ static GLuint gl_loadSurface( SDL_Surface* surface, int *rw, int *rh, unsigned i surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); SDL_UnlockSurface( surface ); - /* Disable mipmaps. */ + /* Create mipmaps. */ if (flags & OPENGL_TEX_MIPMAPS) { - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - if (gl_hasExt("GL_EXT_texture_filter_anisotropic")) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.); + glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); + if (gl_hasExt("GL_EXT_texture_filter_anisotropic")) { + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, ¶m); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, param); + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 9); + + if (nglGenerateMipmap) + nglGenerateMipmap(GL_TEXTURE_2D); } /* cleanup */