source: trunk/src/scene.cpp @ 683

Last change on this file since 683 was 683, checked in by sam, 10 years ago

Try to fix GLES 2 rendering. No luck so far.

  • Property svn:keywords set to Id
File size: 7.5 KB
RevLine 
[100]1//
[221]2// Lol Engine
[100]3//
[221]4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
[75]10
[100]11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
[138]15#include <cstdlib>
[649]16#include <cstdio>
[138]17#include <cmath>
[79]18
[138]19#ifdef WIN32
20#   define WIN32_LEAN_AND_MEAN
21#   include <windows.h>
22#endif
23
[150]24#include "core.h"
[673]25#include "lolgl.h"
[75]26
[79]27struct Tile
28{
29    uint32_t prio, code;
[138]30    int x, y, z, o;
[79]31};
32
[674]33#if defined HAVE_GL_2X || defined HAVE_GLES_2X
[659]34extern Shader *stdshader;
[653]35#endif
[665]36extern mat4 model_matrix;
[653]37
[75]38/*
39 * Scene implementation class
40 */
41
42class SceneData
43{
44    friend class Scene;
45
46private:
[79]47    static int Compare(void const *p1, void const *p2)
48    {
49        Tile const *t1 = (Tile const *)p1;
50        Tile const *t2 = (Tile const *)p2;
51
[133]52        return t2->prio - t1->prio;
[79]53    }
54
55    Tile *tiles;
56    int ntiles;
[222]57    float angle;
[289]58
[674]59#if defined HAVE_GL_2X
[672]60    GLuint vao;
61#endif
[645]62    GLuint *bufs;
63    int nbufs;
64
[289]65    static Scene *scene;
[75]66};
67
[289]68Scene *SceneData::scene = NULL;
69
[75]70/*
71 * Public Scene class
72 */
73
[222]74Scene::Scene(float angle)
[259]75  : data(new SceneData())
[75]76{
[79]77    data->tiles = 0;
78    data->ntiles = 0;
[222]79    data->angle = angle;
[645]80
81    data->bufs = 0;
82    data->nbufs = 0;
[672]83
[674]84#if defined HAVE_GL_2X
[672]85    glGenVertexArrays(1, &data->vao);
86#endif
[75]87}
88
89Scene::~Scene()
90{
[645]91    /* FIXME: this must be done while the GL context is still active.
92     * Change the architecture to make sure of that. */
93    glDeleteBuffers(data->nbufs, data->bufs);
[674]94#if defined HAVE_GL_2X
[672]95    glDeleteVertexArrays(1, &data->vao);
96#endif
[671]97    free(data->bufs);
[75]98    delete data;
99}
100
[289]101Scene *Scene::GetDefault()
102{
103    if (!SceneData::scene)
104        SceneData::scene = new Scene(0.0f);
105    return SceneData::scene;
106}
107
108void Scene::Reset()
109{
110    if (SceneData::scene)
111        delete SceneData::scene;
112    SceneData::scene = NULL;
113}
114
[133]115void Scene::AddTile(uint32_t code, int x, int y, int z, int o)
[79]116{
117    if ((data->ntiles % 1024) == 0)
118        data->tiles = (Tile *)realloc(data->tiles,
119                                      (data->ntiles + 1024) * sizeof(Tile));
[313]120    /* FIXME: this sorting only works for a 45-degree camera */
[141]121    data->tiles[data->ntiles].prio = -y - 2 * 32 * z + (o ? 0 : 32);
[79]122    data->tiles[data->ntiles].code = code;
123    data->tiles[data->ntiles].x = x;
124    data->tiles[data->ntiles].y = y;
[138]125    data->tiles[data->ntiles].z = z;
126    data->tiles[data->ntiles].o = o;
[79]127    data->ntiles++;
128}
129
130void Scene::Render() // XXX: rename to Blit()
131{
[147]132#if 0
133    // Randomise, then sort.
134    for (int i = 0; i < data->ntiles; i++)
135    {
136        Tile tmp = data->tiles[i];
137        int j = rand() % data->ntiles;
138        data->tiles[i] = data->tiles[j];
139        data->tiles[j] = tmp;
140    }
141#endif
[79]142    qsort(data->tiles, data->ntiles, sizeof(Tile), SceneData::Compare);
143
[662]144    // XXX: debug stuff
[664]145    model_matrix = mat4::translate(320.0f, 240.0f, 0.0f);
146    model_matrix *= mat4::rotate(-data->angle, 1.0f, 0.0f, 0.0f);
[662]147#if 0
148    static float f = 0.0f;
149    f += 0.01f;
[664]150    model_matrix *= mat4::rotate(0.1f * sinf(f), 1.0f, 0.0f, 0.0f);
151    model_matrix *= mat4::rotate(0.3f * cosf(f), 0.0f, 0.0f, 1.0f);
[662]152#endif
[664]153    model_matrix *= mat4::translate(-320.0f, -240.0f, 0.0f);
[662]154    // XXX: end of debug stuff
155
[674]156#if defined HAVE_GL_2X || defined HAVE_GLES_2X
[683]157    GLuint uni_mat, uni_tex, attr_pos, attr_tex;
[666]158    attr_pos = stdshader->GetAttribLocation("in_Position");
159    attr_tex = stdshader->GetAttribLocation("in_TexCoord");
160
[674]161    stdshader->Bind();
[683]162    uni_mat = stdshader->GetUniformLocation("model_matrix");
163    glUniformMatrix4fv(uni_mat, 1, GL_FALSE, &model_matrix[0][0]);
164    uni_tex = stdshader->GetUniformLocation("in_Texture");
165    glUniform1i(uni_tex, 0);
[674]166
[666]167    glEnable(GL_DEPTH_TEST);
168    glDepthFunc(GL_LEQUAL);
[674]169#   if !defined HAVE_GLES_2X
[666]170    glEnable(GL_ALPHA_TEST);
171    glAlphaFunc(GL_GEQUAL, 0.01f);
[674]172#   endif
[666]173    glEnable(GL_BLEND);
174    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
[654]175#else
[665]176    glEnable(GL_DEPTH_TEST);
177    glDepthFunc(GL_LEQUAL);
178    glEnable(GL_ALPHA_TEST);
179    glAlphaFunc(GL_GEQUAL, 0.01f);
180    glEnable(GL_BLEND);
181    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
182
[662]183    glLoadIdentity();
184    glMultMatrixf(&model_matrix[0][0]);
[666]185#endif
[138]186
[645]187    for (int buf = 0, i = 0, n; i < data->ntiles; i = n, buf += 2)
188    {
189        /* Generate new vertex / texture coord buffers if necessary */
190        if (buf + 2 > data->nbufs)
191        {
192            data->bufs = (GLuint *)realloc(data->bufs, (buf + 2) * sizeof(GLuint));
193            glGenBuffers(buf + 2 - data->nbufs, data->bufs + data->nbufs);
194            data->nbufs = buf + 2;
195        }
[79]196
[645]197        /* Count how many quads will be needed */
198        for (n = i + 1; n < data->ntiles; n++)
199            if (data->tiles[i].code >> 16 != data->tiles[n].code >> 16)
200                break;
201
202        /* Create a vertex array object */
203        float *vertex = (float *)malloc(6 * 3 * (n - i) * sizeof(float));
204        float *texture = (float *)malloc(6 * 2 * (n - i) * sizeof(float));
205
206        for (int j = i; j < n; j++)
207        {
208            Tiler::BlitTile(data->tiles[j].code, data->tiles[j].x,
209                            data->tiles[j].y, data->tiles[j].z, data->tiles[j].o,
210                            vertex + 18 * (j - i), texture + 12 * (j - i));
211        }
212
[675]213#if defined HAVE_GL_2X || defined HAVE_GLES_2X
[683]214        stdshader->Bind();
215#endif
216        glActiveTexture(GL_TEXTURE0);
217        Tiler::Bind(data->tiles[i].code);
218
219#if defined HAVE_GL_2X || defined HAVE_GLES_2X
[675]220#   if !defined HAVE_GLES_2X
[672]221        glBindVertexArray(data->vao);
[675]222#   endif
[674]223        glEnableVertexAttribArray(attr_pos);
224        glEnableVertexAttribArray(attr_tex);
[666]225#else
[645]226        glEnableClientState(GL_VERTEX_ARRAY);
227        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
[671]228#endif
[645]229
[675]230#if defined HAVE_GL_2X || defined HAVE_GLES_2X
[645]231        glBindBuffer(GL_ARRAY_BUFFER, data->bufs[buf]);
[671]232        glBufferData(GL_ARRAY_BUFFER, 18 * (n - i) * sizeof(GLfloat),
233                     vertex, GL_STATIC_DRAW);
234        glVertexAttribPointer(attr_pos, 3, GL_FLOAT, GL_FALSE, 0, 0);
[674]235#elif defined HAVE_GL_1X
236        glBindBuffer(GL_ARRAY_BUFFER, data->bufs[buf]);
237        glBufferData(GL_ARRAY_BUFFER, 18 * (n - i) * sizeof(GLfloat),
238                     vertex, GL_STATIC_DRAW);
239        glVertexPointer(3, GL_FLOAT, 0, NULL);
[671]240#else
[674]241        glVertexPointer(3, GL_FLOAT, 0, vertex);
[671]242#endif
[645]243
[675]244#if defined HAVE_GL_2X || defined HAVE_GLES_2X
[645]245        glBindBuffer(GL_ARRAY_BUFFER, data->bufs[buf + 1]);
[671]246        glBufferData(GL_ARRAY_BUFFER, 12 * (n - i) * sizeof(GLfloat),
247                     texture, GL_STATIC_DRAW);
248        glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, 0);
[674]249#elif defined HAVE_GL_1X
250        glBindBuffer(GL_ARRAY_BUFFER, data->bufs[buf + 1]);
251        glBufferData(GL_ARRAY_BUFFER, 12 * (n - i) * sizeof(GLfloat),
252                     texture, GL_STATIC_DRAW);
253        glTexCoordPointer(2, GL_FLOAT, 0, NULL);
[671]254#else
[674]255        glTexCoordPointer(2, GL_FLOAT, 0, texture);
[666]256#endif
[645]257
258        glDrawArrays(GL_TRIANGLES, 0, (n - i) * 6);
259
[675]260#if defined HAVE_GL_2X || defined HAVE_GLES_2X
261#   if !defined HAVE_GLES_2X
[666]262        glBindVertexArray(0);
[675]263#   endif
[674]264        glDisableVertexAttribArray(attr_pos);
265        glDisableVertexAttribArray(attr_tex);
[666]266#else
[645]267        glDisableClientState(GL_VERTEX_ARRAY);
268        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
[666]269#endif
[645]270
271        free(vertex);
272        free(texture);
273    }
[138]274
[79]275    free(data->tiles);
276    data->tiles = 0;
277    data->ntiles = 0;
278}
279
Note: See TracBrowser for help on using the repository browser.