Переглянути джерело

Rendering starts to work again. There is no Z-sorting yet.

legacy
Sam Hocevar sam 14 роки тому
джерело
коміт
a9b63620d4
15 змінених файлів з 181 додано та 137 видалено
  1. +2
    -1
      src/Makefile
  2. +51
    -0
      src/game.cpp
  3. +25
    -0
      src/game.h
  4. +9
    -12
      src/layer.cpp
  5. +4
    -4
      src/layer.h
  6. +5
    -3
      src/map.cpp
  7. +2
    -4
      src/map.h
  8. +45
    -1
      src/scene.cpp
  9. +3
    -1
      src/scene.h
  10. +7
    -13
      src/test-map.cpp
  11. +7
    -0
      src/tiler.cpp
  12. +4
    -0
      src/tiler.h
  13. +13
    -94
      src/tileset.cpp
  14. +3
    -3
      src/tileset.h
  15. +1
    -1
      src/video.cpp

+ 2
- 1
src/Makefile Переглянути файл

@@ -1,5 +1,6 @@

SRC = test-map.cpp video.cpp tiler.cpp tileset.cpp scene.cpp layer.cpp map.cpp
SRC = test-map.cpp \
game.cpp video.cpp tiler.cpp tileset.cpp scene.cpp layer.cpp map.cpp

all: test-map



+ 51
- 0
src/game.cpp Переглянути файл

@@ -0,0 +1,51 @@

#include "game.h"
#include "map.h"

/*
* Game implementation class
*/

class GameData
{
friend class Game;

private:
Map *map;
int x, y;
int mousex, mousey;
};

/*
* Public Game class
*/

Game::Game(char const *mapname)
{
data = new GameData();
data->map = new Map(mapname);
data->x = data->y = 0;
}

Game::~Game()
{
delete data->map;
delete data;
}

void Game::SetMouse(int x, int y)
{
data->mousex = x;
data->mousey = y;
}

void Game::Render()
{
Scene *scene = new Scene();

data->map->Render(scene, data->mousex, data->mousey, 0);

scene->Render();
delete scene;
}


+ 25
- 0
src/game.h Переглянути файл

@@ -0,0 +1,25 @@

/*
* The game object
*/

#if !defined __DH_GAME_H__
#define __DH_GAME_H__

class GameData;

class Game
{
public:
Game(char const *mapname);
~Game();

void SetMouse(int x, int y);
void Render();

private:
GameData *data;
};

#endif // __DH_GAME_H__


+ 9
- 12
src/layer.cpp Переглянути файл

@@ -3,11 +3,11 @@

#include "layer.h"

Layer::Layer(int w, int h, int in_z, uint32_t *in_data)
Layer::Layer(int w, int h, int z, uint32_t *in_data)
{
width = w;
height = h;
z = in_z;
altitude = z;
data = in_data;

#if 0
@@ -26,20 +26,17 @@ Layer::~Layer()
free(data);
}

void Layer::Draw()
void Layer::Render(Scene *scene, int x, int y, int z)
{
for (int y = 0; y < 32; y++)
for (int x = 0; x < 32; x++)
;//tileset->AddTile(GetTile(x, y), x * 32, y * 32, z);
for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
if (data[j * width + i])
scene->AddTile(data[j * width + i],
i * 32 - x, j * 32 - y, altitude + z);
}

int Layer::GetZ()
{
return z;
}

unsigned int Layer::GetTile(int x, int y)
{
return data[y * width + x];
return altitude;
}


+ 4
- 4
src/layer.h Переглянути файл

@@ -6,9 +6,10 @@
#if !defined __DH_LAYER_H__
#define __DH_LAYER_H__

#include <cstdio>
#include <stdint.h>

#include "scene.h"

class Layer
{
public:
@@ -16,12 +17,11 @@ public:
~Layer();

int GetZ();
unsigned int GetTile(int x, int y);

void Draw();
void Render(Scene *scene, int x, int y, int z);

private:
int width, height, z;
int width, height, altitude;
uint32_t *data;
};



+ 5
- 3
src/map.cpp Переглянути файл

