BITMAP file problem!:(

Started by
6 comments, last by shakurshams 15 years, 1 month ago
i previously posted a problem about my project... now i have a new problem.. i am trying to use a bitmap file as the background of the game..but it makes my game very sloww.. i dont know y here is the code.. related functions are: 1. void DrawBitmap(long width, long height, unsigned char* bitmapImage)=>to draw the image 2.unsignedchar*LoadBitmapFile(char*filename,BITMAPINFOHEADER*bitmapInfoHeader)=>to load the bitmap image..used bfore the main loop in WinMain (to initialise) 3.void DrawMyScene(float q,float x,float w)=>here i do all the drawings.. my code:

#define BITMAP_ID 0x4D42

#include<windows.h>
#include<stdio.h>
#include<time.h>
#include<gl/gl.h>
#include<gl/glu.h>
#include<gl/glaux.h>
 
HDC ghdc;
BITMAPINFOHEADER bitmapInfoHeader;
unsigned char* bitmapData;		
float LIFE=100;
float MISS=30;
float q=.1;
float x=0;
float w=-.1;
bool bull=false;
bool ubull=false;
float j=-.8;
int dsqr0=0;
int dsqr1=0;
int dsqr2=0;
bool countflag=true;
bool exxit=false;
GLuint	texture[1];

struct ball1 // ball structure
{
	float bcord,bycord;
}b;

struct sqr  // square structure
{
	bool alive;
	float k,l;
	float centre;

}a1;
struct sqr1  // square structure
{
	bool alive;
	float k,l;
	float centre;

}a2;

struct sqr2
{
	bool alive;
	float k,l;
	float centre;
}a3;

void DrawBitmap(long width, long height, unsigned char* bitmapImage)
{
	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
	glRasterPos2i(-.99,-.80);
	glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, bitmapImage);
}


unsigned char *LoadBitmapFile(char* filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
  FILE *filePtr=NULL;                 // the file pointer
  BITMAPFILEHEADER bitmapFileHeader;         // bitmap file header
  unsigned char *bitmapImage;             // bitmap image data
  int imageIdx = 0;             // image index counter
  unsigned char tempRGB;                // swap variable

  if (!filename)										
  {
	 MessageBox(NULL,"ERROR nameee","ERROR",NULL);
     return NULL;								
  }
  filePtr = fopen(filename,"r");
  if (filePtr == NULL)
  {
	MessageBox(NULL,"ERROR open","ERROR",NULL);
    return NULL;
  }

  // read the bitmap file header
  fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
  // verify that this is a bitmap by checking for the universal bitmap id
  if (bitmapFileHeader.bfType != BITMAP_ID)
  {
	 MessageBox(NULL,"ERROR ID","ERROR",NULL);
     fclose(filePtr);
     return NULL;
  }
  // read the bitmap information header
  fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);
 // move file pointer to beginning of bitmap data
  fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
  // allocate enough memory for the bitmap image data
  bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
  // verify memory allocation
  if (!bitmapImage)
  {
    free(bitmapImage);
    fclose(filePtr);
    return NULL;
  }
  // read in the bitmap image data
  fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr);
  // make sure bitmap image data was read
  if (bitmapImage == NULL)
  {
    MessageBox(NULL,"ERROR unnn","ERROR",NULL);
    fclose(filePtr);
    return NULL;
  }

   
  // swap the R and B values to get RGB since the bitmap color format is in BGR
  for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3)
  {
   tempRGB = bitmapImage[imageIdx];
   bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
   bitmapImage[imageIdx + 2] = tempRGB;
  }
  // close the file and return the bitmap image data
  fclose(filePtr);
  return bitmapImage;
}


AUX_RGBImageRec *LoadBMP(char *Filename)				
{
	FILE *File=NULL;									
	if (!Filename)										
	{
		return NULL;								
	}


	File=fopen(Filename,"r");						

	if (File)											
	{
		fclose(File);
		
		return auxDIBImageLoad(Filename);			
	}


	return NULL;									
}

int LoadGLTextures()									
{
	int Status=FALSE;									

	AUX_RGBImageRec *TextureImage[1];				

	memset(TextureImage,0,sizeof(void *)*1);           


	if (TextureImage[0]=LoadBMP("shuvo.bmp"))
	{
		
		Status=TRUE;								

		glGenTextures(1, &texture[0]);					

		
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	}

	if (TextureImage[0])									
	{
	
		if (TextureImage[0]->data)						
		{
			free(TextureImage[0]->data);				
		}

		free(TextureImage[0]);								
	}

	return Status;									
}

