diff --git a/src/Makefile b/src/Makefile index 5e45635e..5bbf388e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ -SRC = test-map.cpp video.cpp +SRC = test-map.cpp video.cpp tiler.cpp all: test-map diff --git a/src/test-map.cpp b/src/test-map.cpp index 53139e8d..305d9790 100644 --- a/src/test-map.cpp +++ b/src/test-map.cpp @@ -1,65 +1,22 @@ // Test stuff -#ifdef WIN32 -# define WIN32_LEAN_AND_MEAN -# include -#endif -#if defined __APPLE__ && defined __MACH__ -# include -#else -# define GL_GLEXT_PROTOTYPES -# include -# include -#endif - #include -#include #include #include #include "video.h" +#include "tiler.h" -/* Storage for one texture */ -GLuint texture[1]; - -/* Storage for 3 vertex buffers */ -GLuint buflist[3]; +/* Global objects */ +Video *video; +Tiler *tiler; /* Storage for map layers */ int *layers[128]; int width = 32, height = 32; int nlayers = 0; -/* Player coordinates */ -int playerx = 0, playery = 0; - -// Load Bitmaps And Convert To Textures -void LoadGLTextures(void) -{ - SDL_Surface *image1 = IMG_Load("art/test/groundtest.png"); - - if (!image1) - { - SDL_Quit(); - exit(1); - } - - glGenTextures(1, &texture[0]); - glBindTexture(GL_TEXTURE_2D, texture[0]); - - glTexImage2D(GL_TEXTURE_2D, 0, 4, image1->w, image1->h, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image1->pixels); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); -}; - -void MakeVBOs(void) -{ - glGenBuffers(3, buflist); -} - void LoadMap(void) { FILE *fp = popen("grep '^ ' maps/testmap.tmx | while read i; do echo -n \"$i\" | perl -MMIME::Base64 -ne 'print decode_base64($_)' | gunzip; done", "r"); @@ -84,139 +41,33 @@ void LoadMap(void) } } -void PutMap(int const *themap, int width, int height) -{ - // Put map - float uvs[8 * width * height]; - - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) - { - int tile = themap[width * y + x]; - float ty = .0625f * (tile / 16); - float tx = .0625f * (tile % 16); - uvs[8 * (width * y + x) + 0] = tx; - uvs[8 * (width * y + x) + 1] = ty; - uvs[8 * (width * y + x) + 2] = tx + .0625f; - uvs[8 * (width * y + x) + 3] = ty; - uvs[8 * (width * y + x) + 4] = tx + .0625f; - uvs[8 * (width * y + x) + 5] = ty + .0625f; - uvs[8 * (width * y + x) + 6] = tx; - uvs[8 * (width * y + x) + 7] = ty + .0625f; - } - glBindBuffer(GL_ARRAY_BUFFER, buflist[1]); - glBufferData(GL_ARRAY_BUFFER, - 8 * width * height * sizeof(float), uvs, GL_STATIC_DRAW); - - float vertices[8 * width * height]; - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) - { - vertices[8 * (width * y + x) + 0] = x * 32; - vertices[8 * (width * y + x) + 1] = y * 32; - vertices[8 * (width * y + x) + 2] = x * 32 + 32; - vertices[8 * (width * y + x) + 3] = y * 32; - vertices[8 * (width * y + x) + 4] = x * 32 + 32; - vertices[8 * (width * y + x) + 5] = y * 32 + 32; - vertices[8 * (width * y + x) + 6] = x * 32; - vertices[8 * (width * y + x) + 7] = y * 32 + 32; - } - glBindBuffer(GL_ARRAY_BUFFER, buflist[0]); - glBufferData(GL_ARRAY_BUFFER, - 8 * width * height * sizeof(float), vertices, GL_STATIC_DRAW); - - int indices[4 * width * height]; - for (int n = 0; n < 4 * width * height; n++) - indices[n] = n; - glBindBuffer(GL_ARRAY_BUFFER, buflist[2]); - glBufferData(GL_ARRAY_BUFFER, - 4 * width * height * sizeof(int), indices, GL_STATIC_DRAW); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_INDEX_ARRAY); - - glBindTexture(GL_TEXTURE_2D, texture[0]); - - glBindBuffer(GL_ARRAY_BUFFER, buflist[0]); - glVertexPointer(2, GL_FLOAT, 0, NULL); - glBindBuffer(GL_ARRAY_BUFFER, buflist[1]); - glTexCoordPointer(2, GL_FLOAT, 0, NULL); - glBindBuffer(GL_ARRAY_BUFFER, buflist[2]); - glIndexPointer(GL_INT, 0, NULL); - - glDrawArrays(GL_QUADS, 0, 4 * width * height); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_INDEX_ARRAY); -} - /* The main drawing function. */ void DrawScene() { -/* - int ground[20 * 15] = - { -18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, -18, 1, 2, 2, 2, 34, 2, 2, 2, 2, 2, 2, 3, 34, 4, 18, 18, 18, 18, 18, -18, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 20, 4, 18, 18, 18, 18, -18, 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 19, 18, 18, 18, 18, -18, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 17, 18, 18, 18, 18, -18, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 18, 20, 36, 18, 18, 18, 18, -18, 33, 2, 2, 2, 2, 2, 2, 2, 2, 34, 2, 35, 2, 36, 18, 18, 18, 18, 18, -18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, -16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - }; - - int l1objects[20 * 15] = - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 49, 49, 49, 49, 0, 0, 0, 0, 25, 9, 9, 9, 8, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 40, 39, 39, 41, 0, 0, - 0, 0, 0, 49, 49, 32, 0, 50, 0, 0, 0, 48, 0, 24, 23, 54, 40, 55, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 64, 0, 24, 23, 24, 23, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 38, 24, 23, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 38, 22, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; -*/ - - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); - glLoadIdentity(); + video->Clear(); for (int i = 0; i < nlayers; i++) - { - glPushMatrix(); - if (i == 2) - glTranslatef(playerx, playery, 0.0f); - PutMap(layers[i], width, height); - glPopMatrix(); - } + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) + tiler->AddTile(layers[i][y * width + x], x * 32, y * 32, i); + + /* Test stuff */ + int playerx, playery; + SDL_GetMouseState(&playerx, &playery); + tiler->AddTile(50, playerx, playery, nlayers); + + tiler->Render(); + video->Refresh(33.33333f); } int main(int argc, char **argv) { - Video *video = new Video("Deus Hax", 640, 480); + video = new Video("Deus Hax", 640, 480); + tiler = new Tiler(); int done; /* Loop, drawing and checking events */ - LoadGLTextures(); - MakeVBOs(); LoadMap(); done = 0; @@ -224,10 +75,6 @@ int main(int argc, char **argv) { DrawScene(); - video->Refresh(33.33333f); - - SDL_GetMouseState(&playerx, &playery); - /* This could go in a separate function */ SDL_Event event; while (SDL_PollEvent(&event)) @@ -244,6 +91,7 @@ int main(int argc, char **argv) } } + delete tiler; delete video; return EXIT_SUCCESS; diff --git a/src/tiler.cpp b/src/tiler.cpp new file mode 100644 index 00000000..a1f40822 --- /dev/null +++ b/src/tiler.cpp @@ -0,0 +1,165 @@ + +#ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +# include +#endif +#if defined __APPLE__ && defined __MACH__ +# include +#else +# define GL_GLEXT_PROTOTYPES +# include +# include +#endif + +#include +#include + +#include + +#include "tiler.h" + +/* + * Tiler implementation class + */ + +class TilerData +{ + friend class Tiler; + +private: + int *tiles; + int ntiles; + + GLuint texture[1]; + GLuint buflist[3]; +}; + +/* + * Public Tiler class + */ + +Tiler::Tiler() +{ + data = new TilerData(); + data->tiles = NULL; + data->ntiles = 0; + + /* One tile texture */ + SDL_Surface *img = IMG_Load("art/test/groundtest.png"); + + if (!img) + { + SDL_Quit(); + exit(1); + } + + glGenTextures(1, &data->texture[0]); + glBindTexture(GL_TEXTURE_2D, data->texture[0]); + + glTexImage2D(GL_TEXTURE_2D, 0, 4, img->w, img->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, img->pixels); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + /* Three GPU buffers */ + glGenBuffers(3, data->buflist); +} + +Tiler::~Tiler() +{ + free(data->tiles); + delete data; +} + +void Tiler::AddTile(int n, int x, int y, int z) +{ + if ((data->ntiles % 1024) == 0) + { + data->tiles = (int *)realloc(data->tiles, + (data->ntiles + 1024) * 4 * sizeof(int)); + } + + data->tiles[4 * data->ntiles] = n; + data->tiles[4 * data->ntiles + 1] = x; + data->tiles[4 * data->ntiles + 2] = y; + data->tiles[4 * data->ntiles + 3] = z; + + data->ntiles++; +} + +void Tiler::Render() +{ + /* Texture coord buffer */ + float uvs[8 * data->ntiles]; + for (int n = 0; n < data->ntiles; n++) + { + int tile = data->tiles[4 * n]; + float ty = .0625f * (tile / 16); + float tx = .0625f * (tile % 16); + uvs[8 * n + 0] = tx; + uvs[8 * n + 1] = ty; + uvs[8 * n + 2] = tx + .0625f; + uvs[8 * n + 3] = ty; + uvs[8 * n + 4] = tx + .0625f; + uvs[8 * n + 5] = ty + .0625f; + uvs[8 * n + 6] = tx; + uvs[8 * n + 7] = ty + .0625f; + } + glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]); + glBufferData(GL_ARRAY_BUFFER, + 8 * data->ntiles * sizeof(float), uvs, GL_STATIC_DRAW); + + /* Vertex buffer */ + float vertices[8 * data->ntiles]; + for (int n = 0; n < data->ntiles; n++) + { + int x = data->tiles[4 * n + 1]; + int y = data->tiles[4 * n + 2]; + vertices[8 * n + 0] = x; + vertices[8 * n + 1] = y; + vertices[8 * n + 2] = x + 32; + vertices[8 * n + 3] = y; + vertices[8 * n + 4] = x + 32; + vertices[8 * n + 5] = y + 32; + vertices[8 * n + 6] = x; + vertices[8 * n + 7] = y + 32; + } + glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]); + glBufferData(GL_ARRAY_BUFFER, 8 * data->ntiles * sizeof(float), + vertices, GL_STATIC_DRAW); + + /* Index buffer */ + int indices[4 * data->ntiles]; + for (int n = 0; n < 4 * data->ntiles; n++) + indices[n] = n; + glBindBuffer(GL_ARRAY_BUFFER, data->buflist[2]); + glBufferData(GL_ARRAY_BUFFER, 4 * data->ntiles * sizeof(int), + indices, GL_STATIC_DRAW); + + /* Draw everything */ + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_INDEX_ARRAY); + + glBindTexture(GL_TEXTURE_2D, data->texture[0]); + + glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]); + glVertexPointer(2, GL_FLOAT, 0, NULL); + glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]); + glTexCoordPointer(2, GL_FLOAT, 0, NULL); + glBindBuffer(GL_ARRAY_BUFFER, data->buflist[2]); + glIndexPointer(GL_INT, 0, NULL); + + glDrawArrays(GL_QUADS, 0, 4 * data->ntiles); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_INDEX_ARRAY); + + /* Empty our shit */ + free(data->tiles); + data->tiles = NULL; + data->ntiles = 0; +} + diff --git a/src/tiler.h b/src/tiler.h new file mode 100644 index 00000000..fae95892 --- /dev/null +++ b/src/tiler.h @@ -0,0 +1,22 @@ + + +/* + * The tile manager + */ + +class TilerData; + +class Tiler +{ +public: + Tiler(); + ~Tiler(); + + void AddTile(int n, int x, int y, int z); + + void Render(); + +private: + TilerData *data; +}; + diff --git a/src/video.cpp b/src/video.cpp index 9a1d1fa1..f248d12a 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -90,6 +90,12 @@ int Video::GetHeight() const return data->video->h; } +void Video::Clear() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); +} + void Video::Refresh(float milliseconds) { if (milliseconds > 0.0f) diff --git a/src/video.h b/src/video.h index 98e80731..acd8ebf2 100644 --- a/src/video.h +++ b/src/video.h @@ -9,6 +9,7 @@ public: int GetWidth() const; int GetHeight() const; + void Clear(); void Refresh(float milliseconds); void FullScreen();