Very simple glTexImage2D problem -- white texture

Have found many similar problems through google, but none of their solutions worked for me…

I want to simply create a red texture by using glTexImage2D(…) with an array that repeats values [255,0,0,255] (rgba) as the data parameter. i tried to make it as simple as possible, but am getting a white texture, indicating an incorrectly created texture. I can’t seem to pinpoint where the problem is… Help is much appreciated!

The result from the code below is a white square, as such:

The code:


/*
 * 
 */

#include <time.h>
#include <stdio.h>

#if defined(WIN32) || defined(_WIN32)
	#include <windows.h>
#endif

#include <GL/gl.h>
#include <GL/glut.h>

/* globals */
time_t g_time;
time_t g_begintime;

GLuint g_tex; // texture for screen "back buffer"

GLuint g_width;
GLuint g_height;

unsigned char* g_screenpixels; // array of pixels on the screen

#define NUMCHANNELS		4

/* print errors from OpenGL */
void printglerror( )
{
	int error = glGetError();
	if (error != GL_NO_ERROR)
		printf("An OpenGL error has occured: %s
", gluErrorString(error));
}

/* set the color of the pixels to red */
void redpixels( void )
{
	for( GLuint y=0; y<g_height; y++ )
	{
		for( GLuint x=0; x<g_width; x++ )
		{
			g_screenpixels[y*g_width*NUMCHANNELS+x*NUMCHANNELS+0]=255;
			g_screenpixels[y*g_width*NUMCHANNELS+x*NUMCHANNELS+1]=0;
			g_screenpixels[y*g_width*NUMCHANNELS+x*NUMCHANNELS+2]=0;
			g_screenpixels[y*g_width*NUMCHANNELS+x*NUMCHANNELS+3]=255;
		}
	}
}

/* initialize variables and gl properties */
void init ( )
{
	// begin timer
	g_begintime = clock( );
	g_time = g_begintime;
	
	// gl preparations
	glShadeModel( GL_FLAT );
	glClearColor( 0.0f, 0.0f, 0.0f, 0.5f );
	glClearDepth( 1.0f );
	glEnable( GL_DEPTH_TEST );
	glDepthFunc( GL_LEQUAL );
	glEnable ( GL_COLOR_MATERIAL );
	glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
	
	// prepare backbuffer texture
	glEnable( GL_TEXTURE_2D );
	glGenTextures( 1, &g_tex );
	glBindTexture( GL_TEXTURE_2D, g_tex );

	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

	// color array red
	g_screenpixels = new unsigned char[g_width*g_height*NUMCHANNELS];
	redpixels( );

	// set the texture
	glTexImage2D( GL_TEXTURE_2D, 0, NUMCHANNELS, g_width, g_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, g_screenpixels);
}

/* frame render */
void display( void )
{
	// update time
	double elapsed = difftime( clock( ),g_time )/1000.0;
	g_time = clock( );

	// clear the screen
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	// draw the backbuffer quad
	glBindTexture( GL_TEXTURE_2D, g_tex );
	glLoadIdentity( );
	glTranslatef( 0.0f,0.0f,0.0f );
	glScalef( 0.5f, 0.5f, 0.5f );
	glBegin(GL_QUADS);
		glTexCoord2f(0.0f, 0.0f);	glVertex3f(-1.0f,-1.0f, 0.0f);
		glTexCoord2f(0.0f, 1.0f);	glVertex3f(-1.0f, 1.0f, 0.0f);
		glTexCoord2f(1.0f, 1.0f);	glVertex3f( 1.0f, 1.0f, 0.0f);
		glTexCoord2f(1.0f, 0.0f);	glVertex3f( 1.0f,-1.0f, 0.0f);
	glEnd();

	// swap to screen
	glutSwapBuffers( );
}

/* window resize */
void reshape( int w, int h )
{
	g_width = w;
	g_height = h;

	delete g_screenpixels;
	g_screenpixels = new unsigned char[g_width*g_height*NUMCHANNELS];
	redpixels( );

	glBindTexture( GL_TEXTURE_2D, g_tex );
	glTexImage2D( GL_TEXTURE_2D, 0, NUMCHANNELS, g_width, g_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, g_screenpixels);

	glViewport( 0, 0, w, h );
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity( );
	gluOrtho2D(-1.0,1.0,-1.0,1.0);
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity( );
}

/* keyboard callback */
void keyboard( unsigned char key, int x, int y )
{
	switch( key ) {
		case VK_ESCAPE:
			exit ( 0 );
		default:
			break;
	}
}

/* arrow key callback */
void arrow_keys( int a_keys, int x, int y )	// Create Special Function (required for arrow keys)
{
	switch( a_keys ) {
		case GLUT_KEY_UP:
			glutFullScreen( );
			break;
		case GLUT_KEY_DOWN:
			g_width = 512;
			g_height = 512;
			glutReshapeWindow( g_width, g_height );
			break;
		default:
			break;
	}
}

/* main is main */
int main ( int argc, char** argv )
{
	g_width = 512;
	g_height = 512;

	glutInit( &argc, argv );
	init( );
	
	glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
	glutInitWindowSize( g_width, g_height );
	glutCreateWindow( "Tex" );

	glutDisplayFunc( display );
	glutIdleFunc( display );
	glutReshapeFunc( reshape );
	glutKeyboardFunc( keyboard );
	glutSpecialFunc( arrow_keys );
	glutMainLoop( );

	return 0;
}