#include #include #include "renderutil.hh" #include "exceptions.hh" using namespace gl; namespace render { unsigned ilog2(unsigned in) { unsigned ret = 0u; while (in >>= 1) ++ret; return ret; } std::tuple getGLTextureMaximums() { static int maxTexSize = -1, maxArrTexLayers = -1; if (maxTexSize < 0) glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); if (maxArrTexLayers < 0) glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrTexLayers); if ((maxTexSize < 0) || (maxArrTexLayers < 0)) throw Exception{"GL returned negative values for max tex. dimensions"}; return std::make_tuple(maxTexSize, maxArrTexLayers); } void useProgram(GLuint program) { static GLuint curProgram = 0; if (curProgram != program) { glUseProgram(program); curProgram = program; } } TextureResource create2DTexture(unsigned width, unsigned height, bool alpha, unsigned levels) { TextureResource tex; glGenTextures(1, &tex.get()); glBindTexture(GL_TEXTURE_2D, tex); unsigned logWidth = ilog2(width), logHeight = ilog2(height); if (levels == 0) levels = std::max(logWidth,logHeight)+1u; if(SDL_GL_ExtensionSupported("GL_ARB_texture_storage")) glTexStorage2D(GL_TEXTURE_2D, levels, alpha?GL_RGBA8:GL_RGB8, width, height); else { std::printf("Warning: extension GL_ARB_texture_storage not supported!\n"); for (unsigned i = 0u; i < levels; ++i) { glTexImage2D(GL_TEXTURE_2D, i, static_cast(alpha?GL_RGBA8:GL_RGB8), width, height, 0, alpha?GL_RGBA8:GL_RGB8, GL_UNSIGNED_BYTE, NULL); width = std::max(1u, (width / 2u)); height = std::max(1u, (height / 2u)); } } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels-1); return tex; } TextureResource create2DArrayTexture(unsigned width, unsigned height, unsigned count, bool alpha, unsigned levels) { TextureResource tex; glGenTextures(1, &tex.get()); glBindTexture(GL_TEXTURE_2D_ARRAY, tex); unsigned logWidth = ilog2(width), logHeight = ilog2(height); if (levels == 0) levels = std::max(logWidth,logHeight)+1u; if(SDL_GL_ExtensionSupported("GL_ARB_texture_storage")) glTexStorage3D(GL_TEXTURE_2D_ARRAY, levels, alpha?GL_RGBA8:GL_RGB8, width, height, count); else { std::printf("Warning: extension GL_ARB_texture_storage not supported!\n"); for (unsigned i = 0u; i < levels; ++i) { glTexImage3D(GL_TEXTURE_2D_ARRAY, i, static_cast(alpha?GL_RGBA8:GL_RGB8), width, height, count, 0, alpha?GL_RGBA8:GL_RGB8, GL_UNSIGNED_BYTE, NULL); width = std::max(1u, (width / 2u)); height = std::max(1u, (height / 2u)); } } glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, levels-1); return tex; } }