So, I wrote my own cute little 2D tile-based engine that works fine as far as I want it for now :). Only one point is nagging me: is has a FPS of 68.
What it does: it draws 9*9 (and 10*10 if the character is moving) quads, each having its own texture. The texture and the quad are both 64 pixels in width and height. It determines what texture is needed via an array containing numbers indicating what texture to be used on certain positions.
I did some research, and found out that the drawing part took 1000 times more time then anything else together I do per frame...that is nagging me ^^.
How can I optimise my code? I heard about using the GL_TEXTURE_RECTANGLE_EXT extension...but that didn't really do much (nothing to be honest).
The relevant code:
The main function:
class Graphics
{
int width, height, old_width, old_height;
GLuint textures[n_textures];
void draw_rect(GLuint, int, int, int, int);
public:
Graphics(int, int);
~Graphics();
bool init(int, int);
void resize();
void draw();
};
Graphics::Graphics(int width, int height)
{
glewInit();
glfwInit();
if(!glfwOpenWindow(width, height, 0, 0, 0, 0, 0, 0, GLFW_WINDOW))
{
return;
}
glfwSetWindowTitle("GLFW Application");
old_width = old_height = 0;
resize();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_RECTANGLE_EXT);
corona::Image *image;
for (int i = 0; i < n_textures; i++)
{
image = corona::OpenImage(texture_paths);
if (!image)
{
printf("Error: image error");
return;
}
glGenTextures(1, &textures);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textures);
//corona::PixelFormat format = image->getFormat();
glTexParameterf(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGB, image->getWidth(), image->getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, image->getPixels());
}
delete image;
}
Graphics::~Graphics()
{
glDeleteTextures(n_textures, textures);
glfwTerminate();
}
void Graphics::resize()
{
glfwGetWindowSize(&width, &height);
if (width != old_width || height != old_height)
{
height = height > 0 ? height : 1;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, TILE_SIZE*TILES, TILE_SIZE*TILES, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
old_width = width;
old_height = height;
}
}
void Graphics::draw()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
for (int y = 0; y < 9; y++)
{
for (int x = 0; x < 9; x++)
{
draw_rect(textures[map[y][x]], x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);
x++;
}
y++;
}
glfwSwapBuffers();
}
void Graphics::draw_rect(GLuint texture, int x, int y, int w, int h)
{
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, texture);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(x, y);
glTexCoord2i(64, 0); glVertex2i(x+w, y);
glTexCoord2f(64, 64); glVertex2i(x+w, y+h);
glTexCoord2f(0, 64); glVertex2i(x, y+h);
glEnd();
}
const int n_textures = 2;
char *texture_paths[n_textures] = {"data/dirt.png", "data/grass.png"};
int map[18][18] = {
{0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}
};