/** * @brief Gets some information about the OpenGL window. * * @return 0 on success. */ static int gl_getGLInfo (void) { int doublebuf; SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &gl_screen.r ); SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &gl_screen.g ); SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &gl_screen.b ); SDL_GL_GetAttribute( SDL_GL_ALPHA_SIZE, &gl_screen.a ); SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &doublebuf ); SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &gl_screen.fsaa ); if (doublebuf) gl_screen.flags |= OPENGL_DOUBLEBUF; /* Calculate real depth. */ gl_screen.depth = gl_screen.r + gl_screen.g + gl_screen.b + gl_screen.a; /* Texture information */ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_screen.tex_max); glGetIntegerv(GL_MAX_TEXTURE_UNITS, &gl_screen.multitex_max); /* Debug happiness */ DEBUG("OpenGL Window Created: %dx%d@%dbpp %s", SCREEN_W, SCREEN_H, gl_screen.depth, gl_has(OPENGL_FULLSCREEN)?"fullscreen":"window"); DEBUG("r: %d, g: %d, b: %d, a: %d, db: %s, fsaa: %d, tex: %d", gl_screen.r, gl_screen.g, gl_screen.b, gl_screen.a, gl_has(OPENGL_DOUBLEBUF) ? "yes" : "no", gl_screen.fsaa, gl_screen.tex_max); DEBUG("vsync: %s, vbo: %s, mm: %s, compress: %s, npot: %s", gl_has(OPENGL_VSYNC) ? "yes" : "no", gl_vboIsHW() ? "yes" : "no", gl_texHasMipmaps() ? "yes" : "no", gl_texHasCompress() ? "yes" : "no", gl_needPOT() ? "no" : "yes" ); DEBUG("Renderer: %s", glGetString(GL_RENDERER)); DEBUG("Version: %s", glGetString(GL_VERSION)); /* Now check for things that can be bad. */ if (gl_screen.multitex_max < OPENGL_REQ_MULTITEX) WARN("Missing texture units (%d required, %d found)", OPENGL_REQ_MULTITEX, gl_screen.multitex_max ); if ((conf.fsaa > 1) && (gl_screen.fsaa != conf.fsaa)) WARN("Unable to get requested FSAA level (%d requested, got %d)", conf.fsaa, gl_screen.fsaa ); return 0; }
/** * @brief Loads a surface into an opengl texture. * * @param surface Surface to load into a texture. * @param flags Flags to use. * @param[out] rw Real width of the texture. * @param[out] rh Real height of the texture. * @return The opengl texture id. */ static GLuint gl_loadSurface( SDL_Surface* surface, int *rw, int *rh, unsigned int flags, int freesur ) { GLuint texture; GLfloat param; /* Prepare the surface. */ surface = gl_prepareSurface( surface ); if (rw != NULL) (*rw) = surface->w; if (rh != NULL) (*rh) = surface->h; /* opengl texture binding */ glGenTextures( 1, &texture ); /* Creates the texture */ glBindTexture( GL_TEXTURE_2D, texture ); /* Loads the texture */ /* 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.) || (flags & OPENGL_TEX_MIPMAPS)) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } /* 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); /* now lead the texture data up */ SDL_LockSurface( surface ); if (gl_texHasCompress()) { glTexImage2D( GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA, surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); } else { glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels ); } SDL_UnlockSurface( surface ); /* Create mipmaps. */ if ((flags & OPENGL_TEX_MIPMAPS) && gl_texHasMipmaps()) { /* Do fancy stuff. */ 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); /* Now generate the mipmaps. */ nglGenerateMipmap(GL_TEXTURE_2D); } /* cleanup */ if (freesur) SDL_FreeSurface( surface ); gl_checkErr(); return texture; }