void checkd1() // position detector
{
  if((b.bcord>=a1.k && b.bcord<=(a1.k+.2)) && b.bycord>=a1.l)
  {
	  bull=ubull=false;
	   b.bcord=x;
	  b.bycord=-.88;
	  a1.alive=false;
  }
  if((b.bcord>=a2.k && b.bcord<=(a2.k+.1)) && b.bycord>=a2.l)
  {
	  bull=ubull=false;
	   b.bcord=x;
	  b.bycord=-.88;
	  a2.alive=false;
  }
  if((b.bcord>=a3.k && b.bcord<=(a3.k+.1)) && b.bycord>=a3.l)
  {
	  bull=ubull=false;
	   b.bcord=x;
	  b.bycord=-.88;
	  a3.alive=false;
  }
}

void updatecentre()  // square er niche nama
{
	a1.l-=.001;
}

void updatecentret()
{
	a2.k+=0.001;
}

void updatecenter()
{
	a3.k-=0.001;
}

void getcount()		// square er x & y
{
	int j;
	if(a1.alive==false)
	{
		a1.k=(rand()%80)/100.000;
		j=a1.k*100;
		if(j%2==1)
			a1.k=-a1.k;
		a1.l=.99;
		a1.alive=true;
		dsqr0++;
		if(dsqr0==15)
			dsqr0=0;
		//a1.centre=a1.k;
	}
}

void getcountt()
{
	if(a2.alive==false)
	{
		a2.l=(rand()%50)/100.000;
		a2.k=-.99;
		a2.alive=true;
		dsqr1++;
		if(dsqr1==15)
			dsqr1=0;
	//	a2.centre=a2.k;
	}
}

void getcounttt()
{
	if(a3.alive==false)
	{
		a3.l=(rand()%50)/100.000;
		a3.k=.99;
		a3.alive=true;
		dsqr2++;
		if(dsqr2==15)
			dsqr2=0;
	//	a3.centre=a3.k;
	}
}

void drawsqr()		// drawing square
{	
	switch(dsqr0)
	{
		case 0:
			glColor3f(.4,1,0);
			break;
		case 1:
			glColor3f(.8,.8,0);
			break;
		case 2:
			glColor3f(.1,.2,.5);
			break;
		case 3:
			glColor3f(.6,.6,.1);
			break;
		case 4:
			glColor3f(.42,.2,.92);
			break;
		case 5:
			glColor3f(.14,.44,.84);
			break;
		case 6:
			glColor3f(.48,.8,0);
			break;
		case 7:
			glColor3f(.11,.6,.43);
			break;
		case 8:
			glColor3f(.55,.7,.5);
			break;
		case 9:
			glColor3f(.6,.7,.8);
			break;
		case 10:
			glColor3f(.39,.46,.50);
			break;
		case 11:
			glColor3f(.24,.30,.34);
			break;
		case 12:
			glColor3f(.81,.13,.21);
			break;
		case 13:
			glColor3f(.82,.15,.49);
			break;
		case 14:
			glColor3f(.4,.4,.4);
			break;
		case 15:
			glColor3f(.6,.6,.6);
			break;
	}
		glBegin(GL_POLYGON);
		  glTexCoord2f(0.0f, 0.0f);glVertex3f(a1.k,a1.l-.1,0);
		  glTexCoord2f(1.0f, 0.0f);glVertex3f(a1.k+.1,a1.l-.1,0);
		  glTexCoord2f(1.0f, 1.0f);glVertex3f(a1.k+.1,a1.l,0);
		  glTexCoord2f(0.0f, 1.0f);glVertex3f(a1.k,a1.l,0);
		glEnd();	
		
}

void drawsqrt()
{
	switch(dsqr1)
	{
		case 0:
			glColor3f(.4,1,0);
			break;
		case 1:
			glColor3f(.8,.8,0);
			break;
		case 2:
			glColor3f(.1,.2,.5);
			break;
		case 3:
			glColor3f(.6,.6,.1);
			break;
		case 4:
			glColor3f(.42,.2,.92);
			break;
		case 5:
			glColor3f(.14,.44,.84);
			break;
		case 6:
			glColor3f(.48,.8,0);
			break;
		case 7:
			glColor3f(.11,.6,.43);
			break;
		case 8:
			glColor3f(.55,.7,.5);
			break;
		case 9:
			glColor3f(.6,.7,.8);
			break;
		case 10:
			glColor3f(.39,.46,.50);
			break;
		case 11:
			glColor3f(.24,.30,.34);
			break;
		case 12:
			glColor3f(.31,.53,.21);
			break;
		case 13:
			glColor3f(.82,.15,.49);
			break;
		case 14:
			glColor3f(.4,.4,.4);
			break;
		case 15:
			glColor3f(.6,.6,.6);
			break;
	}

	glBegin(GL_POLYGON);
		  glTexCoord2f(0.0f, 0.0f);glVertex3f(a2.k,a2.l,0);
		  glTexCoord2f(1.0f, 0.0f);glVertex3f(a2.k+.1,a2.l,0);
		  glTexCoord2f(1.0f, 1.0f);glVertex3f(a2.k+.1,a2.l+.1,0);
		  glTexCoord2f(0.0f, 1.0f);glVertex3f(a2.k,a2.l+.1,0);
	glEnd();
	
}

