From d006e52c78232dafdead98ba6c8a161a50d37c5c Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Fri, 20 Apr 2012 09:07:47 -0300 Subject: [PATCH] support for non power of two textures --- src/framework/graphics/glutil.h | 8 ++++-- src/framework/graphics/graphics.cpp | 7 ++++- src/framework/graphics/painterogl1.h | 2 +- src/framework/graphics/texture.cpp | 41 +++++++++++++++++++++------- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/framework/graphics/glutil.h b/src/framework/graphics/glutil.h index 5807315a..be10143a 100644 --- a/src/framework/graphics/glutil.h +++ b/src/framework/graphics/glutil.h @@ -24,19 +24,19 @@ #ifndef GLUTIL_H #define GLUTIL_H -#include #if OPENGL_ES==2 #include #elif OPENGL_ES==1 +#include #include -// define OpenGL 2.0 API just to make compile, it wont actually be used +// define OpenGL ES 2.0 API just to make compile, it wont actually be used inline void glBindFramebuffer (GLenum target, GLuint framebuffer) { } inline void glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers) { } inline void glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { } inline void glGenFramebuffers (GLsizei n, GLuint* framebuffers) { } inline void glGenerateMipmap (GLenum target) { } -inline GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target) { return GL_NONE; } +inline GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target) { return 0; } inline GLuint glCreateShader (GLenum type) { return 0; } inline void glDeleteShader (GLuint shader) { } inline void glCompileShader (GLuint shader) { } @@ -85,6 +85,8 @@ inline void glVertexAttrib3fv (GLuint indx, const GLfloat* values) { } inline void glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { } inline void glVertexAttrib4fv (GLuint indx, const GLfloat* values) { } inline void glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) { } +inline void glEnableVertexAttribArray (GLuint index) { } +inline void glDisableVertexAttribArray (GLuint index) { } #else #define GLEW_STATIC diff --git a/src/framework/graphics/graphics.cpp b/src/framework/graphics/graphics.cpp index a3748d02..35d14034 100644 --- a/src/framework/graphics/graphics.cpp +++ b/src/framework/graphics/graphics.cpp @@ -270,7 +270,12 @@ bool Graphics::canUseBilinearFiltering() bool Graphics::canUseHardwareBuffers() { -#ifndef OPENGL_ES +#if OPENGL_ES==2 + return true; +#elif OPENGL_ES==1 + // OpenGL ES 1.1 supports it but OpenGL ES 1.0 not + return false; +#else // vertex buffer objects is supported by OpenGL 1.5 if(!GLEW_ARB_vertex_buffer_object) return false; diff --git a/src/framework/graphics/painterogl1.h b/src/framework/graphics/painterogl1.h index 028f7124..1fa8a9a2 100644 --- a/src/framework/graphics/painterogl1.h +++ b/src/framework/graphics/painterogl1.h @@ -28,7 +28,7 @@ #include "painter.h" /** - * Painter using OpenGL 1.0 fixed-function rendering pipeline, + * Painter using OpenGL 1.1 fixed-function rendering pipeline, * compatible with OpenGL ES 1.0 and intended to be used on * older graphics cards. Shaders are not available * for this painter engine. diff --git a/src/framework/graphics/texture.cpp b/src/framework/graphics/texture.cpp index bed397bb..0e538189 100644 --- a/src/framework/graphics/texture.cpp +++ b/src/framework/graphics/texture.cpp @@ -45,18 +45,39 @@ Texture::~Texture() uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height) { m_size.resize(width, height); - m_transformMatrix = { 1.0f/width, 0.0f, - 0.0f, 1.0f/height }; - // gets max texture size supported by the driver - static GLint maxTexSize = -1; - if(maxTexSize == -1) - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); + // convert texture pixel data to power of two size, only required for OpenGL 1.5 or older + Size glSize; + std::vector tmp; + if(!g_graphics.canUseNonPowerOfTwoTextures()) { + int glWidth = 1; + while(glWidth < width) + glWidth = glWidth << 1; + + int glHeight = 1; + while(glHeight < height) + glHeight = glHeight << 1; + + if(m_size != glSize && pixels) { + tmp.resize(glHeight*glWidth*channels, 0); + for(int y=0; y maxTexSize || height > maxTexSize) { + if(std::max(glSize.width(), glSize.height()) > g_graphics.getMaxTextureSize()) { logError("loading texture with size ", width, "x", height, " failed, " - "the maximum size allowed by the graphics card is ", maxTexSize, "x", maxTexSize, ",", + "the maximum size allowed by the graphics card is ", g_graphics.getMaxTextureSize(), "x", g_graphics.getMaxTextureSize(), ",", "to prevent crashes the texture will be displayed as a blank texture"); //TODO: make a workaround, could be bilinear scaling the texture return 0; @@ -87,7 +108,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int } // load pixels into gl memory - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.width(), m_size.height(), 0, format, GL_UNSIGNED_BYTE, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glSize.width(), glSize.height(), 0, format, GL_UNSIGNED_BYTE, pixels); GLint texParam = GL_REPEAT; if(g_graphics.canUseClampToEdge()) @@ -104,7 +125,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int void Texture::bind() { // must reset painter texture state - //g_painter->setTexture(this); + g_painter->setTexture(this); glBindTexture(GL_TEXTURE_2D, m_textureId); }