Displaying Texture OOP

Started by
15 comments, last by python_regious 19 years, 7 months ago
I am trying to setup some textured quads that are in one class, while I initialize the texture in another class. Basicly I have 2 classes, Block and Map. The Block class holds the draw info, while the textures are loaded in the init of the Map class. I declare the texture array global(I know, bad me), and call the extern to access them in the Block class. When ever it comiles and runs though, the textures do not show up. I have verified the textures do load and are in the correct file path. Here is the code. Block (important parts of class)

extern Texture blockTexture[8];
...
//Draw block
void Block::drawBlock()
{ 
	glSetupTexture(blockTexture[text].ID);
	enginelog.Write(2, "%d", text);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0f, 0.0f);
			glVertex3f(box[0].x+position.x, box[0].y+position.y,  1.0f);	
			glTexCoord2f(1.0f, 0.0f);
			glVertex3f(box[1].x+position.x, box[1].y+position.y,  1.0f);	
			glTexCoord2f(1.0f, 1.0f);
			glVertex3f(box[2].x+position.x, box[2].y+position.y,  1.0f);	
			glTexCoord2f(0.0f, 1.0f);
			glVertex3f(box[3].x+position.x, box[3].y+position.y,  1.0f);	
		glEnd();
	glDeleteTex();
}

//Set Texture Unit
void Block::setTexture(int image)
{
	text = image;
}

Map (important part of class)

Texture blockTexture[8];
//Map Constructor
Map::Map()
{
	Vector4 color;
	Vector4 position;

	color.x = 0.0f;
	color.y = 0.0f;
	color.z = 0.0f;

	position.x = 0.0f;
	position.y = 0.0f;

	for (int r = 0;r < MAPSIZER; r++)
	{
		for (int c =0;c < MAPSIZEC;c++)
		{
			level[r][c].setColor(color);
			level[r][c].setPosition(position);
		}
	}


	if(!blockTexture[0].LoadTGAFile("data/red.tga"))
	{MessageBox(NULL, "Cannot Load data/red.tga", "Error", MB_OK);}
	if(blockTexture[0].textureExist)
	{MessageBox(NULL, "Loaded red.tga::Red Block", "Texture", MB_OK);}
	
	if(!blockTexture[1].LoadTGAFile("data/green.tga"))
	{MessageBox(NULL, "Cannot Load data/green.tga", "Error", MB_OK);}
	
	if(!blockTexture[2].LoadTGAFile("data/blue.tga"))
	{MessageBox(NULL, "Cannot Load data/blue.tga", "Error", MB_OK);}
	
	if(!blockTexture[3].LoadTGAFile("data/orange.tga"))
	{MessageBox(NULL, "Cannot Load data/orange.tga", "Error", MB_OK);}
	
	if(!blockTexture[4].LoadTGAFile("data/pink.tga"))
	{MessageBox(NULL, "Cannot Load data/pink.tga", "Error", MB_OK);}
	
	if(!blockTexture[5].LoadTGAFile("data/yellow.tga"))
	{MessageBox(NULL, "Cannot Load data/yellow.tga", "Error", MB_OK);}
	
	if(!blockTexture[6].LoadTGAFile("data/grey.tga"))
	{MessageBox(NULL, "Cannot Load data/grey.tga", "Error", MB_OK);}
	
	if(!blockTexture[7].LoadTGAFile("data/blank.tga"))
	{MessageBox(NULL, "Cannot Load data/blank.tga", "Error", MB_OK);}

}

//Map File Parser
Block Map::parseInput(char input, int r, int c)
{
	Block temp;

	Vector4 color;
	Vector4 position;

	int	alive;
	int solid;
	int text;

	switch(input)
	{
	 case '0':
		 color.x = 0.0f;
		 color.y = 0.0f;
		 color.z = 0.0f;

		 text = 7;			// Blank

		 alive = 0;
		 solid = 0;
		 break;
	 case 'S':				// Grey Solid Block
		 color.x = 0.4f;
		 color.y = 0.4f;
		 color.z = 0.4f;

		text = 6;

		 alive = 1;
		 solid = 1;
		 break;
	 case 'R':				// Red Block
		 color.x = 1.0f;
		 color.y = 0.0f;
		 color.z = 0.0f;

		 text = 0;

		 alive = 1;
		 solid = 0;
		 break;
	 case 'G':				// Green Block
		 color.x = 0.0f;
		 color.y = 1.0f;
		 color.z = 0.0f;

		 text = 1;

		 alive = 1;
		 solid = 0;
		 break;
	 case 'B':				// Blue Block
		 color.x = 0.0f;
		 color.y = 0.0f;
		 color.z = 1.0f;

		 text = 2;

		 alive = 1;
		 solid = 0;
		 break;
	 case 'Y':				// Yellow Block
		 color.x = 1.0f;
		 color.y = 1.0f;
		 color.z = 0.0f;

		 text = 5;

		 alive = 1;
		 solid = 0;
		 break;
	 case 'P':
		 color.x = 0.0f;	// Pink Block
		 color.y = 1.0f;
		 color.z = 1.0f;

		 text = 4;

		 alive = 1;
		 solid = 0;
		 break;

	 case 'O':				// Orange Block
		 color.x = 1.0f;
		 color.y = 0.5f;
		 color.z = 0.5f;

		 text = 3;

		 alive = 1;
		 solid = 0;
		 break;
	 default:				// Default NO BLOCK
		 color.x = 0.0f;
		 color.y = 0.0f;
		 color.z = 0.0f;

		 text = 7;

		 alive = 0;
		 solid = 0;
	}

	position.x = -c;
	position.y = -r;

	temp.setColor(color);
	temp.setPosition(position);
	temp.setAlive(alive);
	temp.setSolid(solid);
	temp.setTexture(text);

	return temp;
}