void drawsqrtt()
{
	switch(dsqr2)
	{
		case 0:
			glColor3f(.4,1,0);
			break;
		case 1:
			glColor3f(.8,.8,0);
			break;
		case 2:
			glColor3f(.1,.2,.5);
			break;
		case 3:
			glColor3f(.6,.6,.1);
			break;
		case 4:
			glColor3f(.42,.2,.92);
			break;
		case 5:
			glColor3f(.14,.44,.84);
			break;
		case 6:
			glColor3f(.48,.8,0);
			break;
		case 7:
			glColor3f(.11,.6,.43);
			break;
		case 8:
			glColor3f(.55,.7,.5);
			break;
		case 9:
			glColor3f(.6,.7,.8);
			break;
		case 10:
			glColor3f(.39,.46,.50);
			break;
		case 11:
			glColor3f(.24,.30,.34);
			break;
		case 12:
			glColor3f(.31,.84,.53);
			break;
		case 13:
			glColor3f(.82,.15,.49);
			break;
		case 14:
			glColor3f(.4,.4,.4);
			break;
		case 15:
			glColor3f(.6,.6,.6);
			break;
	}

	glBegin(GL_POLYGON);
		  glTexCoord2f(0.0f, 0.0f);glVertex3f(a3.k,a3.l,0);
		  glTexCoord2f(1.0f, 0.0f);glVertex3f(a3.k-.1,a3.l,0);
		  glTexCoord2f(1.0f, 1.0f);glVertex3f(a3.k-.1,a3.l+.1,0);
		  glTexCoord2f(0.0f, 1.0f);glVertex3f(a3.k,a3.l+.1,0);
	glEnd();
	
}
void DrawBull()		// drawing bullet
{
	b.bcord=x;
	b.bycord=-.8;
	glColor3f(0,0,1);
	glEnable(GL_POINT_SMOOTH);
	glPointSize(7);
	glBegin(GL_POINTS);
	  glVertex3f(b.bcord,-.8,0);
	glEnd();
	bull=false;
	ubull=true;
}
void UpdateBull()		// updating bullets
{
	b.bycord+=.005;
	if(b.bycord<=1)
	{
	   glColor3f(0,0,1);
	   glPointSize(7);
	   glBegin(GL_POINTS);
	    glVertex3f(b.bcord,b.bycord,0);
	   glEnd();
	}
	else 
	{
		ubull=false;
		b.bycord=-.8;
	}
	
}
void drawline() // drawing border
{
	glLineWidth(5);
	glColor3f(1,0,0);
	glBegin(GL_LINES);
		glVertex3f(-1,-.9,0);
		glVertex3f(1,-.9,0);
	glEnd();
}

void DrawMyScene(float q,float x,float w)		// scene drawing
{
	if(LIFE>0.0)
	{
		int i;
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
		glLoadIdentity();
		glColor3f(1,0,0);
		
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		glEnable(GL_POLYGON_SMOOTH);
	    DrawBitmap(bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight, bitmapData);
		drawline();
		glBegin(GL_TRIANGLES);
		  glVertex3f(q,-.89,0);
		  glVertex3f(x,-.79,0);
		  glVertex3f(w,-.89,0);
		glEnd();
	
		if(countflag==true)
		{	
		 a1.alive=false;
	
		 countflag=false;
		}

		getcount();
		getcountt();
		getcounttt();
		
		if(a1.l>=-.8)
		{	
	    	drawsqr();
			updatecentre();
		}
		else
		{
			a1.alive=false;
			LIFE-=1.0;
		}
	
		if(a2.k<=1)
		{
			drawsqrt();
			updatecentret();
		}
		else
		{
			a2.alive=false;
			LIFE-=.5;
		}
		if(a3.k>=-1)
		{
			drawsqrtt();
			updatecenter();
		}
		else
		{
			a3.alive=false;
			LIFE-=.5;
		}
		
		if(bull)  //draw bull
				DrawBull();
		
		if(ubull)  // update bull
				UpdateBull();		
		checkd1();

		SwapBuffers(ghdc);
	}

	else
	{
		exxit=true;
	}
}

