Cleanup OpenGL texture for optimal performance: using GL4 glTexStorage2D

with RGBA8 (most efficient implementation in hardware).
This commit is contained in:
brunoherbelin
2020-07-30 00:13:46 +02:00
parent 4f17620cae
commit 4f3114770d
5 changed files with 39 additions and 27 deletions

View File

@@ -38,12 +38,11 @@ void FrameBuffer::init()
// generate texture // generate texture
glGenTextures(1, &textureid_); glGenTextures(1, &textureid_);
glBindTexture(GL_TEXTURE_2D, textureid_); glBindTexture(GL_TEXTURE_2D, textureid_);
glTexStorage2D(GL_TEXTURE_2D, 1, use_alpha_ ? GL_RGBA8 : GL_RGB8, attrib_.viewport.x, attrib_.viewport.y);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, use_alpha_ ? GL_RGBA : GL_RGB, attrib_.viewport.x, attrib_.viewport.y,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
// create a framebuffer object // create a framebuffer object
@@ -58,10 +57,10 @@ void FrameBuffer::init()
// create a multisample texture // create a multisample texture
glGenTextures(1, &intermediate_textureid_); glGenTextures(1, &intermediate_textureid_);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, intermediate_textureid_); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, intermediate_textureid_);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, Settings::application.render.multisampling,
use_alpha_ ? GL_RGBA8 : GL_RGB8, attrib_.viewport.x, attrib_.viewport.y, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, Settings::application.render.multisampling,
use_alpha_ ? GL_RGBA : GL_RGB, attrib_.viewport.x, attrib_.viewport.y, GL_TRUE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
// attach the multisampled texture to FBO (currently binded) // attach the multisampled texture to FBO (currently binded)
@@ -160,7 +159,11 @@ void FrameBuffer::readPixels()
else else
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_); glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
glPixelStorei(GL_PACK_ALIGNMENT, 1); if (use_alpha())
glPixelStorei(GL_PACK_ALIGNMENT, 4);
else
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, attrib_.viewport.x, attrib_.viewport.y, (use_alpha_? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, 0); glReadPixels(0, 0, attrib_.viewport.x, attrib_.viewport.y, (use_alpha_? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }

View File

@@ -518,11 +518,11 @@ void MediaPlayer::init_texture(guint index)
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &textureindex_); glGenTextures(1, &textureindex_);
glBindTexture(GL_TEXTURE_2D, textureindex_); glBindTexture(GL_TEXTURE_2D, textureindex_);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width_, height_);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_,
GL_RGBA, GL_UNSIGNED_BYTE, frame_[index].vframe.data[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_,
0, GL_RGBA, GL_UNSIGNED_BYTE, frame_[index].vframe.data[0]);
if (!isimage_) { if (!isimage_) {

View File

@@ -610,8 +610,9 @@ bool RenderingWindow::init(int id, GLFWwindow *share)
// This hint can improve the speed of texturing when perspective-correct texture coordinate interpolation isn't needed // This hint can improve the speed of texturing when perspective-correct texture coordinate interpolation isn't needed
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
// This hint can improve the speed of shading when dFdx dFdy aren't needed in GLSL //
glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_FASTEST); glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_NICEST);
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
// if not main window // if not main window
if ( master_ != NULL ) { if ( master_ != NULL ) {

View File

@@ -35,7 +35,8 @@ uint Resource::getTextureBlack()
glBindTexture( GL_TEXTURE_2D, tex_index_black); glBindTexture( GL_TEXTURE_2D, tex_index_black);
unsigned char clearColor[4] = {0, 0, 0, 255}; unsigned char clearColor[4] = {0, 0, 0, 255};
// texture with one black pixel // texture with one black pixel
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, clearColor); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, clearColor);
} }
return tex_index_black; return tex_index_black;
@@ -51,7 +52,8 @@ uint Resource::getTextureWhite()
glBindTexture( GL_TEXTURE_2D, tex_index_white); glBindTexture( GL_TEXTURE_2D, tex_index_white);
unsigned char clearColor[4] = {255, 255, 255, 255}; unsigned char clearColor[4] = {255, 255, 255, 255};
// texture with one black pixel // texture with one black pixel
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, clearColor); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, clearColor);
} }
return tex_index_white; return tex_index_white;
@@ -241,12 +243,11 @@ uint Resource::getTextureImage(const std::string& path, float *aspect_ratio)
glGenTextures(1, &textureID); glGenTextures(1, &textureID);
glBindTexture( GL_TEXTURE_2D, textureID); glBindTexture( GL_TEXTURE_2D, textureID);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, w, h);
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img);
// free memory // free memory
stbi_image_free(img); stbi_image_free(img);

View File

