Sign in to follow this  

Targa Loader, Quick Question

This topic is 4732 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

The targa loader found at http://steinsoft.net/index.php?site=Programming/Code%20Snippets/Cpp/no8 , has me a bit confused. How exactly do you use it? Can someone just give me a simple example of how to load the tga and create a 2d texture with it? Then bind the one line of code to bind it to a object? (ofcourse its more with polygons, but atm i am talkin prebuilt glut objects.) Thanks! I must have been doin somethin wrong because i get an error anytime i try to implement it. Thanks :)

Share this post


Link to post
Share on other sites
Although the example is actually wrong. It should be:
STGA tgaFile;
if (loadTGA("data/image.tga", tgaFile)) // no operator&
{
//Do things...
// ex. create OpenGL texture using tgaFile->imageData etc.
}

//tgaFile will clean up itself thanks to destructor

Since the loadTGA function takes its parameter by reference, not by pointer. Looks like this code was originally pure C, retrofitted with a couple of functions (one of which is dangerous and should not be there) and reference calling convention.

Enigma

Share this post


Link to post
Share on other sites
Sorry, i have been busy with the holiday lol.

Can you give me an example of the "do stuff" section of the code? Inside the if statement for loading the bitmap?


If my light grasp of loading images and creating a texture is correct, you take the image, load it into an array (to do that you need some type of decoder that knows the image format), then start telling opengl what you wish to do with the data you loaded.

However after that it gets very hazy. Can someone give me an example code of what i need to load the texture?

Like the glGenTexture, BindTexture, glTexImage2D, and glTexParameteri's?

Total nub here, please help me out lol, thanks! :)

Share this post


Link to post
Share on other sites
An example (remember to include the right struct):
http://www.nife.1go.dk/C++/LoadTGAFile.txt
It's not my newest version (because that's implemented into another class, and would therefore be hard to seperate nicely), but it should do the job for now...

For speed:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Medium quality:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

High quality (2x AF):
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2);

Very high quality (4x AF)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4);

The higheste count of AF can be achieved by:
int anisotropic;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropic);

And for the GLUT question: frankly I have no idea, since I've never used GLU or GLUT, but I can show you how to with OpenGL functions ;-)

Share this post


Link to post
Share on other sites
That isn't exactly the best designed class I've seen..
First it should be a class, second, LoadTGA should be a member function of STGA [smile] - but thats just me being picky. Also, the big thing, is that the number of channels in the image is a local variable of LoadTGA.. it should be a class variable.

Btw. to my eye at least, the destroy() method of STGA will likly cause a crash in the destructor so don't use it.

I couldn't resist...
Here is my version: [wink]

STGA.h:

#pragma once

class STGA
{
STGA(STGA & tga); // no copying! (memory errors otherwise)

public:
STGA();
STGA(char * file);

~STGA();

void destroy();

int width();

int height();
unsigned char * data();

int channels();

bool load(char *filename);


void loadOpenGL();

void bindOpenGL();

void destroyOpenGL();
private:
unsigned int openGLid;

int imageWidth;
int imageHeight;
unsigned char imageTypeCode;
unsigned char bitCount;
unsigned char* imageData;
int imageChannels;
};




STGA.cpp:


#include "STGA.h"
// #include "stdafx.h" // whatever
// etc

STGA::STGA(STGA & tga) // no copying! (memory errors otherwise)
{
}

STGA::STGA() : imageData(0), imageWidth(0), imageHeight(0), imageTypeCode(0), bitCount(0), imageChannels(0), openGLid(0)
{
}

STGA::STGA(char * file) : imageData(0), imageWidth(0), imageHeight(0), imageTypeCode(0), bitCount(0), imageChannels(0), openGLid(0)
{
load(file);
}

STGA::~STGA()
{
destroy();
}

void STGA::destroy()
{
if (imageData)
delete[] imageData;
imageData=0;
imageWidth=0;
imageHeight=0;
imageTypeCode= 0;
bitCount=0;
imageChannels=0;

destroyOpenGL();
}

int STGA::width()
{
return imageWidth;
}

int STGA::height()
{
return imageHeight;
}

unsigned char * STGA::data()
{
return imageData;
}

int STGA::channels()
{
return imageChannels;
}