I have run checks to make sure the correct texture unit is being called, and all seems to be going good, but it just draws the blocks as white. By the way my texture setup functions just enables texture2d and binds the texture. dimebag
Advertisement
Whats in glSetupTexture(blockTexture[text].ID)?

What texture environment is being used?
Is texturing enabled?
If at first you don't succeed, redefine success.
glSetupTexture() and glDeleteTex() are just utility functions I have setup.

//Setup Texture Unitvoid glSetupTexture(unsigned int tex){	glEnable(GL_TEXTURE_2D);	glBindTexture(GL_TEXTURE_2D, tex);}//Release Texture informationvoid glDeleteTex(){	glDisable(GL_TEXTURE_2D);	glBindTexture(GL_TEXTURE_2D, NULL);}



I know they work, cause I use it for my background and a few other things. They have always worked in the past as well. I use them to setup multitexture or bump depending on the card. (Few other functions of course).

If I just declare one texture(red.tga for example) and use it instead of blockTexture[0].ID, it works fine. but of course all the blocks are not red.

dimebag
Ok, then blockTexture[0].ID isn't correct. I assume ID is an unsigned int? Step through your program with a debugger, and look at their values. Or print them to a log file or something.
If at first you don't succeed, redefine success.
Ok, you were right about the blockTexture ID not being correct. For some reason it is 0 for all textures in the array. My question is, how can I get it working. I originaly wanted to load the textures in the block class, but I create 100+ blocks per frame, and I don't want to load the textures every time a block is created.

I know there is a way to create a variable(texture in my case) that is static for all instances of class Block, but I am unsure of how to procede with this. If I can make the blockTexture[8] part of the block class, but have only one instance of it, that would be ideal for me.

something like:
class Block{   public:      //constructor      //destructor            //misc function      //some kind of const function that loads all textures once         //for all instances of block      static const textureInit();   private:      //private variables      static const blockTexture[8];};


There might be errors here as I am unfamiliar with having const variables in a class in this situation.

Thanks,
dimebag
I used the old noodle and figured things out to a point. I have my static texture array, but when compile time comes I get linking errors.

Error:
block.obj : error LNK2001: unresolved external symbol "public: static class Texture * Block::blockTexture" (?blockTexture@Block@@2PAVTexture@@A)Debug/3DEngine.exe : fatal error LNK1120: 1 unresolved externalsError executing link.exe.


Here is my block class
#ifndef _BLOCKH__#define _BLOCKH__#include "vector.h"#include "texture.h"class Block{public:	Block();	~Block(){}	Block(Vector4 iColor, Vector4 iPosition);	Vector4 getPosition(){return position;}	Vector4 getColor(){return color;}	void setPosition(Vector4 iPosition);	void setColor(Vector4 iColor);	void setAlive(int iAlive);	void setSolid(int iSolid);	void setTexture(int image);	int isAlive(){return alive;}	int isSolid(){return solid;}	void drawBlock();	void print();	void textureInit();private:	Vector4 position;	Vector4 box[4];	Vector4 color;	int		special;	int		alive;	int		solid;	int text;	static Texture blockTexture[8];};#endif


Here is the texture init function
void Block::textureInit(){	if(!blockTexture[0].LoadTGAFile("data/red.tga"))	{MessageBox(NULL, "Cannot Load data/red.tga", "Error", MB_OK);}		if(!blockTexture[1].LoadTGAFile("data/green.tga"))	{MessageBox(NULL, "Cannot Load data/green.tga", "Error", MB_OK);}		if(!blockTexture[2].LoadTGAFile("data/blue.tga"))	{MessageBox(NULL, "Cannot Load data/blue.tga", "Error", MB_OK);}		if(!blockTexture[3].LoadTGAFile("data/orange.tga"))	{MessageBox(NULL, "Cannot Load data/orange.tga", "Error", MB_OK);}		if(!blockTexture[4].LoadTGAFile("data/pink.tga"))	{MessageBox(NULL, "Cannot Load data/pink.tga", "Error", MB_OK);}		if(!blockTexture[5].LoadTGAFile("data/yellow.tga"))	{MessageBox(NULL, "Cannot Load data/yellow.tga", "Error", MB_OK);}		if(!blockTexture[6].LoadTGAFile("data/grey.tga"))	{MessageBox(NULL, "Cannot Load data/grey.tga", "Error", MB_OK);}		if(!blockTexture[7].LoadTGAFile("data/blank.tga"))	{MessageBox(NULL, "Cannot Load data/blank.tga", "Error", MB_OK);}}


I would think this would work, but something is junking up the works.

Thanks for you replies,
dimebag
By the looks of things, the implementation of Texture isn't being found. Try cleaning the intermediate files, and rebuilding...

On another note, instead of having the textures static, just pass a pointer to the array as an argument to drawBlock().
If at first you don't succeed, redefine success.
This is troublesome. Am I initializing the static members correctly? I still get the smae error.

I thought about doing the pointer, but I wanted to keep the textures in the block class.

dimebag
Oh, I just think I've remember what your problem is.

You haven't initialised your variable. Try putting something like...
Texture Block::blockTexture[8];
in the block source file... I can't remember the exact syntax for initialisng static arrays, but it shouldn't be too far off from that.
If at first you don't succeed, redefine success.
This all boils down to me begin STUPID. I was trying to initialize the texture before I setup my gl stuff. Since the textures where initialized globaly, they were begin generated first, before gl stuff, so the textures never really got created.

Thanks for your help through this, I appreciate it. I feel very foolish for not realizing this earlier.

dimebag

This topic is closed to new replies.

Advertisement