94 lines
2.8 KiB
C++
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;
|
|
}
|
|
}
|