void mypfd(HDC hdc)			// pixel format descriptor
{
	int why;
	static PIXELFORMATDESCRIPTOR pfd={sizeof(PIXELFORMATDESCRIPTOR),1,PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,PFD_TYPE_RGBA,32,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,PFD_MAIN_PLANE,0,0,0,0};
	why=ChoosePixelFormat(hdc,&pfd);
	SetPixelFormat(hdc,why,&pfd);
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)  //windows procedure
{
	static HDC hdc;
	static HGLRC hrc;
	int wi,he;
	switch(msg)
	{
	case WM_CREATE:
		hdc=GetDC(hwnd);
		ghdc=hdc;
		mypfd(hdc);
		hrc=wglCreateContext(hdc);
		wglMakeCurrent(hdc,hrc);
		return 0;
		break;	
	}

	return DefWindowProc(hwnd,msg,wParam,lParam);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR CmdLine,int nShowCmd)
{
	WNDCLASSEX wc;

	wc.cbClsExtra=0;
	wc.cbSize=sizeof(WNDCLASSEX);
	wc.cbWndExtra=0;
	wc.hbrBackground=0;
	wc.hCursor=LoadCursor(NULL,IDC_ARROW); 
	wc.hIcon=0;
	wc.hIconSm=0;
	wc.hInstance=hInstance;
	wc.lpfnWndProc=(WNDPROC)WndProc;
	wc.lpszClassName="game";
	wc.lpszMenuName=0;
	wc.style=CS_VREDRAW|CS_HREDRAW;

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL,"ERROR:Register","ERROR REPORT",NULL);
		return 0;
	}



	HWND hwnd;

	
	hwnd=CreateWindowEx(NULL,"game","GAME",WS_OVERLAPPEDWINDOW,0,0,700,700,0,0,hInstance,0);	
	if(!hwnd)
	{
		MessageBox(NULL,"ERROR:Creating.....","ERROR REPORT",NULL);
		return 0;
	}

	ShowWindow(hwnd,SW_SHOW);
	UpdateWindow(hwnd);

	MSG msg;

	srand(time(0));

	if (!LoadGLTextures())								
	{
		return FALSE;								
	}
    bitmapData = LoadBitmapFile("levv.bmp", &bitmapInfoHeader);

	glEnable(GL_TEXTURE_2D);
	
	bool flag=false;
	while(!flag)		//message loop
	{
		PeekMessage(&msg,hwnd,NULL,NULL,PM_REMOVE);
		if(msg.message==WM_QUIT)
		{
				flag=true;
				MessageBox(NULL,"GAME OVER","FINISH",NULL);
		}
		else
		{
				
	      if(GetAsyncKeyState(VK_LEFT) & 0x8000)
		  {
			q-=.004;
			x-=.004;
			w-=.004;
		  }
		
	      if(GetAsyncKeyState(VK_RIGHT) & 0x8000)
		  {
		    q+=.004;
			x+=.004;
			w+=.004;
		  }
	      
		  if(GetAsyncKeyState(VK_SPACE) & 0x8000)
		    bull=true;
			  
		  if(GetAsyncKeyState(VK_ESCAPE) & 0x8000)
			  msg.message=WM_QUIT;
			
		  DrawMyScene(q,x,w);
		  TranslateMessage(&msg);
		  DispatchMessage(&msg);
		}
		if(exxit==true)
			msg.message=WM_QUIT;
		
	}

	return msg.wParam;
}

i am also having a problem with VC++06 so if u could tell me where the bug is ...it will b very helpful TC
Advertisement
You appear to be using glDrawPixels using raw bitmap data. This means for every frame it effectively re-uploads the whole image to the graphics card.

I notice that you do use glTexImage2D, but never use the texture unit that you uploaded to. Your DrawBitmap function could instead look something like:

