source: trunk/src/scene.cpp @ 2216

Last change on this file since 2216 was 2216, checked in by touky, 9 years ago

New year copyright update.

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