@@ -56,7 +56,7 @@ Map::Map(char const *path)
/* Read a line, then decide what to do with it. */
fgets(tmp, BUFSIZ, fp);

if (tiles)
if (tiles && !strchr(tmp, '<'))
{
/* We are in the process of reading layer data. Only stop
* when we have read the expected number of tiles. */
@@ -94,6 +94,7 @@ Map::Map(char const *path)
data->layers[data->nlayers] = new Layer(width, height, level, tiles);
data->nlayers++;
tiles = NULL;
//fprintf(stderr, "new layer %ix%i\n", width, height);
}
}
else if (sscanf(tmp, " <tileset firstgid=\"%i\"", &i) == 1)
@@ -106,6 +107,7 @@ Map::Map(char const *path)
/* This is a tileset image file. Associate it with firstgid. */
data->tilers[data->ntilers] = Tiler::Register(str);
data->ntilers++;
//fprintf(stderr, "new tiler %s\n", str);
}
else if (sscanf(tmp, " <layer name=\"%c%i%c%*[^\"]\" "
"width=\"%i\" height=\"%i\"", &a, &i, &b, &j, &k) == 5)
@@ -134,9 +136,9 @@ Map::~Map()
delete data;
}

void Map::Draw()
void Map::Render(Scene *scene, int x, int y, int z)
{
for (int i = 0; i < data->nlayers; i++)
data->layers[i]->Draw();
data->layers[i]->Render(scene, x, y, z);
}


+ 2
- 4
src/map.h Переглянути файл

@@ -6,9 +6,7 @@
#if !defined __DH_MAP_H__
#define __DH_MAP_H__

#include <cstdio>

#include "layer.h"
#include "scene.h"

class MapData;

@@ -18,7 +16,7 @@ public:
Map(char const *path);
~Map();

void Draw();
void Render(Scene *scene, int x, int y, int z);

private:
MapData *data;


+ 45
- 1
src/scene.cpp Переглянути файл

@@ -1,5 +1,14 @@

#include <stdlib.h>

#include "scene.h"
#include "tiler.h"

struct Tile
{
uint32_t prio, code;
int x, y;
};

/*
* Scene implementation class
@@ -10,7 +19,16 @@ class SceneData
friend class Scene;

private:
int dummy;
static int Compare(void const *p1, void const *p2)
{
Tile const *t1 = (Tile const *)p1;
Tile const *t2 = (Tile const *)p2;

return t1->prio - t2->prio;
}

Tile *tiles;
int ntiles;
};

/*
@@ -20,6 +38,8 @@ private:
Scene::Scene()
{
data = new SceneData();
data->tiles = 0;
data->ntiles = 0;
}

Scene::~Scene()
@@ -27,3 +47,27 @@ Scene::~Scene()
delete data;
}

void Scene::AddTile(uint32_t code, int x, int y, int z)
{
if ((data->ntiles % 1024) == 0)
data->tiles = (Tile *)realloc(data->tiles,
(data->ntiles + 1024) * sizeof(Tile));
data->tiles[data->ntiles].prio = 0;
data->tiles[data->ntiles].code = code;
data->tiles[data->ntiles].x = x;
data->tiles[data->ntiles].y = y;
data->ntiles++;
}

void Scene::Render() // XXX: rename to Blit()
{
qsort(data->tiles, data->ntiles, sizeof(Tile), SceneData::Compare);

for (int i = 0; i < data->ntiles; i++)
Tiler::Render(data->tiles[i].code, data->tiles[i].x, data->tiles[i].y);

free(data->tiles);
data->tiles = 0;
data->ntiles = 0;
}


+ 3
- 1
src/scene.h Переглянути файл

@@ -6,7 +6,6 @@
#if !defined __DH_SCENE_H__
#define __DH_SCENE_H__

#include <cstdio>
#include <stdint.h>

class SceneData;
@@ -17,6 +16,9 @@ public:
Scene();
~Scene();

void AddTile(uint32_t code, int x, int y, int z);
void Render();

private:
SceneData *data;
};


+ 7
- 13
src/test-map.cpp Переглянути файл

@@ -6,29 +6,23 @@
#include <math.h>

#include "video.h"
#include "tiler.h"
#include "map.h"
#include "game.h"

int main(int argc, char **argv)
{
Video *video = new Video("Deus Hax", 640, 480);
Map *map = new Map("maps/testmap-grass.tmx");
Game *game = new Game("maps/testmap-library.tmx");

for (int done = 0; !done; )
{
video->Clear();

//map->Draw(tiler);

/* Test stuff */
int playerx, playery;
SDL_GetMouseState(&playerx, &playery);
playerx = playerx * (640 - 32) / 640;
playery = playery * (480 - 32) / 480;

