Skip to main content
GameDev.net gamedev.net
🔒 Locked

2D tile drawing

Started by Arith Jan 4, 2009 at 1:13 PM 7 replies 1k views
Original Post
Arith
Arith
Hello there. To start.. I am relatively green at GL programming. I've tried to find info on this, but nothing to address this particular problem. Knowing this, be gentle :D On to the issue. I am writing a 2D game in allegrogl. (The problem lies with the GL side of things. If this is in the wrong forum, please accept my apologies) Anyway, here is my drawing code; ----------------------------------------------------- void RSMAP::Draw(const float scale) { float zvalue = -2.0; int lx, ly; glEnable(GL_TEXTURE_2D); if (scale ==0) {allegro_message("Warning! Map scale is zero!");} for (ly=0;ly<=MAPW;ly++) { for (lx=0;lx<=MAPH;lx++) { glBindTexture(GL_TEXTURE_2D, Tile[lx][ly].texture); glBegin(GL_QUADS); glColor3f(1.0, 1.0, 1.0); glTexCoord2f( 0, 0); glVertex3f(lx , ly , zvalue); glTexCoord2f( 1, 0); glVertex3f(lx +scale, ly , zvalue); glTexCoord2f( 1, 1); glVertex3f(lx +scale, ly +scale, zvalue); glTexCoord2f( 0, 1); glVertex3f(lx , ly +scale, zvalue); glEnd(); } } } --------------------------------------------------------------------- Now, I'm aware scale doesn't do what it implies. I took out the "proper" code in lieu of debugging. Scale is always 1 for now. The texture loads properly and all that jazz. Anyway, to further explain the problem. The code as it is, is SLOW. 15fps slow. I've determined it's because of the calls to glbegin/end. If I move glbegin/end to the outside of the nested loops, it gets a good 15fps boost, however bind texture doesn't work inside glbegin/end as you all probably know. I may be wrong and it may be all those calls to glbindtexture, but I digress. Every tile has it's own GLuint Texture; inside of Tile[x][y]. MAPW/MAPH are defines (currently 100x100). The question is.. am I approaching this properly.. and if so.. how are you supposed to set each tile's texture? Thanks. Arith
CableGuy
CableGuy
If you are sure that this is the cause for the slowdown then you should render all the tiles that use the same texture in one go. I never checked it but I guess that calling glBindTexture 10,000 times might be a bit slow...

HTH.
sebbit
sebbit
Another way to save glBindTexture calls would be to pack all of your tile textures into one big texture atlas and use texture coordinates to select the right part of the big texture for each tile.
Arith
Arith
Hm.. you present an interesting idea.. I'm loading the textures as one big image to begin with anyway. Thanks (both of you)
Wurzt
Wurzt
What's the size of the texture? (Height and width)
Arith
Arith
The "large" image is 1024x1024, each tile is 64x64
Arith
Arith
Further problems.. I've been trying to put the texture atlas idea to work, but I ran into a strange problem. As I move my sprites, or zoom the camera out, the textures on the map change. ONLY when I move one and or the other.. I'm rather tired, so I may have just done something stupid.. but I've been wracking my brain for quite some time without any headway. Here is the code as it is now;

---------MAP.CPP----------------
void RSMAP::Draw(const float scale)
{
float zvalue = -2.0;
int lx, ly, tmpid;
float texx, texy;

glEnable(GL_TEXTURE_2D);

if (scale ==0) {allegro_message("Warning! Map scale is zero!");}

glBindTexture(GL_TEXTURE_2D, Tileset);
glBegin(GL_QUADS);
for (ly=0;ly<=MAPW;ly++)
{
for (lx=0;lx<=MAPH;lx++)
{

tmpid =0;
texy =1;
while (tmpid != Tile[lx][ly].TileID)
{
if (texx >= 1)
{
texx=0;
texy-=TILESIZE;
}
else texx +=TILESIZE;

if (texy <=0) texy=1;

tmpid++;
}


glColor3f(1.0, 1.0, 1.0);
glTexCoord2f( texx , texy ); glVertex3f(lx , ly , zvalue);
glTexCoord2f( texx+TILESIZE, texy ); glVertex3f(lx +scale, ly , zvalue);
glTexCoord2f( texx+TILESIZE, texy+TILESIZE); glVertex3f(lx +scale, ly +scale, zvalue);
glTexCoord2f( texx , texy+TILESIZE); glVertex3f(lx , ly +scale, zvalue);
}
}

glEnd();

}
--------------------------


and just in case you need to see my main loop..

--------MAIN.CPP-------------
while (!key[KEY_ESC])
{
tmptimer = Tick;

// This is just a test blurb. Has nothing to do with the map at all
if (key[KEY_SPACE])
if (Sprite[0].Binding.isbound == 0)
Sprite[0].Binding.isbound = 1;
else Sprite[0].Binding.isbound =0;

// very VERY basic, half assed camera...
if (key[KEY_PGUP]) zoom += 0.05;
if (key[KEY_PGDN]) zoom -= 0.05;
if (key[KEY_HOME]) zoom =0;
if (zoom >= 1) zoom -=0.05;;
//if (zoom <= -0.15) zoom = -0.15;

glPushMatrix();

glTranslatef(0,0 ,zoom);

Update_sprites();
TestMap.Draw(1);


allegro_gl_flip();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPopMatrix();
while (Tick == tmptimer) rest(0);

}
return 0;
}

-----------------------------



TILESIZE is a define 1/16 (as I have a 16x16 tile texturemap). I'm also pretty new to the whole texture coordinate thing, but this is what I came up with after reading the OpenGL superbible's take on the subject.. so I hope I got it right. Any help would be appreciated.

Thanks


Arith
Arith
Arith
Nevermind.... I did something stupid..
I didn't initialize "texx". Sorry, heh. Told you I was tired :D
iliak
iliak
Have a look at my engine here if you want to see how I handle 2D tiling in OpenGL (look in ArcEngine/Layer.cs)
- Iliak -
[ ArcEngine: An open source .Net gaming framework ]
[ Dungeon Eye: An open source remake of Eye of the Beholder II ]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.