bool STGA::load(char *filename)
{
FILE *file;
unsigned char badChar;
short int badInt;
long imageSize;
int colorMode;

file = fopen(filename, "rb");

if (!file)
return false;

fread(&badChar, sizeof(unsigned char), 1, file);
fread(&badChar, sizeof(unsigned char), 1, file);

fread(&imageTypeCode, sizeof(unsigned char), 1, file);

//image type either 2 (color) or 3 (greyscale)
if ((imageTypeCode != 2) && (imageTypeCode != 3))
{
fclose(file);
return false;
}

//13 bytes of useless data
fread(&badInt, sizeof(short int), 1, file);
fread(&badInt, sizeof(short int), 1, file);
fread(&badChar, sizeof(unsigned char), 1, file);
fread(&badInt, sizeof(short int), 1, file);
fread(&badInt, sizeof(short int), 1, file);

//image dimensions
fread(&imageWidth, sizeof(short int), 1, file);
fread(&imageHeight, sizeof(short int), 1, file);

//image bit depth
fread(&bitCount, sizeof(unsigned char), 1, file);

//1 byte of garbage data
fread(&badChar, sizeof(unsigned char), 1, file);

//colorMode -> 3 = BGR, 4 = BGRA
colorMode = bitCount / 8;
imageSize = imageWidth * imageHeight * colorMode;

//allocate memory for image data
imageData = new unsigned char[imageSize];

//read in image data
fread(imageData, sizeof(unsigned char), imageSize, file);

//change BGR to RGB (especially for OpenGL later on)
for (int i = 0; i < imageSize; i += colorMode)
{
//swap blue and red colour value
imageData[i] ^= imageData[i+2] ^=
imageData[i] ^= imageData[i+2];
}

//close file
fclose(file);

imageChannels=colorMode;

return true;
}


STGA::loadOpenGL()
{
glGenTextures(1, &openGLid);
glBindTexture(GL_TEXTURE_2D, openGLid);

INSERT YOUR glTexParametrei Calls here to set filtering, etc!!!

unsigned int mode=GL_RGB;

if (channels()==4)
mode=GL_RGBA;

glTexImage2D(GL_TEXTURE_2D,0,channels(),width(),height(),0,mode,GL_UNSIGNED_BYTE,data());

gluBuild2DMipmaps(GL_TEXTURE_2D,channels(),width(),height(),mode,GL_UNSIGNED_BYTE,data());
}

STGA::bindOpenGL()
{
if (openGLid)
glBindTexture(GL_TEXTURE_2D, openGLid);
}

STGA::destroyOpenGL()
{
if (openGLid)
glDeleteTextures(1, &openGLid);
openGLid=0;
}






(no guarentee it works, I havn't tested it [smile])

Therefore, the usage would be something like:


STGA tga; // global, or in a class somewhere, ie, sticks around for entire time

....

if (tga.load("data/mytest.tga"))
{
tga.loadOpenGL();
}


then when rendering,

tga.bindOpenGL(); // to bind.

okies? [wink]
All nice and OO :)


