From 4f3114770d1bba21b54bdf0cd108d62cb1d43f9a Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Thu, 30 Jul 2020 00:13:46 +0200 Subject: [PATCH] Cleanup OpenGL texture for optimal performance: using GL4 glTexStorage2D with RGBA8 (most efficient implementation in hardware). --- FrameBuffer.cpp | 13 ++++++++----- MediaPlayer.cpp | 6 +++--- RenderingManager.cpp | 5 +++-- Resource.cpp | 13 +++++++------ View.cpp | 29 ++++++++++++++++++----------- 5 files changed, 39 insertions(+), 27 deletions(-) diff --git a/FrameBuffer.cpp b/FrameBuffer.cpp index ad8a6be..767f1a2 100644 --- a/FrameBuffer.cpp +++ b/FrameBuffer.cpp @@ -38,12 +38,11 @@ void FrameBuffer::init() // generate texture glGenTextures(1, &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_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 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); // create a framebuffer object @@ -58,10 +57,10 @@ void FrameBuffer::init() // create a multisample texture glGenTextures(1, &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_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); // attach the multisampled texture to FBO (currently binded) @@ -160,7 +159,11 @@ void FrameBuffer::readPixels() else 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); glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/MediaPlayer.cpp b/MediaPlayer.cpp index f96dce1..d27748b 100644 --- a/MediaPlayer.cpp +++ b/MediaPlayer.cpp @@ -518,11 +518,11 @@ void MediaPlayer::init_texture(guint index) glActiveTexture(GL_TEXTURE0); glGenTextures(1, &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_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_) { diff --git a/RenderingManager.cpp b/RenderingManager.cpp index 19db58c..b3b8132 100644 --- a/RenderingManager.cpp +++ b/RenderingManager.cpp @@ -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 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 ( master_ != NULL ) { diff --git a/Resource.cpp b/Resource.cpp index b1c5858..9b187b3 100644 --- a/Resource.cpp +++ b/Resource.cpp @@ -35,7 +35,8 @@ uint Resource::getTextureBlack() glBindTexture( GL_TEXTURE_2D, tex_index_black); unsigned char clearColor[4] = {0, 0, 0, 255}; // 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; @@ -51,7 +52,8 @@ uint Resource::getTextureWhite() glBindTexture( GL_TEXTURE_2D, tex_index_white); unsigned char clearColor[4] = {255, 255, 255, 255}; // 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; @@ -241,12 +243,11 @@ uint Resource::getTextureImage(const std::string& path, float *aspect_ratio) glGenTextures(1, &textureID); glBindTexture( GL_TEXTURE_2D, textureID); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, w, h); + 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_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img); // free memory stbi_image_free(img); diff --git a/View.cpp b/View.cpp index 98ed1ab..378970c 100644 --- a/View.cpp +++ b/View.cpp @@ -28,8 +28,6 @@ #include "UpdateCallback.h" #include "Log.h" -#define CIRCLE_PIXELS 64 -#define CIRCLE_PIXEL_RADIUS 1024.0 bool View::need_deep_update_ = true; @@ -418,6 +416,13 @@ void MixingView::setAlpha(Source *s) 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) { 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; if (texid == 0) { // 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 color[4] = {0,0,0,0}; GLfloat luminance = 1.f; @@ -447,27 +450,31 @@ uint MixingView::textureMixingQuadratic() // transparency alpha = 255.f * CLAMP( distance , 0.f, 1.f); color[3] = static_cast(alpha); + // luminance adjustment luminance = 255.f * CLAMP( 0.2f + 0.75f * distance, 0.f, 1.f); color[0] = color[1] = color[2] = static_cast(luminance); // 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 - 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 - 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 - 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; } ++l; } - // two components texture : luminance and alpha - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + // setup texture + 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); - 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;