source: trunk/orbital/mesh.h @ 1263

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

orbital: fix syntax errors in the HLSL shader.

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