NeHe tutorial help (HELP BADLY NEEDED)

Started by
3 comments, last by Deftoned 15 years, 11 months ago
Does anyone know how to edit the code for the NeHe tutorial (#6 Texture mapping) so that it loads .bmp files instead of .raw ones i posted the code for the NeHe tutorial below /* NeHe (nehe.gamedev.net) OpenGL tutorial series GLUT port.in 2001 by milix (milix_gr@hotmail.com) Most comments are from the original tutorials found in NeHe. For VC++ users, create a Win32 Console project and link the program with glut32.lib, glu32.lib, opengl32.lib */


#include <stdio.h>           // Standard C/C++ Input-Output (NEW)
#include <windows.h>         // Standard Header For MSWindows Applications
#include <gl/glut.h>         // The GL Utility Toolkit (GLUT) Header

// The Following Directive Fixes The Problem With Extra Console Window
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

#define TEXTURES_NUM 1       // We Have 1 Texture (NEW) 
#define CUBE_TEX     0       // Our Cube Texture Index (NEW)

// A Structure For RGB Bitmaps
typedef struct _RGBIMG {
	GLuint   w;    // Image's Width
	GLuint   h;    // Image's Height
	GLubyte* data; // Image's Data (Pixels)
} RGBIMG;

// Global Variables
bool    g_gamemode;            // GLUT GameMode ON/OFF
bool    g_fullscreen;          // Fullscreen Mode ON/OFF (When g_gamemode Is OFF)
GLfloat	g_xrot = 0.0f;         // X Rotation (NEW)
GLfloat	g_yrot = 0.0f;         // Y Rotation (NEW)
GLfloat	g_zrot = 0.0f;         // Z Rotation (NEW)
GLuint	g_texid[TEXTURES_NUM]; // Our Textures' Id List (NEW)

// Loads A RGB Raw Image From A Disk File And Updates Our Image Reference
// Returns true On Success, False On Fail.
bool load_rgb_image(const char* file_name, int w, int h, RGBIMG* refimg)
{
	GLuint   sz;    // Our Image's Data Field Length In Bytes
	FILE*    file;  // The Image's File On Disk
	long     fsize; // File Size In Bytes
	GLubyte* p;     // Helper Pointer

	// Update The Image's Fields
	refimg->w = (GLuint) w;
	refimg->h = (GLuint) h;
	sz = (((3*refimg->w+3)>>2)<<2)*refimg->h;
	refimg->data = new GLubyte [sz];
	if (refimg->data == NULL) return false;

	// Open The File And Read The Pixels
	file = fopen(file_name , "rb");
	if (!file) return false;
	fseek(file, 0L, SEEK_END);
	fsize = ftell(file);
	if (fsize != (long)sz) {
		fclose(file);
		return false;
	}
	fseek(file, 0L, SEEK_SET);
	p = refimg->data;
	while (fsize > 0) {
		fread(p, 1, 1, file);
		p++;
		fsize--;
	}
	fclose(file); 
	return true;
}

// Setup Our Textures. Returns true On Success, false On Fail
bool setup_textures()
{
	RGBIMG img;

	// Create The Textures' Id List
	glGenTextures(TEXTURES_NUM, g_texid);          
	// Load The Image From A Disk File
	if (!load_rgb_image("swirl_256x256.raw", 256, 256, &img)) return false;
	// Typical Texture Generation Using Data From The Image
	glBindTexture(GL_TEXTURE_2D, g_texid[CUBE_TEX]);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, 3, img.w, img.h, 0, GL_RGB, GL_UNSIGNED_BYTE, img.data);
	// Finished With Our Image, Free The Allocated Data
	delete img.data;
	return true;
}

// Our GL Specific Initializations. Returns true On Success, false On Fail.
bool init(void)
{
    glShadeModel(GL_SMOOTH);						   // Enable Smooth Shading
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);			   // Black Background
    glClearDepth(1.0f);								   // Depth Buffer Setup
    glEnable(GL_DEPTH_TEST);						   // Enables Depth Testing
    glDepthFunc(GL_LEQUAL);							   // The Type Of Depth Testing To Do
	if (!setup_textures()) return false;
	glEnable(GL_TEXTURE_2D);                           // Enable Texture Mapping (NEW)
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);             // Pixel Storage Mode To Byte Alignment (NEW)
    glEnable(GL_CULL_FACE);                            // Cull Polygons (NEW)
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	return true;
}

// Our Rendering Is Done Here
void render(void)   
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
	glLoadIdentity();									

	glTranslatef(0.0f,0.0f,-5.0f);
	glRotatef(g_xrot,1.0f,0.0f,0.0f);
	glRotatef(g_yrot,0.0f,1.0f,0.0f);
	glRotatef(g_zrot,0.0f,0.0f,1.0f);

	// Say Here What Texture Do You Want To Use 
	glBindTexture(GL_TEXTURE_2D, g_texid[CUBE_TEX]);
	glBegin(GL_QUADS);
		// Front Face
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		// Back Face
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		// Top Face
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		// Bottom Face
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		// Right face
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		// Left Face
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
	glEnd();

	g_xrot += 0.3f;
	g_yrot += 0.2f;
	g_zrot += 0.4f;

    // Swap The Buffers To Become Our Rendering Visible
    glutSwapBuffers ( );
}