@@ -28,8 +28,6 @@
#include "UpdateCallback.h" #include "UpdateCallback.h"
#include "Log.h" #include "Log.h"
#define CIRCLE_PIXELS 64
#define CIRCLE_PIXEL_RADIUS 1024.0
bool View::need_deep_update_ = true; bool View::need_deep_update_ = true;
@@ -418,6 +416,13 @@ void MixingView::setAlpha(Source *s)
s->touch(); s->touch();
} }
#define CIRCLE_PIXELS 64
#define CIRCLE_PIXEL_RADIUS 1024.0
//#define CIRCLE_PIXELS 256
//#define CIRCLE_PIXEL_RADIUS 16384.0
//#define CIRCLE_PIXELS 1024
//#define CIRCLE_PIXEL_RADIUS 262144.0
float sin_quad_texture(float x, float y) { float sin_quad_texture(float x, float y) {
return 0.5f + 0.5f * cos( M_PI * CLAMP( ( ( x * x ) + ( y * y ) ) / CIRCLE_PIXEL_RADIUS, 0.f, 1.f ) ); return 0.5f + 0.5f * cos( M_PI * CLAMP( ( ( x * x ) + ( y * y ) ) / CIRCLE_PIXEL_RADIUS, 0.f, 1.f ) );
} }
@@ -427,8 +432,6 @@ uint MixingView::textureMixingQuadratic()
static GLuint texid = 0; static GLuint texid = 0;
if (texid == 0) { if (texid == 0) {
// generate the texture with alpha exactly as computed for sources // generate the texture with alpha exactly as computed for sources
glGenTextures(1, &texid);
glBindTexture(GL_TEXTURE_2D, texid);
GLubyte matrix[CIRCLE_PIXELS*CIRCLE_PIXELS * 4]; GLubyte matrix[CIRCLE_PIXELS*CIRCLE_PIXELS * 4];
GLubyte color[4] = {0,0,0,0}; GLubyte color[4] = {0,0,0,0};
GLfloat luminance = 1.f; GLfloat luminance = 1.f;
@@ -447,27 +450,31 @@ uint MixingView::textureMixingQuadratic()
// transparency // transparency
alpha = 255.f * CLAMP( distance , 0.f, 1.f); alpha = 255.f * CLAMP( distance , 0.f, 1.f);
color[3] = static_cast<GLubyte>(alpha); color[3] = static_cast<GLubyte>(alpha);
// luminance adjustment // luminance adjustment
luminance = 255.f * CLAMP( 0.2f + 0.75f * distance, 0.f, 1.f); luminance = 255.f * CLAMP( 0.2f + 0.75f * distance, 0.f, 1.f);
color[0] = color[1] = color[2] = static_cast<GLubyte>(luminance); color[0] = color[1] = color[2] = static_cast<GLubyte>(luminance);
// 1st quadrant // 1st quadrant
memmove(&matrix[ j * 4 + i * CIRCLE_PIXELS * 4 ], color, 4); memmove(&matrix[ j * 4 + i * CIRCLE_PIXELS * 4 ], color, 4 * sizeof(GLubyte));
// 4nd quadrant // 4nd quadrant
memmove(&matrix[ (CIRCLE_PIXELS -j -1)* 4 + i * CIRCLE_PIXELS * 4 ], color, 4); memmove(&matrix[ (CIRCLE_PIXELS -j -1)* 4 + i * CIRCLE_PIXELS * 4 ], color, 4 * sizeof(GLubyte));
// 3rd quadrant // 3rd quadrant
memmove(&matrix[ j * 4 + (CIRCLE_PIXELS -i -1) * CIRCLE_PIXELS * 4 ], color, 4); memmove(&matrix[ j * 4 + (CIRCLE_PIXELS -i -1) * CIRCLE_PIXELS * 4 ], color, 4 * sizeof(GLubyte));
// 4th quadrant // 4th quadrant
memmove(&matrix[ (CIRCLE_PIXELS -j -1) * 4 + (CIRCLE_PIXELS -i -1) * CIRCLE_PIXELS * 4 ], color, 4); memmove(&matrix[ (CIRCLE_PIXELS -j -1) * 4 + (CIRCLE_PIXELS -i -1) * CIRCLE_PIXELS * 4 ], color, 4 * sizeof(GLubyte));
++c; ++c;
} }
++l; ++l;
} }
// two components texture : luminance and alpha // setup texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glGenTextures(1, &texid);
glBindTexture(GL_TEXTURE_2D, texid);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, CIRCLE_PIXELS, CIRCLE_PIXELS);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, CIRCLE_PIXELS, CIRCLE_PIXELS, GL_BGRA, GL_UNSIGNED_BYTE, matrix);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, CIRCLE_PIXELS, CIRCLE_PIXELS, 0, GL_RGBA, GL_UNSIGNED_BYTE, (float *) matrix); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} }
return texid; return texid;