]> git.tdb.fi Git - libs/gl.git/blob - source/vertexarray.cpp
Move VertexFormat and VertexArrayBuilder to their own files
[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/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::clear()
52 {
53         data.clear();
54 }
55
56 void VertexArray::reset(VertexFormat f)
57 {
58         clear();
59         format=NODATA;
60         for(uint fmt=f; fmt; fmt>>=4)
61                 format=(format, static_cast<VertexFormat>(fmt&15));
62         stride=get_stride(format);
63 }
64
65 RefPtr<VertexArrayBuilder> VertexArray::modify()
66 {
67         return new VertexArrayBuilder(*this, data);
68 }
69
70 void VertexArray::apply() const
71 {
72         if(vbuf) vbuf->bind();
73
74         const float *base=vbuf?0:&data[0];
75         uint offset=0;
76         uint found=0;
77         for(uint fmt=format; fmt; fmt>>=4)
78         {
79                 uint size=(fmt&3)+1;
80                 switch(fmt&12)
81                 {
82                 case 0:
83                         glVertexPointer(size, GL_FLOAT, stride, base+offset);
84                         break;
85                 case 4:
86                         glNormalPointer(GL_FLOAT, stride, base+offset);
87                         break;
88                 case 8:
89                         glTexCoordPointer(size, GL_FLOAT, stride, base+offset);
90                         break;
91                 case 12:
92                         if(size==1)
93                                 glColorPointer(4, GL_UNSIGNED_BYTE, stride, base+offset);
94                         else
95                                 glColorPointer(size, GL_FLOAT, stride, base+offset);
96                         break;
97                 }
98                 found|=1<<((fmt&12)>>2);
99                 offset+=size;
100         }
101
102         set_array(GL_VERTEX_ARRAY, found&1, 1);
103         set_array(GL_NORMAL_ARRAY, found&2, 2);
104         set_array(GL_TEXTURE_COORD_ARRAY, found&4, 4);
105         set_array(GL_COLOR_ARRAY, found&8, 8);
106
107         VertexBuffer::unbind();
108 }
109
110 /**
111 Updates the VertexArray data to the VertexBuffer tied to the array, if any.
112 */
113 void VertexArray::update_data()
114 {
115         if(vbuf)
116                 vbuf->data(data.size()*sizeof(float), &data[0]);
117 }
118
119 void VertexArray::set_array(unsigned array, unsigned bit, unsigned mask) const
120 {
121         if((enabled_arrays&mask) && !bit)
122         {
123                 glDisableClientState(array);
124                 enabled_arrays&=~mask;
125         }
126         else if(!(enabled_arrays&mask) && bit)
127         {
128                 glEnableClientState(array);
129                 enabled_arrays|=mask;
130         }
131 }
132
133 unsigned VertexArray::enabled_arrays=0;
134
135
136 VertexArray::Loader::Loader(VertexArray &a):
137         VertexArrayBuilder(a, a.data)
138 {
139         add("vertex2",   static_cast<void (Loader::*)(float, float)>(&Loader::vertex));
140         add("vertex3",   static_cast<void (Loader::*)(float, float, float)>(&Loader::vertex));
141         add("vertex4",   static_cast<void (Loader::*)(float, float, float, float)>(&Loader::vertex));
142         add("normal3",   static_cast<void (Loader::*)(float, float, float)>(&Loader::normal));
143         add("texcoord1", static_cast<void (Loader::*)(float)>(&Loader::texcoord));
144         add("texcoord2", static_cast<void (Loader::*)(float, float)>(&Loader::texcoord));
145         add("texcoord3", static_cast<void (Loader::*)(float, float, float)>(&Loader::texcoord));
146         add("texcoord4", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::texcoord));
147         add("color3",    static_cast<void (Loader::*)(float, float, float)>(&Loader::color));
148         add("color4",    static_cast<void (Loader::*)(float, float, float, float)>(&Loader::color));
149 }
150
151 } // namespace GL
152 } // namespace Msp