source: trunk/src/debugsphere.cpp @ 647

Last change on this file since 647 was 647, checked in by sam, 9 years ago

Switch debug sphere rendering method to vertex buffer objects.

  • Property svn:keywords set to Id
File size: 5.5 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#ifdef WIN32
16#   define _USE_MATH_DEFINES /* for M_PI */
17#   define WIN32_LEAN_AND_MEAN
18#   include <windows.h>
19#endif
20#if defined __APPLE__ && defined __MACH__
21#   include <OpenGL/gl.h>
22#else
23#   define GL_GLEXT_PROTOTYPES
24#   include <GL/gl.h>
25#endif
26
27#include <cstdio>
28#include <cmath>
29
30#include "core.h"
31#include "debugsphere.h"
32
33/*
34 * DebugSphere implementation class
35 */
36
37class DebugSphereData
38{
39    friend class DebugSphere;
40
41    void DrawSphere(int ndiv, GLfloat r, float *&vertex, float *&normal)
42    {
43        for (int i = 0; i < 20; i++)
44            DrawTriangle(vdata[tindices[i][0]],
45                         vdata[tindices[i][2]],
46                         vdata[tindices[i][1]], ndiv, r, vertex, normal);
47    }
48
49    void DrawTriangle(GLfloat const *a, GLfloat const *b, GLfloat const *c,
50                      int div, GLfloat r, float *&vertex, float *&normal)
51    {
52        if (div <= 0)
53        {
54            *normal++ = a[0]; *normal++ = a[1]; *normal++ = a[2];
55            *vertex++ = a[0] * r; *vertex++ = a[1] * r; *vertex++ = a[2] * r;
56            *normal++ = b[0]; *normal++ = b[1]; *normal++ = b[2];
57            *vertex++ = b[0] * r; *vertex++ = b[1] * r; *vertex++ = b[2] * r;
58            *normal++ = c[0]; *normal++ = c[1]; *normal++ = c[2];
59            *vertex++ = c[0] * r; *vertex++ = c[1] * r; *vertex++ = c[2] * r;
60        }
61        else
62        {
63            GLfloat ab[3], ac[3], bc[3];
64            for (int i = 0; i < 3; i++)
65            {
66                ab[i] = (a[i] + b[i]) * 0.5;
67                ac[i] = (a[i] + c[i]) * 0.5;
68                bc[i] = (b[i] + c[i]) * 0.5;
69            }
70            Normalize(ab); Normalize(ac); Normalize(bc);
71            DrawTriangle(a, ab, ac, div - 1, r, vertex, normal);
72            DrawTriangle(b, bc, ab, div - 1, r, vertex, normal);
73            DrawTriangle(c, ac, bc, div - 1, r, vertex, normal);
74            DrawTriangle(ab, bc, ac, div - 1, r, vertex, normal);
75        }
76    }
77
78    void Normalize(GLfloat *a)
79    {
80        GLfloat d = 1.0f / sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
81        a[0] *= d; a[1] *= d; a[2] *= d;
82    }
83
84private:
85    float time;
86    int initialised;
87    GLuint buflist[2];
88
89    static GLfloat const vdata[12][3];
90    static GLuint const tindices[20][3];
91    static GLfloat const X, Z;
92};
93
94GLfloat const DebugSphereData::X = .525731112119133606;
95GLfloat const DebugSphereData::Z = .850650808352039932;
96
97GLfloat const DebugSphereData::vdata[12][3] =
98{
99    {-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},
100    {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},
101    {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}
102};
103
104GLuint const DebugSphereData::tindices[20][3] =
105{
106    {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
107    {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
108    {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
109    {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11}
110};
111
112/*
113 * Public DebugSphere class
114 */
115
116DebugSphere::DebugSphere()
117  : data(new DebugSphereData())
118{
119    data->time = 0.0f;
120    data->initialised = 0;
121}
122
123void DebugSphere::TickGame(float deltams)
124{
125    Entity::TickGame(deltams);
126
127    data->time += 0.003f * deltams;
128    while (data->time > 6.0 * M_PI)
129        data->time -= 6.0 * M_PI;
130}
131
132void DebugSphere::TickDraw(float deltams)
133{
134    Entity::TickDraw(deltams);
135
136    if (IsDestroying())
137    {
138        if (data->initialised)
139        {
140            glDeleteBuffers(2, data->buflist);
141            data->initialised = 0;
142        }
143    }
144    else if (!data->initialised)
145    {
146        glGenBuffers(2, data->buflist);
147        data->initialised = 1;
148    }
149
150    float a = sinf(data->time);
151    float b = sinf(data->time * 0.5f);
152
153    int const ndiv = 2;
154    int const ntriangles = 20 * (1 << (ndiv * 2))
155                              * (int)(log(1.0f / 0.01f) / log(1.1f) + 0.9999f);
156
157    float *vertex = (float *)malloc(ntriangles * 3 * 3 * sizeof(float));
158    float *normal = (float *)malloc(ntriangles * 3 * 3 * sizeof(float));
159
160    float *vertex_parser = vertex;
161    float *normal_parser = normal;
162    for (float t = 0.01f; t < 1.0f; t *= 1.1f)
163        data->DrawSphere(ndiv, t * (60.0f + 40.0f * a),
164                         vertex_parser, normal_parser);
165
166    glEnableClientState(GL_VERTEX_ARRAY);
167    glEnableClientState(GL_NORMAL_ARRAY);
168
169    glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]);
170    glBufferData(GL_ARRAY_BUFFER, ntriangles * 3 * 3 * sizeof(float),
171                 vertex, GL_DYNAMIC_DRAW);
172    glVertexPointer(3, GL_FLOAT, 0, NULL);
173
174    glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]);
175    glBufferData(GL_ARRAY_BUFFER, ntriangles * 3 * 3 * sizeof(float),
176                 normal, GL_DYNAMIC_DRAW);
177    glNormalPointer(GL_FLOAT, 0, NULL);
178
179#if 0
180    glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT);
181#endif
182    glColor4f(1.0f, b, a, 0.1f);
183    glBindTexture(GL_TEXTURE_2D, NULL);
184
185    glTranslatef(320.0f, 240.0f, 32.0f);
186    glDrawArrays(GL_TRIANGLES, 0, ntriangles * 3);
187    glTranslatef(-320.0f, -240.0f, -32.0f);
188    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
189#if 0
190    glPopAttrib();
191#endif
192
193    glDisableClientState(GL_VERTEX_ARRAY);
194    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
195
196    free(vertex);
197    free(normal);
198}
199
200DebugSphere::~DebugSphere()
201{
202    delete data;
203}
204
Note: See TracBrowser for help on using the repository browser.