Thursday, August 20, 2009

Simple OpenGL Texture Example

Here is a simple example of code to use an OpenGL Texture.





// Apple gcc program0.c -framework opengl -framework glut
// A simple OpenGL and glut program
#include <GLUT/glut.h> /* Header File For The GLut Library*/
#include <stdint.h>

//
// You need to generate the texture data that you are going to
// use. GIMP will convert a bitmap, jpg, etc. to a "C" structure
// that you can use almost directly.
//


// GIMP RGBA C-Source image dump (f35_schem_02_edit_4.c)

static const struct {
uint32_t width;
uint32_t height;
uint32_t bytes_per_pixel; /* 3:RGB, 4:RGBA */
uint8_t pixel_data[128 * 128 * 4 + 1];
} planform = {
128, 128, 4,
"\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
"\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0"
"\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
"\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
// ... much of the texture deleted
"\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
"\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377",
};


// The routine to draw the screen
void display() {
// A value to hold our texture handle
static uint32_t texture = 0;
static int32_t firstTimeDone = 0;

// Clear the display
glClear(GL_COLOR_BUFFER_BIT);
// Set the color to white
glColor3f(1.0, 1.0, 1.0);
// Setup the coordinates to what I am used to
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

// Get a texture number if we dont have one
if (!firstTimeDone)
{
// Get a texture number
glGenTextures(1, &texture);

// Tell OpenGL that we want to use that texture
glBindTexture(GL_TEXTURE_2D, texture);

// You have to tell OpenGL how to take the raw bitmap data
// in the structure above to put it into a texture. We
// do this with a glTexImage2D() call. We will describe the
// structure above and how we want it stored internally in
// OpenGl.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, planform.width, planform.height,
0, GL_RGBA, GL_UNSIGNED_BYTE, planform.pixel_data);

// OpenGl lets you describe how you want to scale the
// texture data when the destination is bigger or smaller
// than the original texture data. In this case, we want
// simple linear scaling.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

// First Time is done
firstTimeDone = 1;
}
else
{
// Tell OpenGL that we want to use that texture
glBindTexture(GL_TEXTURE_2D, texture);
}

// We are going to put the texture on a 2D surface, much
// like we would apply a decal.
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

// Normally you leave GL_TEXTURE_2D turned off unless
// you are applying a decal to a surface. Since we are
// doing that, we turn it on here.
glEnable(GL_TEXTURE_2D);

// Draw the square
glBegin(GL_POLYGON);

// Here we want to associate a point in the texture with the
// vertex we are drawing on the screen. So these are paired up.
glTexCoord2f(0.0f, 1.0f); glVertex2f(-0.5, -0.5);
glTexCoord2f(0.0f, 0.0f); glVertex2f(-0.5, 0.5);
glTexCoord2f(1.0f, 0.0f); glVertex2f(0.5, 0.5);
glTexCoord2f(1.0f, 1.0f); glVertex2f(0.5, -0.5);

// End of the list of verticies
glEnd();
// Turn texture drawing back off, normally we leave if off.
glDisable(GL_TEXTURE_2D);

// Flush the data. In many drivers, this causes the
// actual draw to the Frame Buffer.
glFlush();
}

int main(int argc, char **argv) {
// A minimal GLUT setup to get GLUT up and going.
// If you use EGL or some other windowing system
// other than GLUT, you need to replace this.
glutInit(&argc, argv);
glutInitWindowSize(512,512);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("The glut hello world program");
glutDisplayFunc(display);
glClearColor(0.0, 0.0, 0.0, 1.0);
glutMainLoop(); // Infinite event loop
return 0;
}

</stdint.h>