0
votes

I'm rewriting a renderer (part of a 2D game) to use OpenGL instead of SDL. I have an issue with the following code:

void renderer_opengl::draw_rectangle_filled(int x, int y, int w, int h, SDL_Color color){
    glColor4f((1.0f/255)*color.r, (1.0f/255)*color.g, (1.0f/255)*color.b, (1.0f/255)*color.a);
    glBegin(GL_POLYGON);
        glVertex2f(x, y);
        glVertex2f(x + w, y);
        glVertex2f(x + w, y + h);
        glVertex2f(x, y + h);
    glEnd();
    glColor4f(1, 1, 1, 1);
} 

(yeah I know this is deprecated GL, let's just ignore that now) This draws a rectangle with the given colors and alpha value. The problem is that even when setting the color like this: glColor4f(0, 0, 0, 1); doesn't result in pure black, but instead a semi transparent black (similar to setting the alpha to 50% in the standard SDL renderer).

I have enabled blending like this:

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

I tried different parameters to glBlendFunc but nothing fixes the issue. I can never get a solid color. The rectangles are drawn over textures that are already rendered to the screen. (These rectangles should be black with around 70% alpha - so pretty dark, but still transparent). Thanks for any help.

Code that loads texture from a std::unordered_map of SDL_Surface*

void renderer_opengl::upload_surfaces(std::unordered_map<int, SDL_Surface*>* surfaces){
    for ( auto it = surfaces->begin(); it != surfaces->end(); ++it ){
        if(it->second != NULL && textures[it->first] == NULL){
            glEnable(GL_TEXTURE_2D);
            GLuint TextureID = new_texture_id();
            glGenTextures(1, &TextureID);
            glBindTexture(GL_TEXTURE_2D, TextureID);
            int Mode = GL_RGB;
            if(it->second->format->BytesPerPixel == 4) {
                Mode = GL_RGBA;
            }
            glTexImage2D(GL_TEXTURE_2D, 0, Mode, it->second->w, it->second->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, it->second->pixels);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            textures[it->first] = new texture(TextureID, Mode, it->second->w, it->second->h); //texture is just a struct that holds the GLuint, the Mode, width and height


       }
   }
}

The function that draws textures:

void renderer_opengl::draw_texture(int arg, int x, int y){
    texture* Texture = textures[arg];
    glBindTexture(GL_TEXTURE_2D, Texture->TextureID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   int Width = Texture->width;
   int Height = Texture->height;
   int X = x;
   int Y = y - Height;
   glBegin(GL_QUADS);
        glTexCoord2f(0, 1); glVertex3f(X, Y+ Height, 0);
        glTexCoord2f(1, 1); glVertex3f(X + Width, Y + Height, 0);
        glTexCoord2f(1, 0); glVertex3f(X + Width, Y , 0);
        glTexCoord2f(0, 0); glVertex3f(X, Y , 0);
    glEnd();
}

What I do in the initialization code that hasn't to do with setting up the viewport, aspect ratio, etc..

glEnable (GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

The whole rendering operation goes something like this:

1.

glClearColor(0.0,0.0,0.0,0.0); //Screen is cleared
glClear( GL_COLOR_BUFFER_BIT );
  1. Calls to draw_texture and draw_rectangle_filled are made

  2. SDL_GL_SwapWindow(window); and then everything is displayed

1
glColor4f(1, 1, 1, 1); is not supposed to be pure black, it is supposed to be pure white. - user7860670
Yes, you are right, sorry. I meant to write glColor4f(0, 0, 0, 1); that should be pure black. I edited the question :) - Max
You need to provide Minimal, Complete, and Verifiable example. Or at least show complete frame rendering code that reproduces the stated problem. This draw function looks fine, but who knows what else are you doing before / after? - user7860670
The entire rendering is too much code to post here, but I will try to show the functions that load and draw a texture, as I think that where the problem is. - Max

1 Answers

0
votes

I have resolved the issue by calling glDisable(GL_TEXTURE_2D); before drawing a rectangle. I guess there was still a texture bound to the OpenGl context and that was causing the issue. Everything is perfect now.