source: trunk/test/tutorial/tut02.cpp @ 1228

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

gpu: port the vertex buffer abstraction layer to OpenGL.

  • Property svn:keywords set to Id
File size: 7.7 KB
Line 
1//
2// Lol Engine - Cube tutorial
3//
4// Copyright: (c) 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 "core.h"
16#include "lolgl.h"
17#include "loldebug.h"
18
19using namespace std;
20using namespace lol;
21
22#if defined _WIN32 && defined USE_D3D9
23#   define FAR
24#   define NEAR
25#   include <d3d9.h>
26#endif
27
28#if USE_SDL && defined __APPLE__
29#   include <SDL_main.h>
30#endif
31
32#if defined _WIN32
33#   undef main /* FIXME: still needed? */
34#   include <direct.h>
35#endif
36
37#if defined USE_D3D9
38extern IDirect3DDevice9 *g_d3ddevice;
39#elif defined _XBOX
40extern D3DDevice *g_d3ddevice;
41#endif
42
43class Cube : public WorldEntity
44{
45public:
46    Cube()
47    {
48        m_angle = 0;
49
50        /* Front */
51        m_vertices[0] = vec3(-1.0, -1.0,  1.0);
52        m_vertices[1] = vec3( 1.0, -1.0,  1.0);
53        m_vertices[2] = vec3( 1.0,  1.0,  1.0);
54        m_vertices[3] = vec3(-1.0,  1.0,  1.0);
55        /* Back */
56        m_vertices[4] = vec3(-1.0, -1.0, -1.0);
57        m_vertices[5] = vec3( 1.0, -1.0, -1.0);
58        m_vertices[6] = vec3( 1.0,  1.0, -1.0);
59        m_vertices[7] = vec3(-1.0,  1.0, -1.0);
60
61        m_colors[0] = vec3(1.0, 0.0, 0.0);
62        m_colors[1] = vec3(0.0, 1.0, 0.0);
63        m_colors[2] = vec3(0.0, 0.0, 1.0);
64        m_colors[3] = vec3(1.0, 1.0, 1.0);
65        m_colors[4] = vec3(1.0, 0.0, 0.0);
66        m_colors[5] = vec3(0.0, 1.0, 0.0);
67        m_colors[6] = vec3(0.0, 0.0, 1.0);
68        m_colors[7] = vec3(1.0, 1.0, 1.0);
69
70        m_indices[0] = i16vec3(0, 1, 2);
71        m_indices[1] = i16vec3(2, 3, 0);
72        m_indices[2] = i16vec3(1, 5, 6);
73        m_indices[3] = i16vec3(6, 2, 1);
74        m_indices[4] = i16vec3(7, 6, 5);
75        m_indices[5] = i16vec3(5, 4, 7);
76        m_indices[6] = i16vec3(4, 0, 3);
77        m_indices[7] = i16vec3(3, 7, 4);
78        m_indices[8] = i16vec3(4, 5, 1);
79        m_indices[9] = i16vec3(1, 0, 4);
80        m_indices[10] = i16vec3(3, 2, 6);
81        m_indices[11] = i16vec3(6, 7, 3);
82
83        m_ready = false;
84    }
85
86    virtual void TickGame(float deltams)
87    {
88        WorldEntity::TickGame(deltams);
89
90        m_angle += deltams / 1000.0f * 45.0f;
91
92        mat4 anim = mat4::rotate(m_angle, vec3(0, 1, 0));
93        mat4 model = mat4::translate(vec3(0, 0, -4));
94        mat4 view = mat4::lookat(vec3(0, 2, 0), vec3(0, 0, -4), vec3(0, 1, 0));
95        mat4 proj = mat4::perspective(45.0f, 640.0f, 480.0f, 0.1f, 10.0f);
96
97        m_matrix = proj * view * model * anim;
98    }
99
100    virtual void TickDraw(float deltams)
101    {
102        WorldEntity::TickDraw(deltams);
103
104        if (!m_ready)
105        {
106            m_shader = Shader::Create(
107#if !defined __CELLOS_LV2__ && !defined _XBOX && !defined USE_D3D9
108                "#version 120\n"
109                "attribute vec3 in_Vertex;"
110                "attribute vec3 in_Color;"
111                "uniform mat4 in_Matrix;"
112                "varying vec3 pass_Color;"
113                ""
114                "void main(void) {"
115                "    gl_Position = in_Matrix * vec4(in_Vertex, 1.0);"
116                "    pass_Color = in_Color;"
117                "}",
118
119                "#version 120\n"
120                "varying vec3 pass_Color;"
121                ""
122                "void main(void) {"
123                "    gl_FragColor = vec4(pass_Color, 1.0);"
124                "}"
125#else
126                "void main(float3 in_Vertex : POSITION,"
127                "          float3 in_Color : COLOR,"
128                "          uniform float4x4 in_Matrix,"
129                "          out float4 out_Position : POSITION,"
130                "          out float3 pass_Color : COLOR) {"
131                "    pass_Color = in_Color;"
132                "    out_Position = mul(in_Matrix, float4(in_Vertex, 1.0));"
133                "}",
134
135                "void main(float3 pass_Color : COLOR,"
136                "          out float4 out_FragColor : COLOR) {"
137                "    out_FragColor = float4(pass_Color, 1.0);"
138                "}"
139#endif
140            );
141            m_mvp = m_shader->GetUniformLocation("in_Matrix");
142            m_coord = m_shader->GetAttribLocation("in_Vertex",
143                                                  VertexUsage::Position, 0);
144            m_color = m_shader->GetAttribLocation("in_Color",
145                                                  VertexUsage::Color, 0);
146
147            m_vdecl =
148              new VertexDeclaration(VertexStream<vec3>(VertexUsage::Position),
149                                    VertexStream<vec3>(VertexUsage::Color));
150
151            m_vbo = new VertexBuffer(sizeof(m_vertices));
152            void *vertices = m_vbo->Lock(0, 0);
153            memcpy(vertices, m_vertices, sizeof(m_vertices));
154            m_vbo->Unlock();
155
156            m_cbo = new VertexBuffer(sizeof(m_colors));
157            void *colors = m_cbo->Lock(0, 0);
158            memcpy(colors, m_colors, sizeof(m_colors));
159            m_cbo->Unlock();
160
161#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__ && !defined _XBOX && !defined USE_D3D9
162            /* Method 1: store vertex buffer on the GPU memory */
163            glGenBuffers(1, &m_ibo);
164            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
165            glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_indices), m_indices,
166                         GL_STATIC_DRAW);
167#elif defined _XBOX || defined USE_D3D9
168            int16_t *indices;
169            if (FAILED(g_d3ddevice->CreateIndexBuffer(sizeof(m_indices), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_ibo, NULL)))
170                exit(0);
171            if (FAILED(m_ibo->Lock(0, 0, (void **)&indices, 0)))
172                exit(0);
173            memcpy(indices, m_indices, sizeof(m_indices));
174            m_ibo->Unlock();
175#else
176            /* TODO */
177#endif
178
179            /* FIXME: this object never cleans up */
180            m_ready = true;
181        }
182
183        m_shader->Bind();
184        m_shader->SetUniform(m_mvp, m_matrix);
185        m_vdecl->Bind();
186        m_vdecl->SetStream(m_vbo, m_coord);
187        m_vdecl->SetStream(m_cbo, m_color);
188
189#if defined _XBOX || defined USE_D3D9
190        g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
191        g_d3ddevice->SetIndices(m_ibo);
192        g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, sizeof(m_indices) / sizeof(*m_indices));
193#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
194        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
195        int size;
196        glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
197
198
199        glDrawElements(GL_TRIANGLES, size / sizeof(uint16_t), GL_UNSIGNED_SHORT, 0);
200
201        glBindBuffer(GL_ARRAY_BUFFER, 0);
202#else
203        glEnableClientState(GL_VERTEX_ARRAY);
204        glVertexPointer(3, GL_FLOAT, 0, m_vertices);
205        glDisableClientState(GL_VERTEX_ARRAY);
206#endif
207    }
208
209private:
210    float m_angle;
211    mat4 m_matrix;
212    vec3 m_vertices[8];
213    vec3 m_colors[8];
214    i16vec3 m_indices[12];
215    Shader *m_shader;
216    ShaderAttrib m_coord, m_color;
217    ShaderUniform m_mvp;
218    VertexDeclaration *m_vdecl;
219    VertexBuffer *m_vbo, *m_cbo;
220#if defined USE_D3D9
221    IDirect3DIndexBuffer9 *m_ibo;
222#elif defined _XBOX
223    D3DIndexBuffer *m_ibo;
224#else
225#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
226    GLuint m_ibo;
227#endif
228#endif
229    bool m_ready;
230};
231
232int main(int argc, char **argv)
233{
234    Application app("Tutorial 2: Cube", ivec2(640, 480), 60.0f);
235
236#if defined _MSC_VER && !defined _XBOX
237    _chdir("..");
238#elif defined _WIN32 && !defined _XBOX
239    _chdir("../..");
240#endif
241
242    new DebugFps(5, 5);
243    new Cube();
244
245    app.Run();
246
247    return EXIT_SUCCESS;
248}
249
Note: See TracBrowser for help on using the repository browser.