0
\$\begingroup\$

I'm currently fiddling with SDL2 and OpenGL to get an understanding on how they work and, moreover, how shaders are done and work. Right now, I'm following this tutorial, using SDL instead of glfw; and in a SDL window I render 2 triangles via shader and change their color dynamically, but an obnoxious flickering effect shows, even though I'm sure double buffering is active.

Now, to the code:

    //Here they are SDL attributes for OpenGL
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
    //Double buffer should be on by default, but I set it anyway
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );

    //SDL window creation
    mWindow = SDL_CreateWindow( "Window Title", 
                            SDL_WINDOWPOS_UNDEFINED, 
                            SDL_WINDOWPOS_UNDEFINED, 
                            mWidth, 
                            mHeight, 
                            SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE );

    // Use Vsync    
   if( SDL_GL_SetSwapInterval( 1 ) < 0 )
   {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError() );
  }


    //OpenGL initialization
    glClearColor(0.f, 0.f, 0.f, 1.f);

    glEnable( GL_TEXTURE_2D );

    glEnable( GL_BLEND );
    glDisable( GL_DEPTH_TEST );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

while one of the shaders (no point in pasting the other one, too, as the issue is the same) I use is:

vertex shader:

#version 330
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
out vec3 LSampleFrag;
void main()
{
    gl_Position = vec4(position, 1.0);
    LSampleFrag = color;
}

fragment shader:

#version 330
out vec4 color;
uniform vec4 LSampleFrag;
void main()
{
    color = LSampleFrag;
}

Binding of vertex data to the shader:

    glClearColor(0.f, 0.f, 0.f, 1.f);

    //VBO data
    GLfloat vertexData[] =
    {
        0.5f, -0.5f, 0.0f,
        0.5f, 0.5f, 0.0f,
        -0.5f,  0.5f, 0.0f
    };

    glGenVertexArrays(1, &gVAO);
    glGenBuffers(1, &gVBO);
    // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
    glBindVertexArray(gVAO);

    glBindBuffer(GL_ARRAY_BUFFER, gVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

    // Position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr );
    glEnableVertexAttribArray(0);

    glBindVertexArray(0);

and its render function is this one, where I change, everytime is called shade of green:

GLfloat timeValue = SDL_GetTicks();
GLfloat greenValue = (sin(timeValue) / 2) + 0.5;
GLint vertexColorLocation = glGetUniformLocation(mProgramID, "LSampleFrag");
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

glBindVertexArray(gVAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

//in the main render function, after rendering the shader
SDL_GL_SwapWindow( window_->getSDLWindow());

As I've already said, double buffering is active but flickering is still an issue: am I missing something? I really don't understand why it is happening.

\$\endgroup\$
3
\$\begingroup\$

In fact it's not a flickering problem, in the last codebox lies the root of the nuisance.

GLfloat timeValue = SDL_GetTicks();
GLfloat greenValue = (sin(timeValue) / 2) + 0.5;

Those two lines update the green value each millisecond, changing the colour far too fast, and it could look like a flicker, try increasing the period (decreasing the frequency) of the sin like this:

float period = 1000.0f;
GLfloat timeValue = SDL_GetTicks();
GLfloat greenValue = (sin(timeValue/period) / 2) + 0.5;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.