Win32 + OpenGL flashes white beam ocassionally

Hello, everyone!
I’m beginner of OpenGL. I have been working on some demos with win32 Application. There’re some annoying artifacts which I cannot figure out why. My application flashes white horizontal beams across the client rect from time to time. I thought it might be caused by disabled vertical sync. But after I enabled the global vertical sync on the nvidia pannel, the white flash still exists. I couldn’t figure it out. I’ll appreciate it if everyone could help me out. Thank you!
I’ve added a picture to illustrate the problem. [ATTACH=CONFIG]1107[/ATTACH].
Its just an illustration. The white bar just flashes occasionally and it’s not periodically.
Here’s the message loop of my application.


void OglApp::Run()
{
    while (mbRunning)
    {
        if (PeekMessage(&mMsg, mhWnd, 0, 0, PM_REMOVE) != 0)
        {
            if (mMsg.message != WM_QUIT)
            {
                TranslateMessage(&mMsg);
                DispatchMessage(&mMsg);
            }
            else
            {
                mbRunning = FALSE;
            }
        }
        else //Idle
        {
            if (!mbVisible)
                WaitMessage();
            else
            {
                // Update
                double currentTime = clock();
                mUpdateTimeGap += currentTime - mLastTime;
                if (mUpdateTimeGap > mMinUpdateTimeGap)
                {
                    Update(mMinUpdateTimeGap);
                    mUpdateTimeGap -= mMinUpdateTimeGap;
                }
                mLastTime = currentTime;
                // Draw things
                ShowFps();
                Render();
                SwapBuffers(mhDC);
            }
        }
    }
    DestroyApp();
    return;
}

The rendering part works fine without white bar flashing when built with MFC. So I assume there must be something wrong with the other parts.

How about a picture? A short test program that illustrates the problem would help as well.

If you don’t have one, trying to isolate your problem into one will help you nail down the problem, as well as allow others to reproduce it to help you out.

Thank you for the instruction. I’ve added more details of the problem.

Show us what you do in the Render function.

In the Render() function, Only RenderForward() is called and its code is shown below.


void MyApp::RenderForward()
{
    if (!mpMesh)
        return;

    GLShader* pShader = mpShaderLib->GetShaderProgram(E_Default);
    pShader->Use();


    glBindFramebuffer(GL_FRAMEBUFFER, 0);  // Render to back buffer
    glViewport(0, 0, mWidth, mHeight);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    mpCamera->SetFrustrum(90.0f, static_cast<float>(mWidth) / static_cast<float>(mHeight), 1.0f, 10000.0f);

    iv::mat4 modelMatrix(1.0f);
    iv::mat4 viewMatrix = mpCamera->GetViewMatrix();
    iv::mat4 projectionMatrix = mpCamera->GetProjectionMatrix();
    iv::mat4 MVP = projectionMatrix * viewMatrix * modelMatrix;

    pShader->SetUniform("ModelMatrix", modelMatrix);
    pShader->SetUniform("ViewMatrix", viewMatrix);
    pShader->SetUniform("MVP", MVP);
    pShader->SetUniform("tex", 0);


    iv::vec4 LightWorldPosition(100.0f, 100.0f, 100.0f, 1.0f);
    iv::vec3 LightIntensity(1.0f);
    pShader->SetUniform("Light0.Position", iv::vec3(viewMatrix * LightWorldPosition));
    pShader->SetUniform("Light0.Intensity", LightIntensity);

    pShader->SetUniform("material.Ka", iv::vec3(0.4f));
    pShader->SetUniform("material.Kd", iv::vec3(0.6f));
    pShader->SetUniform("material.Ks", iv::vec3(0.3f));

    pShader->SetUniform("material.Shininess", 128.0f);
    //mTexture.Bind();
    mpMesh->Render();
}

My Shader:

–Vertex Shader–


#version 400

layout ( location = 0 ) in vec3 VertexPosition;
layout ( location = 1 ) in vec3 VertexNormal;
layout ( location = 2 ) in vec2 TexCoord;

out vec3 ePosition;
out vec3 eNormal;
out vec2 Coord;

uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 MVP;

void main()
{
    mat4 MV = ViewMatrix * ModelMatrix;
    ePosition = vec3( MV * vec4(VertexPosition,1.0f));
    eNormal = mat3(MV)*VertexNormal;
    Coord = TexCoord;
    gl_Position = MVP * vec4(VertexPosition,1.0f);
}

–Fragment Shader–


#version 400

layout ( location = 0 ) out vec4 FragColor;

in vec3 ePosition;
in vec3 eNormal;
in vec2 Coord;

uniform sampler2D tex;

struct LightInfo {
    vec3 Position;
    vec3 Intensity;
};

uniform LightInfo Light0;

struct MaterialInfo {
    vec3 Ka;
    vec3 Kd;
    vec3 Ks;
    float Shininess;
};

uniform MaterialInfo material;

void main()
{
    vec3 n = normalize(eNormal);
    vec3 l = normalize(Light0.Position - ePosition);
    vec3 e = normalize( - ePosition );
    vec3 r = reflect( -l , n );
    vec3 ambient = material.Ka;
    vec3 diffuse = material.Kd * max(dot(n,l),0.0f);
    vec3 specular = material.Ks * pow(max(dot(r,e),1.0),material.Shininess);
    vec4 LightColor = vec4(Light0.Intensity * (ambient + diffuse + specular ),1.0f);
    vec4 texColor = texture(tex,Coord);
    FragColor = LightColor * texColor;

}

Please use [noparse]

...

or

...

[/noparse] blocks around your source code as it makes them easier to read (note you can use “glsl” instead of “cpp” for shader source). I’ve added that for you.

As to your problem, nothing’s jumping out at me. I doubt this is it, but you can exclude all your lighting calculations as a possible contributor but modifying your fragment shader to just output solid red.

I would suggest two things

  1. Add a call to glDrawBuffer(GL_BACK_LEFT) after you unbind the framebuffer object

glBindFramebuffer[GL_FRAMEBUFFER,0;// Render to back buffer
glDrawBuffer(GL_BACK_LEFT); //this call will set the back buffer as the drawbuffer

  1. Try outputting just the texture coordinates from the fragment shader and see if you still get the artifacts.

FragColor = vec4(Coord,0,1);

[QUOTE=mobeen;1271217]I would suggest two things

  1. Add a call to glDrawBuffer(GL_BACK_LEFT) after you unbind the framebuffer object

glBindFramebuffer[GL_FRAMEBUFFER,0;// Render to back buffer
glDrawBuffer(GL_BACK_LEFT); //this call will set the back buffer as the drawbuffer

  1. Try outputting just the texture coordinates from the fragment shader and see if you still get the artifacts.

FragColor = vec4(Coord,0,1);

[/QUOTE]

Thank you for your suggestions. I’ve tried the two methods, but the the white beam still flashes from time to time.