White quad converting SDL_Surface to OPENGL_Texture
I'm trying to convert a SDL surface to an openGL texture using a snippet of code I found lying around the internet, after many hours of searching, most seem to use the same functions in the same order, so I'm assuming i'm doing things right.
Self-Critisizing, i'm splitting up my code a little too much, i like to keep things organised, but there may be something buried in a file I don't go into much...
Long and short of it, my app is supposed to render 2 cubes, rotate them both and allow one to be moved.
Cubes can be created with a class I wrote, just define one and give it a filename, it should load that texture and apply it to the cube when the show function is called.
I had it working partially with the SOIL library, but i've moved a lot of code to SDL and I'd prefer to use IMG_Load instead.
Here's the code
GLuint loadTexture(std::string filename)
{
GLuint texture;
if(SDL_Surface* surfaceTex = IMG_Load(filename.c_str()))
{
glPixelStorei(GL_UNPACK_ALIGNMENT,4);
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
SDL_PixelFormat *format = surfaceTex->format;
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
if (format->Amask)
{
gluBuild2DMipmaps(GL_TEXTURE_2D,4,surfaceTex->w,surfaceTex->h,GL_RGBA,GL_UNSIGNED_BYTE,surfaceTex->pixels);
}
else
{
gluBuild2DMipmaps(GL_TEXTURE_2D,3,surfaceTex->w,surfaceTex->h,GL_RGBA,GL_UNSIGNED_BYTE,surfaceTex->pixels);
}
SDL_FreeSurface(surfaceTex);
}
else
{
log("Loading texture failed!",true);
}
return texture;
}
I really want the code to be portable between projects, so I can just say
Gluint Tex = loadTexture(filename);
and the texture is ready.
UPDATE:
Here's the show method for showing a cube
cubeTexture = loadTexture(filename);
glLoadIdentity();
glTranslatef(xPos,yPos,zPos);
xRotate = 1.0;
yRotate = 1.0;
zRotate = 1.0;
glRotatef(angle,xRotate,yRotate,zRotate);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, cubeTexture);
glBegin(GL_QUADS);
/* Top face */
glNormal3f(0.0f,0.0f,1.0f); /* Top face normal */
glTexCoord2f(0.0f, 0.0f); glVertex3f( Width, Height, -Depth); /* top right */
glTexCoord2f(1.0f, 0.0f); glVertex3f(-Width, Height, -Depth); /* top left */
glTexCoord2f(1.0f, 1.0f); glVertex3f(-Width, Height, Depth); /* bottom left */
glTexCoord2f(0.0f, 1.0f); glVertex3f( Width, Height, Depth); /* bottom right */
/* Bottom face */
glNormal3f(0.0f,0.0f,-1.0f); /* Bottom face normal */
glTexCoord2f(1.0f, 0.0f); glVertex3f( Width, -Height, Depth); /* top right */
glTexCoord2f(1.0f, 1.0f); glVertex3f(-Width, -Height, Depth); /* top left */
glTexCoord2f(0.0f, 1.0f); glVertex3f(-Width, -Height, -Depth); /* bottom left */
glTexCoord2f(0.0f, 0.0f); glVertex3f( Width, -Height, -Depth); /* bottom right */
/* Front face */
glNormal3f(0.0f,1.0f,0.0f); /* Front face normal */
glTexCoord2f(0.0f, 1.0f); glVertex3f( Width, Height, Depth); /* top right */
glTexCoord2f(0.0f, 0.0f); glVertex3f(-Width, Height, Depth); /* top left */
glTexCoord2f(1.0f, 0.0f); glVertex3f(-Width, -Height, Depth); /* bottom left */
glTexCoord2f(1.0f, 1.0f); glVertex3f( Width, -Height, Depth); /* bottom right */
/* Back face */
glNormal3f(0.0f,-1.0f,0.0f); /* Back face normal */
glTexCoord2f(1.0f, 1.0f); glVertex3f( Width, -Height, -Depth); /* top right */
glTexCoord2f(0.0f, 1.0f); glVertex3f(-Width, -Height, -Depth); /* top left */
glTexCoord2f(0.0f, 0.0f); glVertex3f(-Width, Height, -Depth); /* bottom left */
glTe开发者_开发知识库xCoord2f(1.0f, 0.0f); glVertex3f( Width, Height, -Depth); /* bottom right */
/* Left face */
glNormal3f(-1.0f,0.0f,0.0f); /* Left face normal */
glTexCoord2f(1.0f, 0.0f); glVertex3f(-Width, Height, Depth); /* top right */
glTexCoord2f(1.0f, 1.0f); glVertex3f(-Width, Height, -Depth); /* top left */
glTexCoord2f(0.0f, 1.0f); glVertex3f(-Width, -Height, -Depth); /* bottom left */
glTexCoord2f(0.0f, 0.0f); glVertex3f(-Width, -Height, Depth); /* bottom right */
/* Right face */
glNormal3f(1.0f,0.0f,0.0f); /* Right face normal */
glTexCoord2f(0.0f, 0.0f); glVertex3f( Width, Height, -Depth); /* top right */
glTexCoord2f(1.0f, 0.0f); glVertex3f( Width, Height, Depth); /* top left */
glTexCoord2f(1.0f, 1.0f); glVertex3f( Width, -Height, Depth); /* bottom left */
glTexCoord2f(0.0f, 1.0f); glVertex3f( Width, -Height, -Depth); /* bottom right */
glEnd();
and my GL_INIT function
glEnable(GL_TEXTURE_2D); /* Enable Texture Mapping */
glShadeModel(GL_SMOOTH); /* Enable smooth shading */
glClearColor(0.0f,0.0f,0.0f,0.0f); /* Set the background black */
glClearDepth(1.0f); /* Set the depth buffer up */
glEnable(GL_DEPTH_TEST); /* Set Depth testing up */
glDepthFunc(GL_LEQUAL); /* Sets the type of depth testing to Less or Equal */
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); /* Uses the nice perspective calcs */
glLightfv(GL_LIGHT1,GL_AMBIENT,LightAmbient); /* Sets up the ambient light */ //test
glLightfv(GL_LIGHT1,GL_DIFFUSE,LightDiffuse); /* Sets up the diffuse light */ //test
glLightfv(GL_LIGHT1,GL_POSITION,LightPosition); /* Sets up the light position */ //test
glEnable(GL_LIGHT1); /* Enable the first light */
Make sure to glEnable(GL_TEXTURE_2D)
.
Also, your second gluBuild2DMipmaps()
call should take GL_RGB
, not GL_RGBA
. Otherwise it reads off past the end of surfaceTex->pixels
.
Try this:
#include <iostream>
#include <SDL.h>
#include <SDL_opengl.h>
#include <SDL_image.h>
using namespace std;
GLuint loadTexture(std::string filename)
{
GLuint texture;
if(SDL_Surface* surfaceTex = IMG_Load(filename.c_str()))
{
glPixelStorei(GL_UNPACK_ALIGNMENT,4);
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
SDL_PixelFormat *format = surfaceTex->format;
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
if (format->Amask)
{
gluBuild2DMipmaps(GL_TEXTURE_2D,4,surfaceTex->w,surfaceTex->h,GL_RGBA,GL_UNSIGNED_BYTE,surfaceTex->pixels);
}
else
{
gluBuild2DMipmaps(GL_TEXTURE_2D,3,surfaceTex->w,surfaceTex->h,GL_RGB,GL_UNSIGNED_BYTE,surfaceTex->pixels);
}
SDL_FreeSurface(surfaceTex);
}
else
{
return 0;
}
return texture;
}
int main(int argc, char* argv[])
{
_putenv("SDL_VIDEO_CENTERED=1");
SDL_Init(SDL_INIT_EVERYTHING);
int win_w = 800;
int win_h = 600;
SDL_Surface* display = SDL_SetVideoMode(win_w, win_h, 32, SDL_OPENGL);
GLuint tex = loadTexture("concrete.png");
bool running = true;
while( running )
{
// handle all pending events
SDL_Event event;
while( SDL_PollEvent(&event) )
{
switch (event.type)
{
case SDL_KEYDOWN:
if( event.key.keysym.sym == SDLK_ESCAPE )
running = false;
break;
case SDL_QUIT:
running = false;
break;
default:
break;
}
}
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, win_w, 0, win_h, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glPushMatrix();
glScalef(200,200,200);
glBegin(GL_TRIANGLES);
glTexCoord2f(0,0);
glVertex2f(0,0);
glTexCoord2f(1,0);
glVertex2f(1,0);
glTexCoord2f(1,1);
glVertex2f(1,1);
glEnd();
glPopMatrix();
SDL_GL_SwapBuffers();
SDL_Delay( 1 );
}
SDL_Quit();
return 0;
}
concrete.png
:
Try glPixelStorei(GL_UNPACK_ALIGNMENT,1)
.
Avoid gluBuild2DMipmaps()
.
精彩评论