Donald Duck Donald Duck - 4 months ago 34
C Question

Problems with PNG in OpenGL textures

I tried to use a PNG image in an OpenGL texture like this:

GLuint texture;
SDL_Surface *surface;
surface = IMG_Load("image.png");
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,surface->w,surface->h,0,GL_RGB,GL_UNSIGNED_BYTE,surface->pixels);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
SDL_FreeSurface(surface);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texture);
glBegin(GL_QUADS);
glColor3ub(255,255,255);
glTexCoord2f(0,0);
glVertex3d(0,0,0);
glTexCoord2f(0,1);
glVertex3d(0,1,0);
glTexCoord2f(1,1);
glVertex3d(1,1,0);
glTexCoord2f(1,0);
glVertex3d(1,0,0);
glEnd();
glDisable(GL_TEXTURE_2D);


The included libraries are the following ones (some are not relevant here, but here are all of them just in case it matters):

#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <dirent.h>
#include <unistd.h>


image.png is a 128x128 sized PNG image located in the same folder as the executable. Here is a screenshot of what I get:

problem

To compare, here is the original image:

originalimage

As you can see, there is a big problem.

I tried to use Bitmap instead of PNG and it worked just fine. But I need to use PNG because I need transparency (not for this image in particular but for other images). I tried changing the code in all sorts of ways to get it to work with PNG, but it didn't work.

I'm using SDL 1.2 and OpenGL 1.4.

Why does it do this and how should I fix it?

Answer

Here is the problem.

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,surface->w,surface->h,0,GL_RGB,GL_UNSIGNED_BYTE,surface->pixels);

Your format parameter is incorrect.

is should be

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,surface->w,surface->h,0,GL_RGBA8,GL_UNSIGNED_BYTE,surface->pixels);

GL_RGBA8 will represent 8 bits per channel which is what I think you need in your solution.

Please refer https://www.opengl.org/sdk/docs/man/html/glTexImage2D.xhtml for more information.

Comments