]> git.tdb.fi Git - libs/gl.git/blob - source/mesh.cpp
a1930d75d124bc35f9d6c40374b9cb7b2f64cb6a
[libs/gl.git] / source / mesh.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2007-2010  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include "buffer.h"
9 #include "extension.h"
10 #include "mesh.h"
11
12 using namespace std;
13
14 namespace Msp {
15 namespace GL {
16
17 Mesh::Mesh():
18         vertices(VERTEX3),
19         ibuf(0),
20         defer_ibuf(true)
21 { }
22
23 Mesh::Mesh(const VertexFormat &f):
24         vertices(f),
25         ibuf(0),
26         defer_ibuf(true)
27 { }
28
29 Mesh::~Mesh()
30 {
31         delete ibuf;
32 }
33
34 void Mesh::clear()
35 {
36         vertices.clear();
37         batches.clear();
38 }
39
40 void Mesh::use_buffers(bool b)
41 {
42         if(b)
43         {
44                 vertices.use_vertex_buffer();
45                 if(!ibuf)
46                         ibuf = new Buffer(ELEMENT_ARRAY_BUFFER);
47                 defer_ibuf = false;
48         }
49         else
50         {
51                 vertices.use_vertex_buffer(0);
52                 delete ibuf;
53                 ibuf = 0;
54                 defer_ibuf = false;
55         }
56 }
57
58 unsigned Mesh::get_n_vertices() const
59 {
60         return vertices.size();
61 }
62
63 float *Mesh::modify_vertex(unsigned i)
64 {
65         return vertices.modify(i);
66 }
67
68 void Mesh::add_batch(const Batch &b)
69 {
70         bool can_append = false;
71         if(!batches.empty())
72         {
73                 PrimitiveType type = b.get_type();
74                 can_append = (type==batches.back().get_type() &&
75                         type!=LINE_STRIP && type!=LINE_LOOP && type!=POLYGON &&
76                         (type!=TRIANGLE_FAN || is_supported("GL_NV_primitive_restart")));
77         }
78
79         if(defer_ibuf)
80         {
81                 ibuf = new Buffer(ELEMENT_ARRAY_BUFFER);
82                 defer_ibuf = false;
83         }
84
85         if(can_append)
86                 batches.back().append(b);
87         else
88         {
89                 Batch *prev = (batches.empty() ? 0 : &batches.back());
90                 batches.push_back(b);
91                 if(ibuf)
92                         batches.back().use_index_buffer(ibuf, prev);
93         }
94 }
95
96 void Mesh::draw() const
97 {
98         vertices.apply();
99
100         if(ibuf)
101                 ibuf->bind_to(ELEMENT_ARRAY_BUFFER);
102
103         for(list<Batch>::const_iterator i=batches.begin(); i!=batches.end(); ++i)
104                 i->draw();
105
106         if(ibuf)
107                 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
108 }
109
110
111 Mesh::Loader::Loader(Mesh &m):
112         DataFile::ObjectLoader<Mesh>(m)
113 {
114         add("vertices", &Loader::vertices);
115         add("batch",    &Loader::batch);
116 }
117
118 void Mesh::Loader::vertices(VertexFormat f)
119 {
120         obj.vertices.reset(f);
121         load_sub(obj.vertices);
122 }
123
124 void Mesh::Loader::batch(PrimitiveType p)
125 {
126         Batch btc(p);
127         load_sub(btc);
128         obj.add_batch(btc);
129 }
130
131 } // namespace GL
132 } // namespace Msp