source: trunk/src/scene.cpp @ 654

Last change on this file since 654 was 654, checked in by sam, 11 years ago

More shader crap. We can now display a coloured quad. Still disabled.

  • Property svn:keywords set to Id
File size: 6.8 KB
Line 
1//
2// Lol Engine
3//
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//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cstdlib>
16#include <cstdio>
17#include <cmath>
18
19#ifdef WIN32
20#   define WIN32_LEAN_AND_MEAN
21#   include <windows.h>
22#endif
23#if defined __APPLE__ && defined __MACH__
24#   include <OpenGL/gl.h>
25#else
26#   define GL_GLEXT_PROTOTYPES
27#   include <GL/gl.h>
28#endif
29
30#include "core.h"
31
32struct Tile
33{
34    uint32_t prio, code;
35    int x, y, z, o;
36};
37
38#if SHADER_CRAP
39#   define ATTRIB_POSITION 42 /* arbitrary id */
40    extern GLuint prog;
41    extern GLint uni_mvp, uni_color;
42#endif
43
44/*
45 * Scene implementation class
46 */
47
48class SceneData
49{
50    friend class Scene;
51
52private:
53    static int Compare(void const *p1, void const *p2)
54    {
55        Tile const *t1 = (Tile const *)p1;
56        Tile const *t2 = (Tile const *)p2;
57
58        return t2->prio - t1->prio;
59    }
60
61    Tile *tiles;
62    int ntiles;
63    float angle;
64
65    GLuint *bufs;
66    int nbufs;
67
68    static Scene *scene;
69};
70
71Scene *SceneData::scene = NULL;
72
73/*
74 * Public Scene class
75 */
76
77Scene::Scene(float angle)
78  : data(new SceneData())
79{
80    data->tiles = 0;
81    data->ntiles = 0;
82    data->angle = angle;
83
84    data->bufs = 0;
85    data->nbufs = 0;
86}
87
88Scene::~Scene()
89{
90    /* FIXME: this must be done while the GL context is still active.
91     * Change the architecture to make sure of that. */
92    glDeleteBuffers(data->nbufs, data->bufs);
93    delete data;
94}
95
96Scene *Scene::GetDefault()
97{
98    if (!SceneData::scene)
99        SceneData::scene = new Scene(0.0f);
100    return SceneData::scene;
101}
102
103void Scene::Reset()
104{
105    if (SceneData::scene)
106        delete SceneData::scene;
107    SceneData::scene = NULL;
108}
109
110void Scene::AddTile(uint32_t code, int x, int y, int z, int o)
111{
112    if ((data->ntiles % 1024) == 0)
113        data->tiles = (Tile *)realloc(data->tiles,
114                                      (data->ntiles + 1024) * sizeof(Tile));
115    /* FIXME: this sorting only works for a 45-degree camera */
116    data->tiles[data->ntiles].prio = -y - 2 * 32 * z + (o ? 0 : 32);
117    data->tiles[data->ntiles].code = code;
118    data->tiles[data->ntiles].x = x;
119    data->tiles[data->ntiles].y = y;
120    data->tiles[data->ntiles].z = z;
121    data->tiles[data->ntiles].o = o;
122    data->ntiles++;
123}
124
125void Scene::Render() // XXX: rename to Blit()
126{
127#if 0
128    // Randomise, then sort.
129    for (int i = 0; i < data->ntiles; i++)
130    {
131        Tile tmp = data->tiles[i];
132        int j = rand() % data->ntiles;
133        data->tiles[i] = data->tiles[j];
134        data->tiles[j] = tmp;
135    }
136#endif
137    qsort(data->tiles, data->ntiles, sizeof(Tile), SceneData::Compare);
138
139#if SHADER_CRAP
140    float *vertices = new float[18];
141    vertices[0] = -0.5f; vertices[1] = -0.5f; vertices[2] = 0.0f;
142    vertices[3] = -0.5f; vertices[4] = 0.5f; vertices[5] = 0.0f;
143    vertices[6] = 0.5f; vertices[7] = 0.5f; vertices[8] = 0.0f;
144
145    vertices[9] = 0.5f; vertices[10] = -0.5f; vertices[11] = 0.0f;
146    vertices[12] = -0.5f; vertices[13] = -0.5f; vertices[14] = 0.0f;
147    vertices[15] = 0.5f; vertices[16] = 0.5f; vertices[17] = 0.0f;
148
149    const GLfloat colors[6][3] = {
150    {  1.0,  0.0,  0.0  },
151    {  0.0,  1.0,  0.0  },
152    {  0.0,  0.0,  1.0  },
153    {  1.0,  0.0,  0.0  },
154    {  0.0,  1.0,  0.0  },
155    {  1.0,  1.0,  0.0  } };
156
157    GLuint id[3];
158    glGenVertexArrays(1, &id[0]);
159    glBindVertexArray(id[0]);
160    glGenBuffers(2, &id[1]);
161
162    glBindBuffer(GL_ARRAY_BUFFER, id[1]);
163    glBufferData(GL_ARRAY_BUFFER, 18 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
164    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
165    glEnableVertexAttribArray(0);
166
167    glBindBuffer(GL_ARRAY_BUFFER, id[2]);
168    glBufferData(GL_ARRAY_BUFFER, 18 * sizeof(GLfloat), colors, GL_STATIC_DRAW);
169    glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0);
170    glEnableVertexAttribArray(1);
171
172    delete[] vertices;
173
174    glUseProgram(prog);
175    glBindVertexArray(id[0]);
176    glDrawArrays(GL_TRIANGLES, 0, 6);
177    glBindVertexArray(0);
178
179#else
180    // XXX: debug stuff
181    glPushMatrix();
182    static float f = 0.0f;
183    f += 0.05f;
184    glTranslatef(320.0f, 240.0f, 0.0f);
185    glRotatef(-data->angle, 1.0f, 0.0f, 0.0f);
186#if 0
187    glRotatef(3.0f * sinf(f), 1.0f, 0.0f, 0.0f);
188    glRotatef(8.0f * cosf(f), 0.0f, 0.0f, 1.0f);
189#endif
190    glTranslatef(-320.0f, -240.0f, 0.0f);
191    // XXX: end of debug stuff
192
193    for (int buf = 0, i = 0, n; i < data->ntiles; i = n, buf += 2)
194    {
195        /* Generate new vertex / texture coord buffers if necessary */
196        if (buf + 2 > data->nbufs)
197        {
198            data->bufs = (GLuint *)realloc(data->bufs, (buf + 2) * sizeof(GLuint));
199            glGenBuffers(buf + 2 - data->nbufs, data->bufs + data->nbufs);
200            data->nbufs = buf + 2;
201        }
202
203        /* Count how many quads will be needed */
204        for (n = i + 1; n < data->ntiles; n++)
205            if (data->tiles[i].code >> 16 != data->tiles[n].code >> 16)
206                break;
207
208        /* Create a vertex array object */
209        float *vertex = (float *)malloc(6 * 3 * (n - i) * sizeof(float));
210        float *texture = (float *)malloc(6 * 2 * (n - i) * sizeof(float));
211
212        for (int j = i; j < n; j++)
213        {
214            Tiler::BlitTile(data->tiles[j].code, data->tiles[j].x,
215                            data->tiles[j].y, data->tiles[j].z, data->tiles[j].o,
216                            vertex + 18 * (j - i), texture + 12 * (j - i));
217        }
218
219        glEnableClientState(GL_VERTEX_ARRAY);
220        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
221#if SHADER_CRAP
222        glUseProgram(prog);
223        //float4x4 mvp(1.0f);
224        //mvp = mvp - mvp;
225        //glUniformMatrix4fv(uni_mvp, 1, GL_FALSE, (GLfloat *)&mvp[0][0]);
226        //glUniform4f(uni_color, 1.0f, 0.0f, 1.0f, 1.0f);
227#endif
228
229        glBindBuffer(GL_ARRAY_BUFFER, data->bufs[buf]);
230        glBufferData(GL_ARRAY_BUFFER, 6 * 3 * (n - i) * sizeof(float),
231                     vertex, GL_DYNAMIC_DRAW);
232        glVertexPointer(3, GL_FLOAT, 0, NULL);
233#if SHADER_CRAP
234        glVertexAttribPointer(ATTRIB_POSITION, (n - i) * 6, GL_FLOAT, false, 0, vertex);
235        glEnableVertexAttribArray(ATTRIB_POSITION);
236#endif
237
238        glBindBuffer(GL_ARRAY_BUFFER, data->bufs[buf + 1]);
239        glBufferData(GL_ARRAY_BUFFER, 6 * 2 * (n - i) * sizeof(float),
240                     texture, GL_DYNAMIC_DRAW);
241        glTexCoordPointer(2, GL_FLOAT, 0, NULL);
242
243        Tiler::Bind(data->tiles[i].code);
244        glDrawArrays(GL_TRIANGLES, 0, (n - i) * 6);
245
246        glDisableClientState(GL_VERTEX_ARRAY);
247        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
248
249        free(vertex);
250        free(texture);
251    }
252
253    glPopMatrix();
254#endif
255
256    free(data->tiles);
257    data->tiles = 0;
258    data->ntiles = 0;
259}
260
Note: See TracBrowser for help on using the repository browser.