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

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

gpu: implement vertex buffer streams for Direct3D. OpenGL is missing for now.

  • Property svn:keywords set to Id
File size: 8.1 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        glEnableVertexAttribArray(m_coord);
195        glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
196        glVertexAttribPointer(m_coord, 3, GL_FLOAT, GL_FALSE, 0, 0);
197
198        glEnableVertexAttribArray(m_color);
199        glBindBuffer(GL_ARRAY_BUFFER, m_cbo);
200        glVertexAttribPointer(m_color, 3, GL_FLOAT, GL_FALSE, 0, 0);
201
202        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
203        int size;
204        glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
205
206
207        glDrawElements(GL_TRIANGLES, size / sizeof(uint16_t), GL_UNSIGNED_SHORT, 0);
208
209        glDisableVertexAttribArray(m_coord);
210        glDisableVertexAttribArray(m_color);
211        glBindBuffer(GL_ARRAY_BUFFER, 0);
212#else
213        glEnableClientState(GL_VERTEX_ARRAY);
214        glVertexPointer(3, GL_FLOAT, 0, m_vertices);
215        glDisableClientState(GL_VERTEX_ARRAY);
216#endif
217    }
218
219private:
220    float m_angle;
221    mat4 m_matrix;
222    vec3 m_vertices[8];
223    vec3 m_colors[8];
224    i16vec3 m_indices[12];
225    Shader *m_shader;
226    ShaderAttrib m_coord, m_color;
227    ShaderUniform m_mvp;
228    VertexDeclaration *m_vdecl;
229    VertexBuffer *m_vbo, *m_cbo;
230#if defined USE_D3D9
231    IDirect3DIndexBuffer9 *m_ibo;
232#elif defined _XBOX
233    D3DIndexBuffer *m_ibo;
234#else
235#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
236    GLuint m_ibo;
237#endif
238#endif
239    bool m_ready;
240};
241
242int main(int argc, char **argv)
243{
244    Application app("Tutorial 2: Cube", ivec2(640, 480), 60.0f);
245
246#if defined _MSC_VER && !defined _XBOX
247    _chdir("..");
248#elif defined _WIN32 && !defined _XBOX
249    _chdir("../..");
250#endif
251
252    new DebugFps(5, 5);
253    new Cube();
254
255    app.Run();
256
257    return EXIT_SUCCESS;
258}
259
Note: See TracBrowser for help on using the repository browser.