Line data Source code
1 : #include "../libprimis-headers/cube.h"
2 : #include "../../shared/geomexts.h"
3 : #include "../../shared/glemu.h"
4 : #include "../../shared/glexts.h"
5 :
6 : #include "rendergl.h"
7 : #include "world/octaworld.h"
8 :
9 : namespace lightsphere
10 : {
11 : namespace
12 : {
13 : size_t numverts = 0,
14 : numindices = 0;
15 : GLuint vbuf = 0, //the GLuint pointing to the lightsphere vertex buffer obj; bound to a buffer with init(), its texture deleted with cleanup(), bound by enable()
16 : ebuf = 0; //the GLuint pointing to the lightsphere element buffer obj; bound to a buffer with init(), its texture deleted with cleanup(), bound by enable()
17 :
18 0 : void init(size_t slices, size_t stacks)
19 : {
20 0 : numverts = (stacks+1)*(slices+1);
21 0 : vec * verts = new vec[numverts];
22 0 : float ds = 1.0f/slices,
23 0 : dt = 1.0f/stacks,
24 0 : t = 1.0f;
25 0 : for(size_t i = 0; i < stacks+1; ++i)
26 : {
27 0 : float rho = M_PI*(1-t),
28 0 : s = 0.0f,
29 0 : sinrho = i && i < stacks ? std::sin(rho) : 0,
30 0 : cosrho = !i ? 1 : (i < stacks ? std::cos(rho) : -1);
31 0 : for(size_t j = 0; j < slices+1; ++j)
32 : {
33 0 : float theta = j==slices ? 0 : 2*M_PI*s;
34 0 : verts[i*(slices+1) + j] = vec(-std::sin(theta)*sinrho, -std::cos(theta)*sinrho, cosrho);
35 0 : s += ds;
36 : }
37 0 : t -= dt;
38 : }
39 :
40 0 : numindices = (stacks-1)*slices*3*2;
41 0 : GLushort *indices = new ushort[numindices];
42 0 : GLushort *curindex = indices;
43 0 : for(size_t i = 0; i < stacks; ++i)
44 : {
45 0 : for(size_t k = 0; k < slices; ++k)
46 : {
47 0 : size_t j = i%2 ? slices-k-1 : k;
48 0 : if(i)
49 : {
50 0 : *curindex++ = i*(slices+1)+j;
51 0 : *curindex++ = i*(slices+1)+j+1;
52 0 : *curindex++ = (i+1)*(slices+1)+j;
53 : }
54 0 : if(i+1 < stacks)
55 : {
56 0 : *curindex++ = i*(slices+1)+j+1;
57 0 : *curindex++ = (i+1)*(slices+1)+j+1;
58 0 : *curindex++ = (i+1)*(slices+1)+j;
59 : }
60 : }
61 : }
62 0 : if(!vbuf)
63 : {
64 0 : glGenBuffers(1, &vbuf);
65 : }
66 0 : gle::bindvbo(vbuf);
67 0 : glBufferData(GL_ARRAY_BUFFER, numverts*sizeof(vec), verts, GL_STATIC_DRAW);
68 0 : delete[] verts;
69 0 : verts = nullptr;
70 0 : if(!ebuf)
71 : {
72 0 : glGenBuffers(1, &ebuf);
73 : }
74 0 : gle::bindebo(ebuf);
75 0 : glBufferData(GL_ELEMENT_ARRAY_BUFFER, numindices*sizeof(GLushort), indices, GL_STATIC_DRAW);
76 0 : delete[] indices;
77 0 : indices = nullptr;
78 0 : }
79 : }
80 0 : void cleanup()
81 : {
82 0 : if(vbuf)
83 : {
84 0 : glDeleteBuffers(1, &vbuf);
85 0 : vbuf = 0;
86 : }
87 0 : if(ebuf)
88 : {
89 0 : glDeleteBuffers(1, &ebuf);
90 0 : ebuf = 0;
91 : }
92 0 : }
93 :
94 0 : void enable()
95 : {
96 0 : if(!vbuf)
97 : {
98 0 : init(8, 4);
99 : }
100 0 : gle::bindvbo(vbuf);
101 0 : gle::bindebo(ebuf);
102 0 : gle::vertexpointer(sizeof(vec), nullptr);
103 0 : gle::enablevertex();
104 0 : }
105 :
106 0 : void draw()
107 : {
108 0 : glDrawRangeElements(GL_TRIANGLES, 0, numverts-1, numindices, GL_UNSIGNED_SHORT, nullptr);
109 0 : xtraverts += numindices;
110 0 : glde++;
111 0 : }
112 :
113 0 : void disable()
114 : {
115 0 : gle::disablevertex();
116 0 : gle::clearvbo();
117 0 : gle::clearebo();
118 0 : }
119 : }
|