void DrawBitmap(long width, long height, unsigned char* bitmapImage){        glEnable(GL_TEXTURE_2D);	glBindTexture(GL_TEXTURE_2D, texture[0]);        //draw a quad or something here with texture coordinates        glBindTexture(GL_TEXTURE_2D, 0);        glDisable(GL_TEXTURE_2D);}


You would not need to pass it the bitmap data every time.
________________________________Blog...
Not related to your problem, but why do define 3 identical structures? Why not do

struct sqr  // square structure{	bool alive;	float k,l;	float centre;};sqr a1;sqr a2;sqr a3;


And yes, Badgerr is correct, you've created the texture, why not use it? The data is already in the VRAM, you're transferring the bitmap data across the bus to your graphics card, every frame! This will be causing your slowdown.
i alredy did texture mapping...and its working good...
for texture rendering i used these functions..
int LoadGLTextures()AUX_RGBImageRec *LoadBMP(char *Filename)	

u will find these in the code i pasted...

but i am trying to use the levv.bmp (in the code) image as the back ground..
and the related functions were mentioned in the previous post...
as i a tried to do that its causing the problem... :)
thnx for ans...
bt i still hav the probzz :(
I started with an array of structure there at first... But after following the same process ( which I am using now ) I din't get things right at all.. Thats why tried different structures with different properties here. But at last used same variables in the structure and forgot to do like u r saying now...

And I am always using the texture on the squares(falling bodies) but my problem is with the background of the project where I want to use the bitmap image ( levv.bmp) which I have mentioned in my last post.. Its an undergoing project and as a beginner of this era of OpenGL programming its killing me...

Thnx for the replies guyss... And keep replying and helping me :P....
The functions you mention aren't for rendering - they are for loading the texture into memory. All you need to do to draw it as a background is use glBindTexture and draw a shape behind everything else in the scene (draw it first). That is all you need to do, the background image will be visible provided you have enabled GL_TEXTURE_2D and drawn a shape with valid texture coordinates. The example I posted will do this, all you need to do is replace the commented line with shape drawing code.
________________________________Blog...
okayy my background image is working fine now...
but i am using the same texture to draw the backgorund and and the square(falling body in the game)..
but i want to load 2 different images...
i tried different ways...
but its not working...
how can i load 2 different images?
and how to use them?
here is the part of the code i used...

the functions are:
if(!LoadGLTextures1("shuvo.bmp"))
{
returnFALSE;
}
if(!LoadGLTextures2("levv.bmp"))
{ returnFALSE; }

and to store:
GLuint texture1[1];
GLuint texture2[1];
AUX_RGBImageRec *LoadBMP(char *Filename)				{	FILE *File=NULL;										if (!Filename)											{		return NULL;									}	File=fopen(Filename,"r");							if (File)												{		fclose(File);				return auxDIBImageLoad(Filename);				}	return NULL;									}int LoadGLTextures2(char* name)									{	int Status=FALSE;									// Status Indicator	AUX_RGBImageRec *TextureImage1[1];					// Create Storage Space For The Texture	memset(TextureImage1,0,sizeof(void *)*1);           	// Set The Pointer To NULL	// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit	if (TextureImage1[0]=LoadBMP(name))	{		Status=TRUE;									// Set The Status To TRUE		glGenTextures(1, &texture2[0]);					// Create The Texture		// Typical Texture Generation Using Data From The Bitmap		glBindTexture(GL_TEXTURE_2D, texture2[0]);		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage1[0]->sizeX, TextureImage1[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage1[0]->data);		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	}	if (TextureImage1[0])									// If Texture Exists	{		if (TextureImage1[0]->data)							// If Texture Image Exists		{			free(TextureImage1[0]->data);					// Free The Texture Image Memory		}		free(TextureImage1[0]);								// Free The Image Structure	}	return Status;												}int LoadGLTextures1(char* name)									{	int Status=FALSE;									// Status Indicator	AUX_RGBImageRec *TextureImage[1];					// Create Storage Space For The Texture	memset(TextureImage,0,sizeof(void *)*1);           	// Set The Pointer To NULL	// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit	if (TextureImage[0]=LoadBMP(name))	{		Status=TRUE;									// Set The Status To TRUE		glGenTextures(1, &texture1[0]);					// Create The Texture		// Typical Texture Generation Using Data From The Bitmap		glBindTexture(GL_TEXTURE_2D, texture1[0]);		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	}	if (TextureImage[0])									// If Texture Exists	{		if (TextureImage[0]->data)							// If Texture Image Exists		{			free(TextureImage[0]->data);					// Free The Texture Image Memory		}		free(TextureImage[0]);								// Free The Image Structure	}	return Status;												}
okayy okayyy :D dat was a silly mestake...
i was trying to load a 700x700 bitmap...
bt when i made it 128x128 its working fine..
my game is doing absolutely f9...
btw i still want to knoww if there is ne efficient way to load multiple bitmaps..
thnx guys for ur support..
i am so grateful to u :)
\m/..\m/

This topic is closed to new replies.

Advertisement