Bläddra i källkod

Switch scene rendering method to vertex buffer objects.

legacy
Sam Hocevar sam 13 år sedan
förälder
incheckning
9a66d6b1bb
5 ändrade filer med 134 tillägg och 20 borttagningar
  1. +58
    -4
      src/scene.cpp
  2. +20
    -2
      src/tiler.cpp
  3. +3
    -1
      src/tiler.h
  4. +50
    -12
      src/tileset.cpp
  5. +3
    -1
      src/tileset.h

+ 58
- 4
src/scene.cpp Visa fil

@@ -55,6 +55,9 @@ private:
int ntiles;
float angle;

GLuint *bufs;
int nbufs;

static Scene *scene;
};

@@ -70,10 +73,16 @@ Scene::Scene(float angle)
data->tiles = 0;
data->ntiles = 0;
data->angle = angle;

data->bufs = 0;
data->nbufs = 0;
}

Scene::~Scene()
{
/* FIXME: this must be done while the GL context is still active.
* Change the architecture to make sure of that. */
glDeleteBuffers(data->nbufs, data->bufs);
delete data;
}

@@ -131,13 +140,58 @@ void Scene::Render() // XXX: rename to Blit()
glRotatef(8.0f * cosf(f), 0.0f, 0.0f, 1.0f);
#endif
glTranslatef(-320.0f, -240.0f, 0.0f);
// XXX: end of debug stuff

for (int i = 0; i < data->ntiles; i++)
Tiler::BlitTile(data->tiles[i].code, data->tiles[i].x,
data->tiles[i].y, data->tiles[i].z, data->tiles[i].o);
for (int buf = 0, i = 0, n; i < data->ntiles; i = n, buf += 2)
{
/* Generate new vertex / texture coord buffers if necessary */
if (buf + 2 > data->nbufs)
{
data->bufs = (GLuint *)realloc(data->bufs, (buf + 2) * sizeof(GLuint));
glGenBuffers(buf + 2 - data->nbufs, data->bufs + data->nbufs);
data->nbufs = buf + 2;
}

/* Count how many quads will be needed */
for (n = i + 1; n < data->ntiles; n++)
if (data->tiles[i].code >> 16 != data->tiles[n].code >> 16)
break;

/* Create a vertex array object */
float *vertex = (float *)malloc(6 * 3 * (n - i) * sizeof(float));
float *texture = (float *)malloc(6 * 2 * (n - i) * sizeof(float));

for (int j = i; j < n; j++)
{
Tiler::BlitTile(data->tiles[j].code, data->tiles[j].x,
data->tiles[j].y, data->tiles[j].z, data->tiles[j].o,
vertex + 18 * (j - i), texture + 12 * (j - i));
}

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, data->bufs[buf]);
glBufferData(GL_ARRAY_BUFFER, 6 * 3 * (n - i) * sizeof(float),
vertex, GL_DYNAMIC_DRAW);
glVertexPointer(3, GL_FLOAT, 0, NULL);

glBindBuffer(GL_ARRAY_BUFFER, data->bufs[buf + 1]);
glBufferData(GL_ARRAY_BUFFER, 6 * 2 * (n - i) * sizeof(float),
texture, GL_DYNAMIC_DRAW);
glTexCoordPointer(2, GL_FLOAT, 0, NULL);

Tiler::Bind(data->tiles[i].code);
glDrawArrays(GL_TRIANGLES, 0, (n - i) * 6);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

free(vertex);
free(texture);
}

glPopMatrix();
// XXX: end of debug stuff

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


+ 20
- 2
src/tiler.cpp Visa fil

@@ -93,7 +93,25 @@ int2 Tiler::GetCount(int id)
return tileset->GetCount();
}

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

TileSet *tileset = (TileSet *)data->tilesets.GetEntity(id);
#if !FINAL_RELEASE
if (!tileset)
{
if (id != data->lasterror)
fprintf(stderr, "ERROR: binding null tiler #%i\n", id);
data->lasterror = id;
return;
}
#endif
tileset->Bind();
}

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