// Our Reshaping Handler (Required Even In Fullscreen-Only Modes)
void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);     // Select The Projection Matrix
	glLoadIdentity();                // Reset The Projection Matrix
	// Calculate The Aspect Ratio And Set The Clipping Volume
	if (h == 0) h = 1;
	gluPerspective(80, (float)w/(float)h, 1.0, 5000.0);
	glMatrixMode(GL_MODELVIEW);      // Select The Modelview Matrix
	glLoadIdentity(); // Reset The Modelview Matrix
}

// Our Keyboard Handler (Normal Keys)
void keyboard(unsigned char key, int x, int y)
{
	switch (key) {
		case 27:        // When Escape Is Pressed...
			exit(0);    // Exit The Program
		break;          // Ready For Next Case
		default:        // Now Wrap It Up
		break;
	}
}

// Our Keyboard Handler For Special Keys (Like Arrow Keys And Function Keys)
void special_keys(int a_keys, int x, int y)
{
	switch (a_keys) {
		case GLUT_KEY_F1:
			// We Can Switch Between Windowed Mode And Fullscreen Mode Only
			if (!g_gamemode) {
				g_fullscreen = !g_fullscreen;       // Toggle g_fullscreen Flag
				if (g_fullscreen) glutFullScreen(); // We Went In Fullscreen Mode
				else glutReshapeWindow(500, 500);   // We Went In Windowed Mode
			}
		break;
		default:
		break;
	}
}

// Ask The User If He Wish To Enter GameMode Or Not
void ask_gamemode()
{
	int answer;
	// Use Windows MessageBox To Ask The User For Game Or Windowed Mode
	answer = MessageBox(NULL, "Do you want to enter game mode?", "Question",
						MB_ICONQUESTION | MB_YESNO);
	g_gamemode = (answer == IDYES);
	// If Not Game Mode Selected, Use Windowed Mode (User Can Change That With F1)
	g_fullscreen = false; 
}

// Main Function For Bringing It All Together.
int main(int argc, char** argv)
{
	ask_gamemode();                                  // Ask For Fullscreen Mode
	glutInit(&argc, argv);                           // GLUT Initializtion
	glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE); // (CHANGED)
	if (g_gamemode) {
		glutGameModeString("640x480:16");            // Select The 640x480 In 16bpp Mode
		if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
			glutEnterGameMode();                     // Enter Full Screen
		else g_gamemode = false;                     // Cannot Enter Game Mode, Switch To Windowed
	}
	if (!g_gamemode) {
		glutInitWindowSize(500, 500);                // Window Size If We Start In Windowed Mode
		glutCreateWindow("NeHe's OpenGL Framework"); // Window Title 
	}
	if (!init()) {                                   // Our Initialization
		MessageBox(NULL,"Cannot initialize textures.","Error",MB_ICONSTOP);
		return -1;
	}
	glutDisplayFunc(render);                         // Register The Display Function
	glutReshapeFunc(reshape);                        // Register The Reshape Handler
	glutKeyboardFunc(keyboard);                      // Register The Keyboard Handler
	glutSpecialFunc(special_keys);                   // Register Special Keys Handler
	glutIdleFunc(render);                            // We Render In Idle Time
	glutMainLoop();                                  // Go To GLUT Main Loop
	return 0;
}


[Edited by - voldemort62442 on May 26, 2008 8:55:41 PM]
Advertisement
Plz edit your post and either replace that source code with a link to the tutorial, or at least wrap it in [source] [/source] tags ;)


The easiest way to get support for other image formats (IMO) is to use a loading library like DevIL or SOIL.
[edit] Ah, beaten to the punch. Ah well, this post may yet have merit, so I leave it here.

A note: my suggestion to the original question is a fairly simplistic one, I'd say - in general, the one that Hodgman gives is probably better. [/edit]

First of all, I suspect that posting pieces of code over a few lines' length might discourage potential respondents. Since the code already exists on the NeHe website, surely a link might have sufficed? If you do, either in this or another thread, want to post longer sections of code, however, I recommend placing it within [ source][ /source] tags (without the addition spaces within the tags, of course); source tags should also preserve indentation, thus potentially increasing legibility. The result should look something like this:

//Code here


As to your request, a quick search of the site turned up this article in the results, perhaps it will be of use: How to Load a Bitmap. If not, try the search and ignore that result (which was the first when I searched, as I recall) - something else may prove useful.

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

I use SDL_image to load my images. It supports .png, .bmp, .tga, and way more. I can't seems to locate any tutorials so just google SDL, SDL_image, or IMG_Load
The only difference i believe in loading a RAW is that a raw image is that it doesn't have any headers to worry about.
When you load a file such as TGA or a BMP i believe they have headers inside of them that contains information about the image. Here is some info, it will let you know what is in a BMP, which is literally a header and RBG info.
http://en.wikipedia.org/wiki/BMP_file_format

So really you only have to modify your RAW loader a little to compensate for some headers in the BMP file format.
For example here are a couple of searches in mine, written in c
    /* seek through the bmp header, up to the width/height: */    fseek(file, 18, SEEK_CUR);


    /* seek past the rest of the bitmap header. */    fseek(file, 24, SEEK_CUR);


For every file format that isn't compressed the same kind of rule applies, in TGA loaders though you will need to allow a bit in your data array to take in alpha values.

This topic is closed to new replies.

Advertisement