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 );
Calls to
draw_texture
anddraw_rectangle_filled
are madeSDL_GL_SwapWindow(window);
and then everything is displayed
glColor4f(1, 1, 1, 1);
is not supposed to be pure black, it is supposed to be pure white. - user7860670glColor4f(0, 0, 0, 1);
that should be pure black. I edited the question :) - Max