@@ -107,6 +125,6 @@ void Tiler::BlitTile(uint32_t code, int x, int y, int z, int o)
return;
}
#endif
tileset->BlitTile(code & 0xffff, x, y, z, o);
tileset->BlitTile(code & 0xffff, x, y, z, o, vertex, texture);
}


+ 3
- 1
src/tiler.h Visa fil

@@ -27,7 +27,9 @@ public:

static int2 GetSize(int id);
static int2 GetCount(int id);
static void BlitTile(uint32_t code, int x, int y, int z, int o);
static void Bind(uint32_t code);
static void BlitTile(uint32_t code, int x, int y, int z, int o,
float *vertex, float *texture);
};

#endif // __DH_TILER_H__


+ 50
- 12
src/tileset.cpp Visa fil

@@ -167,7 +167,14 @@ int2 TileSet::GetCount() const
return data->count;
}

void TileSet::BlitTile(uint32_t id, int x, int y, int z, int o)
void TileSet::Bind()
{
if (!data->img)
glBindTexture(GL_TEXTURE_2D, data->texture);
}

void TileSet::BlitTile(uint32_t id, int x, int y, int z, int o,
float *vertex, float *texture)
{
float tx = data->tx * ((id & 0xffff) % data->count.i);
float ty = data->ty * ((id & 0xffff) / data->count.i);
@@ -179,17 +186,48 @@ void TileSet::BlitTile(uint32_t id, int x, int y, int z, int o)

if (!data->img)
{
glBindTexture(GL_TEXTURE_2D, data->texture);
glBegin(GL_QUADS);
glTexCoord2f(tx, ty);
glVertex3f(x, dilate * (y + dy), dilate * (z + dz));
glTexCoord2f(tx + data->tx, ty);
glVertex3f(x + dx, dilate * (y + dy), dilate * (z + dz));
glTexCoord2f(tx + data->tx, ty + data->ty);
glVertex3f(x + dx, dilate * y, dilate * z);
glTexCoord2f(tx, ty + data->ty);
glVertex3f(x, dilate * y, dilate * z);
glEnd();
float tmp[10];

*vertex++ = tmp[0] = x;
*vertex++ = tmp[1] = dilate * (y + dy);
*vertex++ = tmp[2] = dilate * (z + dz);
*texture++ = tmp[3] = tx;
*texture++ = tmp[4] = ty;

*vertex++ = x + dx;
*vertex++ = dilate * (y + dy);
*vertex++ = dilate * (z + dz);
*texture++ = tx + data->tx;
*texture++ = ty;

*vertex++ = tmp[5] = x + dx;
*vertex++ = tmp[6] = dilate * y;
*vertex++ = tmp[7] = dilate * z;
*texture++ = tmp[8] = tx + data->tx;
*texture++ = tmp[9] = ty + data->ty;

*vertex++ = tmp[0];
*vertex++ = tmp[1];
*vertex++ = tmp[2];
*texture++ = tmp[3];
*texture++ = tmp[4];

*vertex++ = tmp[5];
*vertex++ = tmp[6];
*vertex++ = tmp[7];
*texture++ = tmp[8];
*texture++ = tmp[9];

*vertex++ = x;
*vertex++ = dilate * y;
*vertex++ = dilate * z;
*texture++ = tx;
*texture++ = ty + data->ty;
}
else
{
memset(vertex, 0, 3 * sizeof(float));
memset(texture, 0, 2 * sizeof(float));
}
}


+ 3
- 1
src/tileset.h Visa fil

@@ -40,7 +40,9 @@ public:
/* New methods */
int2 GetSize() const;
int2 GetCount() const;
void BlitTile(uint32_t id, int x, int y, int z, int o);
void Bind();
void BlitTile(uint32_t id, int x, int y, int z, int o,
float *vertex, float *texture);

private:
TileSetData *data;


Laddar…
Avbryt
Spara