I currently have a project that renders OpenGL video using a vertex and fragment shader. The shaders work fine as-is, but in trying to add in texturing, I am running into performance issues and can't figure out why.
Before adding texturing, my program ran just fine and loaded my CPU between 0%-4%. When adding texturing (specifically when the fragment shader adds textures AND color -- noted by comment below), my CPU is 100% loaded. The only code I have added to my old, working code is the relevant texturing code to the shader, the "loadTexture()" function, and the "glBindTexture()" calls to the rendering code.
Here are my shaders and relevant rending code.
Vertex Shader:
#version 150
uniform mat4 mvpMatrix;
uniform mat4 lightMatrix;
uniform mat3 normalMatrix;
uniform vec4 lightPosition;
uniform float diffuseValue;
layout(location = 0) in vec3 vertex;
layout(location = 1) in vec3 color;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec2 texCoord;
smooth out VertData {
vec3 color;
vec3 normal;
vec3 toLight;
float diffuseValue;
vec2 texCoord;
} VertOut;
void main(void)
{
gl_Position = mvpMatrix * vec4(vertex, 1.0);
VertOut.normal = normalize(normalMatrix * normal);
VertOut.toLight = normalize(vec3(lightMatrix * lightPosition - gl_Position));
VertOut.color = color;
VertOut.diffuseValue = diffuseValue;
VertOut.texCoord = texCoord;
}
Fragment Shader:
#version 150
smooth in VertData {
vec3 color;
vec3 normal;
vec3 toLight;
float diffuseValue;
vec2 texCoord;
} VertIn;
uniform sampler2D tex;
layout(location = 0) out vec3 colorOut;
void main(void)
{
float diffuseComp = max(dot(normalize(VertIn.normal), normalize(VertIn.toLight))), 0.0);
vec4 color = texture2D(tex, VertIn.texCoord);
colorOut = color.rgb * diffuseComp * VertIn.diffuseValue + color.rgb * (1 - VertIn.diffuseValue);
// FOLLOWING LINE CAUSES PERFORMANCE ISSUES
colorOut *= VertIn.color;
}
Relevant Rendering Code:
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
/*
<-- Some initialization left out -->
*/
// Update Timer
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), SLOT(timeOut()));
timer->start(25); // 25 ms
}
void GLWidget::timeOut()
{
// QT's way to invoke paintGL() and update
updateGL();
}
void GLWidget::loadTexture()
{
// GLUint texture[3] previously defined
QImage img[3];
QImage glTypeImg[3];
// Load Files
img[0].load("White.png");
glTypeImg[0] = QGLWidget::convertToGLFormat(img[0]);
img[1].load("Face.png");
glTypeImg[1] = QGLWidget::convertToGLFormat(img[1]);
img[2].load("Terrain.png");
glTypeImg[2] = QGLWidget::convertToGLFormat(img[2]);
// Generate and Bind
glGenTextures(3, texture);
// #1
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, glTypeImg[0].width(), glTypeImg[0].height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, glTypeImg[0].bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// #2
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, glTypeImg[1].width(), glTypeImg[1].height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, glTypeImg[1].bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// #3
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, glTypeImg[2].width(), glTypeImg[2].height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, glTypeImg[2].bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void QGLWidget::paintGL()
{
// texture[0] is a 1x1 white texture to effectively turn off texturing
program->bind();
program->enableAttributeArray(0); // Vertex
program->enableAttributeArray(1); // Color
program->enableAttributeArray(2); // Normals
program->enableAttributeArray(3); // Tex Coords
/*
<-- Matrix and Light management omitted -->
*/
// Draw squares
glBindTexture(GL_TEXTURE_2D, texture[1]);
// Set attributes, uniforms, etc
glDrawArrays(GL_QUADS, 0, 6*4);
// Draw triangles
glBindTexture(GL_TEXTURE_2D, texture[0]);
// Set attributes, uniforms, etc
glDrawArrays(GL_TRIANGLES, 0, 3*4);
// Draw reference planes
glBindTexture(GL_TEXTURE_2D, texture[0]);
// Set attributes, uniforms, etc
glDrawArrays(GL_LINES, 0, 4*81*2);
// Draw terrain
glBindTexture(GL_TEXTURE_2D, texture[2]);
// Set attributes, uniforms, etc
glDrawArrays(GL_TRIANGLES, 0, 501*501*6);
// Release
glBindTexture(GL_TEXTURE_2D, 0);
program->release();
}
Any help is greatly appreciated!