source: trunk/orbital/mesh.h @ 1249

Last change on this file since 1249 was 1249, checked in by sam, 8 years ago

orbital: the mesh builder is now almost operational! vertex colour doesn't
seem to work yet.

  • Property svn:keywords set to Id
File size: 12.3 KB
Line 
1//
2// Orbital
3//
4// Copyright: (c) 2012 Various People
5//
6
7#if !defined __MESH_H__
8#define __MESH_H__
9
10class Mesh
11{
12public:
13    Mesh()
14      : m_color(0), m_color2(0),
15        m_vert_cursor(0), m_quadidx_cursor(0), m_triidx_cursor(0)
16    {}
17
18    void Flush()
19    {
20        m_vert_cursor = m_vert.Count();
21        m_quadidx_cursor = m_quadidx.Count();
22        m_triidx_cursor = m_triidx.Count();
23    }
24
25    void MeshConvert()
26    {
27        m_gpu.shader = Shader::Create(
28#if !defined __CELLOS_LV2__ && !defined _XBOX && !defined USE_D3D9
29            "#version 120\n"
30            "attribute vec3 in_Vertex;"
31            "attribute vec3 in_Normal;"
32            "attribute vec4 in_Color;"
33            "uniform mat4 in_Matrix;"
34            "varying vec4 pass_Color;"
35            ""
36            "void main(void) {"
37            "    gl_Position = in_Matrix * vec4(in_Vertex, 1.0);"
38            "    pass_Color = in_Color;"
39            "}",
40
41            "#version 120\n"
42            "varying vec4 pass_Color;"
43            ""
44            "void main(void) {"
45            "    gl_FragColor = pass_Color;"
46            "}"
47#else
48            "void main(float3 in_Vertex : POSITION,"
49            "          float3 in_Normal : NORMAL,"
50            "          float4 in_Color : COLOR,"
51            "          uniform float4x4 in_Matrix,"
52            "          out float4 out_Position : POSITION,"
53            "          out float4 pass_Color : COLOR) {"
54            "    pass_Color = in_Color;"
55            "    out_Position = mul(in_Matrix, float4(in_Vertex, 1.0));"
56            "}",
57
58            "void main(float4 pass_Color : COLOR,"
59            "          out float4 out_FragColor : COLOR) {"
60            "    out_FragColor = pass_Color;"
61            "}"
62#endif
63        );
64        m_gpu.mvp = m_gpu.shader->GetUniformLocation("in_Matrix");
65        m_gpu.coord = m_gpu.shader->GetAttribLocation("in_Vertex",
66                                              VertexUsage::Position, 0);
67        m_gpu.norm = m_gpu.shader->GetAttribLocation("in_Normal",
68                                             VertexUsage::Normal, 0);
69        m_gpu.color = m_gpu.shader->GetAttribLocation("in_Color",
70                                              VertexUsage::Color, 0);
71
72        m_gpu.vdecl = new VertexDeclaration(
73            VertexStream<vec3,vec3,u8vec4>(VertexUsage::Position,
74                                           VertexUsage::Normal,
75                                           VertexUsage::Color));
76
77        Array<vec3,vec3,u8vec4> vertexlist;
78        for (int i = 0; i < m_vert.Count(); i++)
79            vertexlist.Append(m_vert[i].m1,
80                              m_vert[i].m2,
81                              (u8vec4)(m_vert[i].m3 * 255.f));
82
83        Array<uint16_t> indexlist;
84        for (int i = 0; i < m_triidx.Count(); i += 3)
85        {
86            indexlist += m_triidx[i + 2];
87            indexlist += m_triidx[i + 1];
88            indexlist += m_triidx[i + 0];
89        }
90        for (int i = 0; i < m_quadidx.Count(); i += 3)
91        {
92            indexlist += m_quadidx[i + 2];
93            indexlist += m_quadidx[i + 1];
94            indexlist += m_quadidx[i + 0];
95
96            indexlist += m_quadidx[i + 3];
97            indexlist += m_quadidx[i + 2];
98            indexlist += m_quadidx[i + 0];
99        }
100
101        m_gpu.vbo = new VertexBuffer(vertexlist.Bytes());
102        void *mesh = m_gpu.vbo->Lock(0, 0);
103        memcpy(mesh, &vertexlist[0], vertexlist.Bytes());
104        m_gpu.vbo->Unlock();
105
106        m_gpu.ibo = new IndexBuffer(indexlist.Bytes());
107        void *indices = m_gpu.ibo->Lock(0, 0);
108        memcpy(indices, &indexlist[0], indexlist.Bytes());
109        m_gpu.ibo->Unlock();
110
111        m_gpu.vertexcount = vertexlist.Count();
112        m_gpu.indexcount = indexlist.Count();
113    }
114
115    void Render(mat4 const &mvp)
116    {
117        m_gpu.shader->Bind();
118        m_gpu.shader->SetUniform(m_gpu.mvp, mvp);
119        m_gpu.vdecl->SetStream(m_gpu.vbo, m_gpu.coord, m_gpu.norm, m_gpu.color);
120        m_gpu.vdecl->Bind();
121        m_gpu.ibo->Bind();
122        m_gpu.vdecl->DrawIndexedElements(MeshPrimitive::Triangles,
123                                         0, 0, m_gpu.vertexcount,
124                                         0, m_gpu.indexcount / 3);
125        m_gpu.ibo->Unbind();
126        m_gpu.vdecl->Unbind();
127    }
128
129    void SetCurColor(vec4 const &color) { m_color = color; }
130    void SetCurColor2(vec4 const &color) { m_color2 = color; }
131
132    void AppendQuadVert(vec3 const &coord)
133    {
134        m_vert.Append(coord, vec3(0.f, 1.f, 0.f), m_color);
135    }
136
137    void AppendDuplicateQuadVert(int i)
138    {
139        m_vert.Append(m_vert[i].m1, vec3(0.f, 1.f, 0.f), m_vert[i].m3);
140    }
141
142    void AppendQuad(int i1, int i2, int i3, int i4, int base)
143    {
144        m_quadidx += base + i1;
145        m_quadidx += base + i2;
146        m_quadidx += base + i3;
147        m_quadidx += base + i4;
148    }
149
150    void AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base)
151    {
152        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i1);
153        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i2);
154        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i3);
155        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i4);
156    }
157
158    void AppendTriangle(int i1, int i2, int i3, int base)
159    {
160        m_quadidx += base + i1;
161        m_quadidx += base + i2;
162        m_quadidx += base + i3;
163    }
164
165    void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base)
166    {
167        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i1);
168        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i2);
169        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i3);
170    }
171
172    void ComputeQuadNormals(int start, int vcount)
173    {
174        for (int i = 0; i < vcount; i += 4)
175        {
176            vec3 v0 = m_vert[m_quadidx[start + i + 2]].m1
177                    - m_vert[m_quadidx[start + i + 0]].m1;
178            vec3 v1 = m_vert[m_quadidx[start + i + 1]].m1
179                    - m_vert[m_quadidx[start + i + 0]].m1;
180            vec3 n = normalize(cross(v1, v0));
181
182            for (int j = 0; j < 4; j++)
183                m_vert[m_quadidx[start + i + j]].m2 = n;
184        }
185    }
186
187    void ComputeTriNormals(int start, int vcount)
188    {
189        for (int i = 0; i < vcount; i += 3)
190        {
191            vec3 v0 = m_vert[m_quadidx[start + i + 2]].m1
192                    - m_vert[m_quadidx[start + i + 0]].m1;
193            vec3 v1 = m_vert[m_quadidx[start + i + 1]].m1
194                    - m_vert[m_quadidx[start + i + 0]].m1;
195            vec3 n = normalize(cross(v1, v0));
196
197            for (int j = 0; j < 3; j++)
198                m_vert[m_quadidx[start + i + j]].m2 = n;
199        }
200    }
201
202    void SetVertColor(vec4 const &color)
203    {
204        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
205            m_vert[i].m3 = color;
206    }
207
208    void SetCurVertNormal(vec3 const &normal)
209    {
210        m_vert[m_vert.Count() - 1].m2 = normal;
211    }
212
213    void SetCurVertColor(vec4 const &color)
214    {
215        m_vert[m_vert.Count() - 1].m3 = color;
216    }
217
218    void Translate(vec3 const &v)
219    {
220        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
221            m_vert[i].m1 += v;
222    }
223
224    void RotateZ(float t)
225    {
226        /* FIXME: use mat3 instead of mat4 when it's working */
227        mat4 m = mat4::rotate(t, 0, 0, 1);
228        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
229            m_vert[i].m1 = (m * vec4(m_vert[i].m1, 1.f)).xyz;
230    }
231
232    void RotateY(float t)
233    {
234        mat4 m = mat4::rotate(t, 0, 1, 0);
235        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
236            m_vert[i].m1 = (m * vec4(m_vert[i].m1, 1.f)).xyz;
237    }
238
239    void RotateX(float t)
240    {
241        mat4 m = mat4::rotate(t, 1, 0, 0);
242        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
243            m_vert[i].m1 = (m * vec4(m_vert[i].m1, 1.f)).xyz;
244    }
245
246    void TaperX(float y, float z, float xoff)
247    {
248        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
249        {
250            m_vert[i].m1.y *= 1.f + (y * m_vert[i].m1.x + xoff);
251            m_vert[i].m1.z *= 1.f + (z * m_vert[i].m1.x + xoff);
252        }
253    }
254
255    void TaperY(float x, float z, float yoff)
256    {
257        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
258        {
259            m_vert[i].m1.x *= 1.f + (x * m_vert[i].m1.y + yoff);
260            m_vert[i].m1.z *= 1.f + (z * m_vert[i].m1.y + yoff);
261        }
262    }
263
264    void TaperZ(float x, float y, float zoff)
265    {
266        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
267        {
268            m_vert[i].m1.x *= 1.f + (x * m_vert[i].m1.z + zoff);
269            m_vert[i].m1.y *= 1.f + (y * m_vert[i].m1.z + zoff);
270        }
271    }
272
273    void Scale(vec3 const &s)
274    {
275        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
276        {
277            m_vert[i].m1 *= s;
278            m_vert[i].m2 *= s;
279        }
280
281        // BH : TODO : not sure about this one
282        // Sam: not too sure either!
283        if (s.x * s.y * s.z < 0)
284        {
285            for (int i = m_quadidx_cursor; i < m_quadidx.Count(); i += 2)
286            {
287                uint16_t tmp = m_quadidx[i + 0];
288                m_quadidx[i + 0] = m_quadidx[i + 1];
289                m_quadidx[i + 1] = tmp;
290            }
291
292            for (int i = m_triidx_cursor; i < m_triidx.Count(); i += 3)
293            {
294                uint16_t tmp = m_triidx[i + 0];
295                m_triidx[i + 0] = m_triidx[i + 1];
296                m_triidx[i + 1] = tmp;
297            }
298        }
299    }
300
301    void MirrorX() { Duplicate(); Scale(vec3(-1, 1, 1)); }
302    void MirrorY() { Duplicate(); Scale(vec3(1, -1, 1)); }
303    void MirrorZ() { Duplicate(); Scale(vec3(1, 1, -1)); }
304
305    void Duplicate()
306    {
307        int vlen = m_vert.Count() - m_vert_cursor;
308        int qlen = m_quadidx.Count() - m_quadidx_cursor;
309        int tlen = m_triidx.Count() - m_triidx_cursor;
310
311        for (int i = 0; i < vlen; i++)
312            m_vert += m_vert[m_vert_cursor++];
313
314        for (int i = 0; i < qlen; i++)
315            m_quadidx += m_quadidx[m_quadidx_cursor++] + vlen;
316
317        for (int i = 0; i < tlen; i++)
318            m_triidx += m_triidx[m_triidx_cursor++] + vlen;
319    }
320
321    void AppendCylinder() {} /* TODO */
322
323    void AppendBox(vec3 const &size)
324    {
325        AppendBox(size, 0.f);
326    }
327
328    void AppendBox(vec3 const &size, float chamf)
329    {
330        int ibase = m_quadidx.Count();
331        int vbase = m_vert.Count();
332
333        vec3 d = size * 0.5f;
334
335        AppendQuadVert(vec3(-d.x, -d.y, -d.z - chamf));
336        AppendQuadVert(vec3(-d.x, +d.y, -d.z - chamf));
337        AppendQuadVert(vec3(+d.x, +d.y, -d.z - chamf));
338        AppendQuadVert(vec3(+d.x, -d.y, -d.z - chamf));
339
340        AppendQuadVert(vec3(-d.x - chamf, -d.y, +d.z));
341        AppendQuadVert(vec3(-d.x - chamf, +d.y, +d.z));
342        AppendQuadVert(vec3(-d.x - chamf, +d.y, -d.z));
343        AppendQuadVert(vec3(-d.x - chamf, -d.y, -d.z));
344
345        AppendQuadVert(vec3(+d.x, -d.y, +d.z + chamf));
346        AppendQuadVert(vec3(+d.x, +d.y, +d.z + chamf));
347        AppendQuadVert(vec3(-d.x, +d.y, +d.z + chamf));
348        AppendQuadVert(vec3(-d.x, -d.y, +d.z + chamf));
349
350        AppendQuadVert(vec3(+d.x + chamf, -d.y, -d.z));
351        AppendQuadVert(vec3(+d.x + chamf, +d.y, -d.z));
352        AppendQuadVert(vec3(+d.x + chamf, +d.y, +d.z));
353        AppendQuadVert(vec3(+d.x + chamf, -d.y, +d.z));
354
355        AppendQuadVert(vec3(-d.x, -d.y - chamf, +d.z));
356        AppendQuadVert(vec3(-d.x, -d.y - chamf, -d.z));
357        AppendQuadVert(vec3(+d.x, -d.y - chamf, -d.z));
358        AppendQuadVert(vec3(+d.x, -d.y - chamf, +d.z));
359
360        AppendQuadVert(vec3(-d.x, +d.y + chamf, -d.z));
361        AppendQuadVert(vec3(-d.x, +d.y + chamf, +d.z));
362        AppendQuadVert(vec3(+d.x, +d.y + chamf, +d.z));
363        AppendQuadVert(vec3(+d.x, +d.y + chamf, -d.z));
364
365        AppendQuad(0, 1, 2, 3, vbase);
366        AppendQuad(4, 5, 6, 7, vbase);
367        AppendQuad(8, 9, 10, 11, vbase);
368        AppendQuad(12, 13, 14, 15, vbase);
369        AppendQuad(16, 17, 18, 19, vbase);
370        AppendQuad(20, 21, 22, 23, vbase);
371
372        ComputeQuadNormals(ibase, m_quadidx.Count() - ibase);
373    }
374
375private:
376    vec4 m_color, m_color2;
377    Array<uint16_t> m_triidx, m_quadidx;
378    Array<vec3, vec3, vec4> m_vert;
379    int m_vert_cursor, m_quadidx_cursor, m_triidx_cursor;
380
381    struct
382    {
383        Shader *shader;
384        ShaderAttrib coord, norm, color;
385        ShaderUniform mvp;
386        VertexDeclaration *vdecl;
387        VertexBuffer *vbo;
388        IndexBuffer *ibo;
389        int vertexcount, indexcount;
390    }
391    m_gpu;
392};
393
394#endif /* __MESH_H__ */
395
Note: See TracBrowser for help on using the repository browser.