Tell me more ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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!

share|improve this question
I'm not 100% certain how GLSL works in this regard (so don't take this as an answer) but you're both reading from and writing to your FS output. Maybe try caching the result in an intermediate variable and then storing that to colorOut at the end? – mh01 Jun 27 '12 at 19:46
1  
How are you loading textures? How are they big? Are you setting some mipmaps? Can you write as many informations as you know? :) – zacharmarz Jun 27 '12 at 20:27
you're having CPU issues, i mean that just doesn't seem like a GLSL problem – dreta Jun 27 '12 at 20:43
Also i can tell you that your light calculation is wrong, you're calculating the vector to light with the light position in camera space, but the vertex position is in the clip space. – dreta Jun 27 '12 at 20:47
Confirmed that reading from/writing to FS output is safe - ignore my first comment. Another question - is this actually manifesting as a measurable performance issue (i.e. actually running slower) or is it just showing up as CPU load? Extra CPU time does not equate to performance loss - it's what you do with that time that's important. – mh01 Jun 27 '12 at 21:14
show 6 more comments

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.