Files
wc3re/render/renderutil.cc

94 lines
2.8 KiB
C++

#include <glbinding/gl/gl.h>
#include <SDL2/SDL.h>
#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<unsigned, unsigned> 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<unsigned, unsigned>(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<const int>(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<const int>(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;
}
}