source: trunk/orbital/mesh.h @ 1256

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

orbital: split model matrix into modelview and projection so that we
can start working on lighting.

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