hope that compiles. (I've left out the tex param sutff that nife mentioned. put in what you feel is appropriate)


Have fun.

Share this post


Link to post
Share on other sites
Quote:
Original post by RipTorn
That isn't exactly the best designed class I've seen..
First it should be a class, second, LoadTGA should be a member function of STGA [smile] - but thats just me being picky. Also, the big thing, is that the number of channels in the image is a local variable of LoadTGA.. it should be a class variable.

Btw. to my eye at least, the destroy() method of STGA will likly cause a crash in the destructor so don't use it.

I couldn't resist...
Here is my version: [wink]

STGA.h:
*** Source Snippet Removed ***

STGA.cpp:
*** Source Snippet Removed ***


(no guarentee it works, I havn't tested it [smile])

Therefore, the usage would be something like:


STGA tga; // global, or in a class somewhere, ie, sticks around for entire time

....

if (tga.load("data/mytest.tga"))
{
tga.loadOpenGL();
}


then when rendering,

tga.bindOpenGL(); // to bind.

okies? [wink]
All nice and OO :)


hope that compiles. (I've left out the tex param sutff that nife mentioned. put in what you feel is appropriate)


Have fun.


That's one slow tga loader ;)
You have way to many fread's, and instead of swapping the bytes, you could use GL_BGR_EXT and GL_BGRA_EXT with pictures which doesn't require to be read from anymore (ie. no runtime manipulation).

Share this post


Link to post
Share on other sites
I just copied and pasted the actual loading code form the site he linked.

It's just it's packaged into a class instead. And got rid of a couple of the bugs in it. And added loading into OpenGL.

So that part isn't my code ;)

Share this post


Link to post
Share on other sites
Thanks guys :), so i havent tested that yet (and my ability to use it). But i'm just curious, do you all just make your own loaders for your applications then?

Share this post


Link to post
Share on other sites
Well, it's better than it was but there are still some bugs and stylistic issues in that class design. Some of the stylistic points are debatable, I've tried to indicate that where applicable.

Bugs:
  • If copy-construction is illegal then assignment should be too.

  • If copy-construction is illegal then the copy constructor should be declared but not defined. This prevents code that can legally call private member functions (i.e. other members or friends) from successfully linking in the event that they try to use the copy constructor (the same goes for the assignment operator).

  • load may be called multiple times on the same instance. Each such call after the first results in a memory leak.

Stylistic:
  • #pragma once is non-portable. An #ifndef, #define, #endif structure would be better if portability is a concern.

  • const correctness. Many functions are themselves or take parameters that are logically const. This should be reflected in the code.

  • Overly large interface. There are several ways to achieve the same functionality (i.e. STGA instance(filename); vs STGA instance;instance.load(filename);). Prefer to make class interfaces complete but minimal.

  • Resouce Acquisition Is Initialisation (RAII). If you subscribe to this philosophy then STGA(filename); should be the only constructor and should call both load and loadOpenGL. The destructor should then call both destroyOpenGL and destroy. As it is it is far too easy for a client to forget to call destroyOpenGL and thus leak a texture ID. In this instance RAII does require that a valid OpenGL context exists before any STGA instances are created. This may not be acceptable.

  • Prefer std::string to char* for textual types. It's just plain easier that way. And no, char* is not going to be faster in any noticable way. For this code the type used to represent text (provided it's sensible) is never going to be a bottleneck.

  • Testing a pointer for nullness prior to deletion is always redundant. The standard guarantees that deleting a null pointer has no effect.

  • A call to glTexImage2D in addition to gluBuild2DMipmaps is redundant. gluBuild2DMipmaps will build all mipmap levels, including the top level.


Also a note on some of the code that was directly from the original loader: Using xor to swap variables is often a pessimisation, not an optimisation. On the platform I tested it on (Pentium IV) all three compilers I tested produced significantly faster code when using a temporary than when swapping using the xor trick.

Enigma

Share this post


Link to post
Share on other sites
Ok, as always, keep in mind im an opengl nub, as well as c++ freshman.

I cannot get it to bind textures, i used RipTorns version, called the load GL and junk, however when i use the class.bindOpenGL() nothing happens. I tried using "glBindTexture(GL_TEXTURE_2D, class.returnID);" (return(ID) is just a simple accessor method to return openGLid), and it still didnt work. Any ideas on what i am doing wrong? I can paste my code if needed, it's just a simple code with 3 objects, 1 triangle, 2 box, and one glut object, teapot.

Share this post


Link to post
Share on other sites
I can't think of anything that would cause that to happen...
Is it a case of not showing any texture at all, or not changing to a tga texture, but showing a different texture (eg a bitmap)?

if you could zip up your example I'll take a look for sure.
I'll need to install DevC++ or somthing (I'm on holiday ;) but that doesn't matter, I need something to do anyway.

Share this post


Link to post
Share on other sites
Make sure you create your textures after you have a valid OpenGL context (which is created by wglCreateContext if using pure Win32). Also make sure that you have enabled texturing (glEnable(GL_TEXTURE_2D);).

Enigma

Share this post


Link to post
Share on other sites
Awesome! Thanks to you all. And yes Enigma you had my number, iw as not enabling 2D texturing. However, since i have this code copied over (i planned on giving you an example if no one could guess what i was doing wrong), are there any major improvements you can see?
I am sure there are i dunno, 50,000 things stupidly done, keep in mind this has a lot of copy pasted code and whatnot, i am just trying to piece stuff together to get it working enough to learn from (after all, if nothing works, how can i learn lol).

Anyway, so this is simple, if you dont know glut, just ignore the glut stuff and focus on the opengl stuff, the glut stuff is a framework i am using. So there shouldent be anything major wrong with it.


/*
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
*/

#include <iostream>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glut.h>

GLfloat rquad;
GLfloat rtri;
GLfloat xrot;
GLfloat yrot;
GLfloat zrot;
void draw();


