]> git.tdb.fi Git - libs/gl.git/blob - source/vertexarray.cpp
Make the use of DevIL optional
[libs/gl.git] / source / vertexarray.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2007  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include "gl.h"
9 #include "vertexarray.h"
10 #include "vertexbuffer.h"
11
12 using namespace std;
13
14 namespace Msp {
15 namespace GL {
16
17 VertexArray::VertexArray(VertexFormat f):
18         format(NODATA),
19         stride(get_stride(f)),
20         vbuf(0),
21         own_vbuf(false)
22 {
23         // Reverse the format so the first item is in lowest bits.  This makes handling in bind() easier.
24         for(uint fmt=f; fmt; fmt>>=4)
25                 format=(format, static_cast<VertexFormat>(fmt&15));
26 }
27
28 VertexArray::~VertexArray()
29 {
30         if(own_vbuf)
31                 delete vbuf;
32 }
33
34 void VertexArray::use_vertex_buffer()
35 {
36         if(vbuf) return;
37
38         vbuf=new VertexBuffer();
39         own_vbuf=true;
40         update_data();
41 }
42
43 void VertexArray::use_vertex_buffer(VertexBuffer *b)
44 {
45         if(vbuf) return;
46
47         vbuf=b;
48         update_data();
49 }
50
51 void VertexArray::reserve(unsigned n)
52 {
53         data.reserve(n*stride);
54 }
55
56 void VertexArray::clear()
57 {
58         data.clear();
59 }
60
61 void VertexArray::reset(VertexFormat f)
62 {
63         clear();
64         format=NODATA;
65         for(uint fmt=f; fmt; fmt>>=4)
66                 format=(format, static_cast<VertexFormat>(fmt&15));
67         stride=get_stride(format);
68 }
69
70 RefPtr<VertexArrayBuilder> VertexArray::modify()
71 {
72         return new VertexArrayBuilder(*this, data);
73 }
74
75 void VertexArray::apply() const
76 {
77         if(format==NODATA)
78                 throw InvalidState("Trying to apply a vertex apply of format NODATA");
79
80         if(vbuf)
81                 vbuf->bind();
82
83         const float *base=vbuf?0:&data[0];
84         uint offset=0;
85         uint found=0;
86         uint bpv=stride*sizeof(float);
87         for(uint fmt=format; fmt; fmt>>=4)
88         {
89                 uint sz=(fmt&3)+1;
90                 switch(fmt&12)
91                 {
92                 case 0:
93                         glVertexPointer(sz, GL_FLOAT, bpv, base+offset);
94                         break;
95                 case 4:
96                         glNormalPointer(GL_FLOAT, bpv, base+offset);
97                         break;
98                 case 8:
99                         glTexCoordPointer(sz, GL_FLOAT, bpv, base+offset);
100                         break;
101                 case 12:
102                         if(sz==1)
103                                 glColorPointer(4, GL_UNSIGNED_BYTE, bpv, base+offset);
104                         else
105                                 glColorPointer(sz, GL_FLOAT, bpv, base+offset);
106                         break;
107                 }
108                 found|=1<<((fmt&12)>>2);
109                 offset+=sz;
110         }
111
112         set_array(GL_VERTEX_ARRAY, found&1, 1);
113         set_array(GL_NORMAL_ARRAY, found&2, 2);
114         set_array(GL_TEXTURE_COORD_ARRAY, found&4, 4);
115         set_array(GL_COLOR_ARRAY, found&8, 8);
116
117         VertexBuffer::unbind();
118 }
119
120 /**
121 Updates the VertexArray data to the VertexBuffer tied to the array, if any.
122 */
123 void VertexArray::update_data()
124 {
125         if(vbuf)
126                 vbuf->data(data.size()*sizeof(float), &data[0]);
127 }
128
129 void VertexArray::set_array(unsigned array, unsigned bit, unsigned mask) const
130 {
131         if((enabled_arrays&mask) && !bit)
132         {
133                 glDisableClientState(array);
134                 enabled_arrays&=~mask;
135         }
136         else if(!(enabled_arrays&mask) && bit)
137         {
138                 glEnableClientState(array);
139                 enabled_arrays|=mask;
140         }
141 }
142
143 unsigned VertexArray::enabled_arrays=0;
144
145
146 VertexArray::Loader::Loader(VertexArray &a):
147         VertexArrayBuilder(a, a.data)
148 {
149         add("vertex2",   static_cast<void (Loader::*)(float, float)>(&Loader::vertex));
150         add("vertex3",   static_cast<void (Loader::*)(float, float, float)>(&Loader::vertex));
151         add("vertex4",   static_cast<void (Loader::*)(float, float, float, float)>(&Loader::vertex));
152         add("normal3",   static_cast<void (Loader::*)(float, float, float)>(&Loader::normal));
153         add("texcoord1", static_cast<void (Loader::*)(float)>(&Loader::texcoord));
154         add("texcoord2", static_cast<void (Loader::*)(float, float)>(&Loader::texcoord));
155         add("texcoord3", static_cast<void (Loader::*)(float, float, float)>(&Loader::texcoord));
156         add("texcoord4", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::texcoord));
157         add("color3",    static_cast<void (Loader::*)(float, float, float)>(&Loader::color));
158         add("color4",    static_cast<void (Loader::*)(float, float, float, float)>(&Loader::color));
159 }
160
161 } // namespace GL
162 } // namespace Msp