Skip to content

Commit

Permalink
* Improved mipmap generation handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
bobbens committed May 16, 2009
1 parent 39f5b03 commit aaa1680
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 39 deletions.
85 changes: 65 additions & 20 deletions src/opengl_ext.c
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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.
*
Expand All @@ -97,6 +141,7 @@ int gl_initExtensions (void)
{
gl_extMultitexture();
gl_extVBO();
gl_extMipmaps();

return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions src/opengl_ext.h
Expand Up @@ -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);
Expand Down
31 changes: 12 additions & 19 deletions src/opengl_tex.c
Expand Up @@ -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);
}
Expand All @@ -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, &param);
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);
Expand All @@ -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, &param);
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 */
Expand Down

0 comments on commit aaa1680

Please sign in to comment.