class STGA
{
STGA(STGA & tga); // no copying! (memory errors otherwise)

public:
STGA();
STGA(char * file);
~STGA();
void destroy();
int width();
int height();
unsigned char * data();
int channels();
bool load(char *filename);
void loadOpenGL();
void bindOpenGL();
void destroyOpenGL();
unsigned int returnID(){ if(openGLid){ return openGLid; } else{ return 0; } }
private:
unsigned int openGLid;
int imageWidth;
int imageHeight;
unsigned char imageTypeCode;
unsigned char bitCount;
unsigned char* imageData;
int imageChannels;
};
STGA::STGA(STGA & tga) // no copying! (memory errors otherwise)
{
}

STGA::STGA() : imageData(0), imageWidth(0), imageHeight(0), imageTypeCode(0), bitCount(0), imageChannels(0), openGLid(0)
{
}

STGA::STGA(char * file) : imageData(0), imageWidth(0), imageHeight(0), imageTypeCode(0), bitCount(0), imageChannels(0), openGLid(0)
{
load(file);
}

STGA::~STGA()
{
destroy();
}

void STGA::destroy()
{
if (imageData)
delete[] imageData;
imageData=0;
imageWidth=0;
imageHeight=0;
imageTypeCode= 0;
bitCount=0;
imageChannels=0;

destroyOpenGL();
}

int STGA::width()
{
return imageWidth;
}

int STGA::height()
{
return imageHeight;
}

unsigned char * STGA::data()
{
return imageData;
}

int STGA::channels()
{
return imageChannels;
}

bool STGA::load(char *filename)
{
FILE *file;
unsigned char badChar;
short int badInt;
long imageSize;
int colorMode;

file = fopen(filename, "rb");

if (!file)
return false;

fread(&badChar, sizeof(unsigned char), 1, file);
fread(&badChar, sizeof(unsigned char), 1, file);

fread(&imageTypeCode, sizeof(unsigned char), 1, file);

//image type either 2 (color) or 3 (greyscale)
if ((imageTypeCode != 2) && (imageTypeCode != 3))
{
fclose(file);
return false;
}

//13 bytes of useless data
fread(&badInt, sizeof(short int), 1, file);
fread(&badInt, sizeof(short int), 1, file);
fread(&badChar, sizeof(unsigned char), 1, file);
fread(&badInt, sizeof(short int), 1, file);
fread(&badInt, sizeof(short int), 1, file);

//image dimensions
fread(&imageWidth, sizeof(short int), 1, file);
fread(&imageHeight, sizeof(short int), 1, file);

//image bit depth
fread(&bitCount, sizeof(unsigned char), 1, file);

//1 byte of garbage data
fread(&badChar, sizeof(unsigned char), 1, file);

//colorMode -> 3 = BGR, 4 = BGRA
colorMode = bitCount / 8;
imageSize = imageWidth * imageHeight * colorMode;

//allocate memory for image data
imageData = new unsigned char[imageSize];

//read in image data
fread(imageData, sizeof(unsigned char), imageSize, file);

//change BGR to RGB (especially for OpenGL later on)
for (int i = 0; i < imageSize; i += colorMode)
{
//swap blue and red colour value
imageData[i] ^= imageData[i+2] ^=
imageData[i] ^= imageData[i+2];
}

//close file
fclose(file);

imageChannels=colorMode;

return true;
}


void STGA::loadOpenGL()
{
glGenTextures(1, &openGLid);
glBindTexture(GL_TEXTURE_2D, openGLid);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

unsigned int mode=GL_RGB;

if (channels()==4)
mode=GL_RGBA;

glTexImage2D(GL_TEXTURE_2D,0,channels(),width(),height(),0,mode,GL_UNSIGNED_BYTE,data());

gluBuild2DMipmaps(GL_TEXTURE_2D,channels(),width(),height(),mode,GL_UNSIGNED_BYTE,data());
}

void STGA::bindOpenGL()
{
if (openGLid)
glBindTexture(GL_TEXTURE_2D, openGLid);
}

void STGA::destroyOpenGL()
{
if (openGLid)
glDeleteTextures(1, &openGLid);
openGLid=0;
}


STGA tgaFile;



// process menu option 'op'
void menu(int op) {

switch(op) {
case 'Q':
case 'q':
exit(0);
}
}