//tiler->AddTile(50, playerx, playery, 1);
int mx, my;
SDL_GetMouseState(&mx, &my);
game->SetMouse(mx * (640 - 32) / 640, my * (480 - 32) / 480);

//tiler->Render();
game->Render();
video->Refresh(33.33333f);

/* This could go in a separate function */
@@ -47,7 +41,7 @@ int main(int argc, char **argv)
}
}

delete map;
delete game;
delete video;

return EXIT_SUCCESS;


+ 7
- 0
src/tiler.cpp Переглянути файл

@@ -83,3 +83,10 @@ void Tiler::Deregister(int id)
}
}

void Tiler::Render(uint32_t code, int x, int y)
{
int id = (code >> 16) - 1; /* ID 0 is for the empty tileset */

data->tilesets[id]->BlitTile(code & 0xffff, x, y);
}


+ 4
- 0
src/tiler.h Переглянути файл

@@ -6,11 +6,15 @@
#if !defined __DH_TILER_H__
#define __DH_TILER_H__

#include <stdint.h>

class Tiler
{
public:
static int Register(char const *path);
static void Deregister(int id);

static void Render(uint32_t code, int x, int y);
};

#endif // __DH_TILER_H__


+ 13
- 94
src/tileset.cpp Переглянути файл

@@ -41,7 +41,6 @@ private:
int ntiles;

GLuint texture[1];
GLuint buflist[3];
};

/*
@@ -77,15 +76,11 @@ TileSet::TileSet(char const *path)

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);
}

TileSet::~TileSet()
{
glDeleteTextures(1, data->texture);
glDeleteBuffers(3, data->buflist);

free(data->tiles);
free(data->name);
@@ -107,97 +102,21 @@ char const *TileSet::GetName()
return data->name;
}

void TileSet::AddTile(int n, int x, int y, int z)
void TileSet::BlitTile(uint32_t id, int x, int y)
{
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 TileSet::Render()
{
/* Sort tiles */
qsort(data->tiles, data->ntiles, 4 * sizeof(int), TileSetData::Compare);

/* 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);
float tx = .0625f * (id & 0xf);
float ty = .0625f * ((id >> 4) & 0xf);

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;
glBegin(GL_QUADS);
glTexCoord2f(tx, ty);
glVertex2f(x, y);
glTexCoord2f(tx + .0625f, ty);
glVertex2f(x + 32, y);
glTexCoord2f(tx + .0625f, ty + .0625f);
glVertex2f(x + 32, y + 32);
glTexCoord2f(tx, ty + .0625f);
glVertex2f(x, y + 32);
glEnd();
}


+ 3
- 3
src/tileset.h Переглянути файл

@@ -6,6 +6,8 @@
#if !defined __DH_TILESET_H__
#define __DH_TILESET_H__

#include <stdint.h>

class TileSetData;

class TileSet
@@ -19,9 +21,7 @@ public:

char const *GetName();

void AddTile(int n, int x, int y, int z);

void Render();
void BlitTile(uint32_t id, int x, int y);

private:
TileSetData *data;


+ 1
- 1
src/video.cpp Переглянути файл

@@ -54,7 +54,7 @@ Video::Video(char const *title, int width, int height)

SDL_WM_SetCaption(title, NULL);
SDL_ShowCursor(0);
//SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_WM_GrabInput(SDL_GRAB_ON);

/* Initialise OpenGL */
glViewport(0, 0, data->video->w, data->video->h);


Завантаження…
Відмінити
Зберегти