source: trunk/src/scene.cpp @ 2370

Last change on this file since 2370 was 2289, checked in by sam, 7 years ago

easymesh: interface the shiny shader with new Light objects.

  • Property svn:keywords set to Id
File size: 7.2 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2013 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://www.wtfpl.net/ for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cstdlib>
16
17#ifdef WIN32
18#   define WIN32_LEAN_AND_MEAN
19#   include <windows.h>
20#endif
21
22#include "core.h"
23#include "lolgl.h"
24
25LOLFX_RESOURCE_DECLARE(tile);
26
27namespace lol
28{
29
30struct Tile
31{
32    TileSet *tileset;
33    uint32_t prio;
34    vec3 pos;
35    vec2 scale;
36    int id, o;
37};
38
39/*
40 * Scene implementation class
41 */
42
43class SceneData
44{
45    friend class Scene;
46
47private:
48    static int Compare(void const *p1, void const *p2)
49    {
50        Tile const *t1 = (Tile const *)p1;
51        Tile const *t2 = (Tile const *)p2;
52
53        if (t1->pos.z > t2->pos.z)
54            return 1;
55        if (t1->pos.z < t2->pos.z)
56            return -1;
57        return 0;
58    }
59
60    mat4 m_model_matrix;
61    mat4 m_view_matrix;
62    mat4 m_proj_matrix;
63
64    Array<Tile> m_tiles;
65    Array<Light *> m_lights;
66
67    Shader *m_shader;
68    VertexDeclaration *m_vdecl;
69    Array<VertexBuffer *> bufs;
70
71    static Scene *scene;
72};
73
74Scene *SceneData::scene = NULL;
75
76/*
77 * Public Scene class
78 */
79
80Scene::Scene()
81  : data(new SceneData())
82{
83    data->m_model_matrix = mat4(1.f);
84    data->m_view_matrix = mat4(1.f);
85    data->m_proj_matrix = mat4::ortho(0, Video::GetSize().x,
86                                      0, Video::GetSize().y, -1000.f, 1000.f);
87
88    data->m_shader = 0;
89    data->m_vdecl = new VertexDeclaration(VertexStream<vec3>(VertexUsage::Position),
90                                          VertexStream<vec2>(VertexUsage::TexCoord));
91}
92
93Scene::~Scene()
94{
95    /* FIXME: this must be done while the GL context is still active.
96     * Change the code architecture to make sure of that. */
97    /* FIXME: also, make sure we do not add code to Reset() that will
98     * reallocate stuff */
99    Reset();
100
101    delete data->m_vdecl;
102    delete data;
103}
104
105Scene *Scene::GetDefault()
106{
107    if (!SceneData::scene)
108        SceneData::scene = new Scene();
109    return SceneData::scene;
110}
111
112void Scene::Reset()
113{
114    for (int i = 0; i < data->bufs.Count(); i++)
115        delete data->bufs[i];
116    data->bufs.Empty();
117    data->m_lights.Empty();
118}
119
120void Scene::SetViewMatrix(mat4 const &m)
121{
122    data->m_view_matrix = m;
123}
124
125void Scene::SetProjMatrix(mat4 const &m)
126{
127    data->m_proj_matrix = m;
128}
129
130mat4 const &Scene::GetViewMatrix(void)
131{
132    return data->m_view_matrix;
133}
134
135mat4 const &Scene::GetProjMatrix(void)
136{
137    return data->m_proj_matrix;
138}
139
140void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale)
141{
142    Tile t;
143    /* FIXME: this sorting only works for a 45-degree camera */
144    t.prio = -pos.y - 2 * 32 * pos.z + (o ? 0 : 32);
145    t.tileset = tileset;
146    t.id = id;
147    t.pos = pos;
148    t.o = o;
149    t.scale = scale;
150
151    data->m_tiles.Push(t);
152}
153
154void Scene::AddLight(Light *l)
155{
156    data->m_lights.Push(l);
157}
158
159Array<Light *> const &Scene::GetLights() const
160{
161    return data->m_lights;
162}
163
164void Scene::Render() // XXX: rename to Blit()
165{
166    /* Early exit if nothing needs to be rendered */
167    if (!data->m_tiles.Count())
168        return;
169
170    if (!data->m_shader)
171        data->m_shader = Shader::Create(LOLFX_RESOURCE_NAME(tile));
172
173#if 0
174    // Randomise, then sort.
175    for (int i = 0; i < data->m_tiles.Count(); i++)
176    {
177        Tile tmp = data->m_tiles[i];
178        int j = rand() % data->m_tiles.Count();
179        data->m_tiles[i] = data->m_tiles[j];
180        data->m_tiles[j] = tmp;
181    }
182#endif
183    qsort(&data->m_tiles[0], data->m_tiles.Count(),
184          sizeof(Tile), SceneData::Compare);
185
186    // XXX: debug stuff
187    data->m_model_matrix = mat4::translate(320.0f, 240.0f, 0.0f);
188#if 0
189    static float f = 0.0f;
190    f += 0.01f;
191    data->m_model_matrix *= mat4::rotate(6.0f * sinf(f), 1.0f, 0.0f, 0.0f);
192    data->m_model_matrix *= mat4::rotate(17.0f * cosf(f), 0.0f, 0.0f, 1.0f);
193#endif
194    data->m_model_matrix *= mat4::translate(-320.0f, -240.0f, 0.0f);
195#if __ANDROID__
196    data->m_model_matrix = mat4::scale(1280.0f / 640,
197                                       736.0f / 480,
198                                       1.0f) * data->m_model_matrix;
199#endif
200    // XXX: end of debug stuff
201
202    ShaderUniform uni_mat, uni_tex;
203    ShaderAttrib attr_pos, attr_tex;
204    attr_pos = data->m_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0);
205    attr_tex = data->m_shader->GetAttribLocation("in_TexCoord", VertexUsage::TexCoord, 0);
206
207    data->m_shader->Bind();
208
209    uni_mat = data->m_shader->GetUniformLocation("proj_matrix");
210    data->m_shader->SetUniform(uni_mat, data->m_proj_matrix);
211    uni_mat = data->m_shader->GetUniformLocation("view_matrix");
212    data->m_shader->SetUniform(uni_mat, data->m_view_matrix);
213    uni_mat = data->m_shader->GetUniformLocation("model_matrix");
214    data->m_shader->SetUniform(uni_mat, data->m_model_matrix);
215
216#if defined USE_D3D9 || defined _XBOX
217#else
218    uni_tex = data->m_shader->GetUniformLocation("in_Texture");
219    data->m_shader->SetUniform(uni_tex, 0);
220
221#if !defined HAVE_GLES_2X
222    glEnable(GL_TEXTURE_2D);
223#endif
224    glEnable(GL_DEPTH_TEST);
225    glDepthFunc(GL_LEQUAL);
226#if defined HAVE_GL_2X && !defined __APPLE__
227    glEnable(GL_ALPHA_TEST);
228    glAlphaFunc(GL_GEQUAL, 0.01f);
229#endif
230    glEnable(GL_BLEND);
231    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
232#endif
233
234    for (int buf = 0, i = 0, n; i < data->m_tiles.Count(); i = n, buf += 2)
235    {
236        /* Count how many quads will be needed */
237        for (n = i + 1; n < data->m_tiles.Count(); n++)
238            if (data->m_tiles[i].tileset != data->m_tiles[n].tileset)
239                break;
240
241        /* Create a vertex array object */
242        VertexBuffer *vb1 = new VertexBuffer(6 * 3 * (n - i) * sizeof(float));
243        float *vertex = (float *)vb1->Lock(0, 0);
244        VertexBuffer *vb2 = new VertexBuffer(6 * 2 * (n - i) * sizeof(float));
245        float *texture = (float *)vb2->Lock(0, 0);
246
247        data->bufs.Push(vb1);
248        data->bufs.Push(vb2);
249
250        for (int j = i; j < n; j++)
251        {
252            data->m_tiles[i].tileset->BlitTile(data->m_tiles[j].id,
253                            data->m_tiles[j].pos, data->m_tiles[j].o,
254                            data->m_tiles[j].scale,
255                            vertex + 18 * (j - i), texture + 12 * (j - i));
256        }
257
258        vb1->Unlock();
259        vb2->Unlock();
260
261        /* Bind texture */
262        data->m_tiles[i].tileset->Bind();
263
264        /* Bind vertex and texture coordinate buffers */
265        data->m_vdecl->Bind();
266        data->m_vdecl->SetStream(vb1, attr_pos);
267        data->m_vdecl->SetStream(vb2, attr_tex);
268
269        /* Draw arrays */
270        data->m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6);
271        data->m_vdecl->Unbind();
272        data->m_tiles[i].tileset->Unbind();
273    }
274
275    data->m_tiles.Empty();
276
277    data->m_shader->Unbind();
278
279#if defined USE_D3D9 || defined _XBOX
280    /* TODO */
281#else
282#if !defined HAVE_GLES_2X
283    glDisable(GL_TEXTURE_2D);
284#endif
285    glDisable(GL_DEPTH_TEST);
286#if defined HAVE_GL_2X && !defined __APPLE__
287    glDisable(GL_ALPHA_TEST);
288#endif
289    glDisable(GL_BLEND);
290#endif
291}
292
293} /* namespace lol */
294
Note: See TracBrowser for help on using the repository browser.