// executed when a regular key is pressed
void keyboardDown(unsigned char key, int x, int y) {

switch(key) {
case 'Q':
case 'q':
case 27: // ESC
exit(0);
}
}

// executed when a regular key is released
void keyboardUp(unsigned char key, int x, int y) {

}

// executed when a special key is pressed
void keyboardSpecialDown(int k, int x, int y) {

}

// executed when a special key is released
void keyboardSpecialUp(int k, int x, int y) {

}

// reshaped window
void reshape(int width, int height) {

GLfloat fieldOfView = 90.0f;
glViewport (0, 0, (GLsizei) width, (GLsizei) height);

glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(fieldOfView, (GLfloat) width/(GLfloat) height, 0.1, 500.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}


void mouseClick(int button, int state, int x, int y) {

}

void mouseMotion(int x, int y) {

}

// executed when program is idle
void idle() {
draw();
}

// render the scene
void draw() {

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-1.5f,0.0f,-6.0f);

glRotatef(rtri,0.0f,1.0f,0.0f);
glBegin(GL_TRIANGLES); // Start Drawing A Triangle
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)

glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)

glColor3f(1.0f,0.0f,0.0f); // Red

glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)

glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)
glEnd();

glLoadIdentity(); // Reset The Current Modelview Matrix
glTranslatef(1.5f,0.0f,-6.0f); // Move Right 1.5 Units And Into The Screen 6.0
glRotatef(rquad,1.0f,0.0f,0.0f); // Rotate The Quad On The X axis ( NEW )
glRotatef(rquad,0.0f,1.0f,0.0f); // Rotate The Quad On The X axis ( NEW )

glColor3f(0.5f,0.5f,1.0f); // Set The Color To A Nice Blue Shade
glBegin(GL_QUADS); // Start Drawing A Quad
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)

glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange
glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)

glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)

glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Back)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Back)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Back)
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Back)

glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)

glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
glEnd(); // Done Drawing The Quad
glLoadIdentity();
glTranslatef(0.0f,3.0f,-6.0f);
glRotatef(rquad,1.0f,0.0f,0.0f);
tgaFile.bindOpenGL();
//glBindTexture(GL_TEXTURE_2D, tgaFile.returnID());
glutSolidTeapot(1.0f);


glFlush();
glutSwapBuffers();
rtri+=0.2f;
rquad-=0.15f;
}

// initialize OpenGL settings
void initGL(int width, int height) {

reshape(width, height);

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
if (tgaFile.load("data/nehe2.tga"))
{
tgaFile.loadOpenGL();
}

}

// initialize GLUT settings, register callbacks, enter main loop
int main(int argc, char** argv) {

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("EmptyGLUT");

// register glut call backs
glutKeyboardFunc(keyboardDown);
glutKeyboardUpFunc(keyboardUp);
glutSpecialFunc(keyboardSpecialDown);
glutSpecialUpFunc(keyboardSpecialUp);
glutMouseFunc(mouseClick);
glutMotionFunc(mouseMotion);
glutReshapeFunc(reshape);
glutDisplayFunc(draw);
glutIdleFunc(idle);
glutIgnoreKeyRepeat(true); // ignore keys held down

// create a sub menu
int subMenu = glutCreateMenu(menu);
glutAddMenuEntry("Do nothing", 0);
glutAddMenuEntry("Really Quit", 'q');

// create main "right click" menu
glutCreateMenu(menu);
glutAddSubMenu("Sub Menu", subMenu);
glutAddMenuEntry("Quit", 'q');
glutAttachMenu(GLUT_RIGHT_BUTTON);

initGL(800, 600);

glutMainLoop();
return 0;
}


Thanks to anyone who wants to glance over :)

[Edited by - Zeusbwr on December 25, 2004 12:18:59 AM]

Share this post


Link to post
Share on other sites
That looks pretty good since its just a simple program. Obviously as you advance to more complicated programs you'll need to start splitting your code up into more functions and classes, but no need for that at the moment. The only two comments I would make are about your glMatrixMode(GL_MODELVIEW); call at the start of draw(). You will always be in <MODELVIEW mode here since you never switch to anything else without switching back, so the call is redundant. The second point is about initGL();. GLut will automatically call reshape for you when it creates the window, so there is no need to call it yourself. This also frees you from passing the window width and height to this function and means you don't need to have two copies of this data, which could easily get out of sync.

Enigma

Share this post


Link to post
Share on other sites

This topic is 4732 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this