Changeset 645


Ignore:
Timestamp:
Feb 14, 2011, 2:26:31 AM (10 years ago)
Author:
sam
Message:

Switch scene rendering method to vertex buffer objects.

Location:
trunk/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/scene.cpp

    r313 r645  
    5656    float angle;
    5757
     58    GLuint *bufs;
     59    int nbufs;
     60
    5861    static Scene *scene;
    5962};
     
    7174    data->ntiles = 0;
    7275    data->angle = angle;
     76
     77    data->bufs = 0;
     78    data->nbufs = 0;
    7379}
    7480
    7581Scene::~Scene()
    7682{
     83    /* FIXME: this must be done while the GL context is still active.
     84     * Change the architecture to make sure of that. */
     85    glDeleteBuffers(data->nbufs, data->bufs);
    7786    delete data;
    7887}
     
    132141#endif
    133142    glTranslatef(-320.0f, -240.0f, 0.0f);
    134 
    135     for (int i = 0; i < data->ntiles; i++)
    136         Tiler::BlitTile(data->tiles[i].code, data->tiles[i].x,
    137                         data->tiles[i].y, data->tiles[i].z, data->tiles[i].o);
     143    // XXX: end of debug stuff
     144
     145    for (int buf = 0, i = 0, n; i < data->ntiles; i = n, buf += 2)
     146    {
     147        /* Generate new vertex / texture coord buffers if necessary */
     148        if (buf + 2 > data->nbufs)
     149        {
     150            data->bufs = (GLuint *)realloc(data->bufs, (buf + 2) * sizeof(GLuint));
     151            glGenBuffers(buf + 2 - data->nbufs, data->bufs + data->nbufs);
     152            data->nbufs = buf + 2;
     153        }
     154
     155        /* Count how many quads will be needed */
     156        for (n = i + 1; n < data->ntiles; n++)
     157            if (data->tiles[i].code >> 16 != data->tiles[n].code >> 16)
     158                break;
     159
     160        /* Create a vertex array object */
     161        float *vertex = (float *)malloc(6 * 3 * (n - i) * sizeof(float));
     162        float *texture = (float *)malloc(6 * 2 * (n - i) * sizeof(float));
     163
     164        for (int j = i; j < n; j++)
     165        {
     166            Tiler::BlitTile(data->tiles[j].code, data->tiles[j].x,
     167                            data->tiles[j].y, data->tiles[j].z, data->tiles[j].o,
     168                            vertex + 18 * (j - i), texture + 12 * (j - i));
     169        }
     170
     171        glEnableClientState(GL_VERTEX_ARRAY);
     172        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
     173
     174        glBindBuffer(GL_ARRAY_BUFFER, data->bufs[buf]);
     175        glBufferData(GL_ARRAY_BUFFER, 6 * 3 * (n - i) * sizeof(float),
     176                     vertex, GL_DYNAMIC_DRAW);
     177        glVertexPointer(3, GL_FLOAT, 0, NULL);
     178
     179        glBindBuffer(GL_ARRAY_BUFFER, data->bufs[buf + 1]);
     180        glBufferData(GL_ARRAY_BUFFER, 6 * 2 * (n - i) * sizeof(float),
     181                     texture, GL_DYNAMIC_DRAW);
     182        glTexCoordPointer(2, GL_FLOAT, 0, NULL);
     183
     184        Tiler::Bind(data->tiles[i].code);
     185        glDrawArrays(GL_TRIANGLES, 0, (n - i) * 6);
     186
     187        glDisableClientState(GL_VERTEX_ARRAY);
     188        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     189
     190        free(vertex);
     191        free(texture);
     192    }
    138193
    139194    glPopMatrix();
    140     // XXX: end of debug stuff
    141195
    142196    free(data->tiles);
  • trunk/src/tiler.cpp

    r637 r645  
    9494}
    9595
    96 void Tiler::BlitTile(uint32_t code, int x, int y, int z, int o)
     96void Tiler::Bind(uint32_t code)
     97{
     98    int id = (code >> 16) - 1; /* ID 0 is for the empty tileset */
     99
     100    TileSet *tileset = (TileSet *)data->tilesets.GetEntity(id);
     101#if !FINAL_RELEASE
     102    if (!tileset)
     103    {
     104        if (id != data->lasterror)
     105            fprintf(stderr, "ERROR: binding null tiler #%i\n", id);
     106        data->lasterror = id;
     107        return;
     108    }
     109#endif
     110    tileset->Bind();
     111}
     112
     113void Tiler::BlitTile(uint32_t code, int x, int y, int z, int o,
     114                     float *vertex, float *texture)
    97115{
    98116    int id = (code >> 16) - 1; /* ID 0 is for the empty tileset */
     
    108126    }
    109127#endif
    110     tileset->BlitTile(code & 0xffff, x, y, z, o);
     128    tileset->BlitTile(code & 0xffff, x, y, z, o, vertex, texture);
    111129}
    112130
  • trunk/src/tiler.h

    r637 r645  
    2828    static int2 GetSize(int id);
    2929    static int2 GetCount(int id);
    30     static void BlitTile(uint32_t code, int x, int y, int z, int o);
     30    static void Bind(uint32_t code);
     31    static void BlitTile(uint32_t code, int x, int y, int z, int o,
     32                         float *vertex, float *texture);
    3133};
    3234
  • trunk/src/tileset.cpp

    r637 r645  
    168168}
    169169
    170 void TileSet::BlitTile(uint32_t id, int x, int y, int z, int o)
     170void TileSet::Bind()
     171{
     172    if (!data->img)
     173        glBindTexture(GL_TEXTURE_2D, data->texture);
     174}
     175
     176void TileSet::BlitTile(uint32_t id, int x, int y, int z, int o,
     177                       float *vertex, float *texture)
    171178{
    172179    float tx = data->tx * ((id & 0xffff) % data->count.i);
     
    180187    if (!data->img)
    181188    {
    182         glBindTexture(GL_TEXTURE_2D, data->texture);
    183         glBegin(GL_QUADS);
    184             glTexCoord2f(tx, ty);
    185             glVertex3f(x, dilate * (y + dy), dilate * (z + dz));
    186             glTexCoord2f(tx + data->tx, ty);
    187             glVertex3f(x + dx, dilate * (y + dy), dilate * (z + dz));
    188             glTexCoord2f(tx + data->tx, ty + data->ty);
    189             glVertex3f(x + dx, dilate * y, dilate * z);
    190             glTexCoord2f(tx, ty + data->ty);
    191             glVertex3f(x, dilate * y, dilate * z);
    192         glEnd();
    193     }
    194 }
    195 
     189        float tmp[10];
     190
     191        *vertex++ = tmp[0] = x;
     192        *vertex++ = tmp[1] = dilate * (y + dy);
     193        *vertex++ = tmp[2] = dilate * (z + dz);
     194        *texture++ = tmp[3] = tx;
     195        *texture++ = tmp[4] = ty;
     196
     197        *vertex++ = x + dx;
     198        *vertex++ = dilate * (y + dy);
     199        *vertex++ = dilate * (z + dz);
     200        *texture++ = tx + data->tx;
     201        *texture++ = ty;
     202
     203        *vertex++ = tmp[5] = x + dx;
     204        *vertex++ = tmp[6] = dilate * y;
     205        *vertex++ = tmp[7] = dilate * z;
     206        *texture++ = tmp[8] = tx + data->tx;
     207        *texture++ = tmp[9] = ty + data->ty;
     208
     209        *vertex++ = tmp[0];
     210        *vertex++ = tmp[1];
     211        *vertex++ = tmp[2];
     212        *texture++ = tmp[3];
     213        *texture++ = tmp[4];
     214
     215        *vertex++ = tmp[5];
     216        *vertex++ = tmp[6];
     217        *vertex++ = tmp[7];
     218        *texture++ = tmp[8];
     219        *texture++ = tmp[9];
     220
     221        *vertex++ = x;
     222        *vertex++ = dilate * y;
     223        *vertex++ = dilate * z;
     224        *texture++ = tx;
     225        *texture++ = ty + data->ty;
     226    }
     227    else
     228    {
     229        memset(vertex, 0, 3 * sizeof(float));
     230        memset(texture, 0, 2 * sizeof(float));
     231    }
     232}
     233
  • trunk/src/tileset.h

    r637 r645  
    4141    int2 GetSize() const;
    4242    int2 GetCount() const;
    43     void BlitTile(uint32_t id, int x, int y, int z, int o);
     43    void Bind();
     44    void BlitTile(uint32_t id, int x, int y, int z, int o,
     45                  float *vertex, float *texture);
    4446
    4547private:
Note: See TracChangeset for help on using the changeset viewer.