]> git.tdb.fi Git - gldbg.git/blob - flavors/gl/source/bufferstate.cpp
5060e15e21fa2a359080be9dfbf64c305c789cf4
[gldbg.git] / flavors / gl / source / bufferstate.cpp
1 /* $Id$
2
3 This file is part of gldbg
4 Copyright © 2009-2011  Mikko Rasa, Mikkosoft Productions
5 Distributed under the GPL
6 */
7
8 #include "arraysize.h"
9 #include "arraystate.h"
10 #include "bufferstate.h"
11 #include "enums.h"
12 #include "strformat.h"
13
14 using namespace std;
15
16 BufferContent::BufferContent():
17         consistent(true),
18         stride(0)
19 { }
20
21 void BufferContent::update(const ArrayState &array)
22 {
23         if(array.stride!=stride)
24                 consistent = false;
25
26         stride = array.stride;
27
28         for(vector<Array>::iterator i=arrays.begin(); i!=arrays.end(); ++i)
29                 if(i->kind==array.kind && i->index==array.index)
30                 {
31                         if(array.size!=i->size || array.type!=i->type || array.pointer!=i->offset)
32                         {
33                                 consistent = false;
34                                 arrays.erase(i);
35                         }
36                         else
37                                 return;
38
39
40                         break;
41                 }
42
43         vector<Array>::iterator place = arrays.end();
44         for(vector<Array>::iterator i=arrays.begin(); i!=arrays.end(); ++i)
45                 if(i->offset>array.pointer)
46                 {
47                         place = i;
48                         break;
49                 }
50
51         arrays.insert(place, array);
52 }
53
54 void BufferContent::update_elements(GLenum type)
55 {
56         if(arrays.empty())
57         {
58                 Array array;
59                 array.kind = GL_ELEMENT_ARRAY_BUFFER;
60                 array.type = type;
61                 arrays.push_back(array);
62                 stride = typesize(type);
63         }
64         else if(arrays.size()>1 || arrays.front().kind!=GL_ELEMENT_ARRAY_BUFFER)
65                 consistent = false;
66         else
67         {
68                 if(arrays.front().type!=type)
69                         consistent = false;
70                 arrays.front().type = type;
71                 stride = typesize(type);
72         }
73 }
74
75 string BufferContent::describe() const
76 {
77         if(arrays.empty())
78                 return "(unknown)";
79
80         string result;
81         for(vector<Array>::const_iterator i=arrays.begin(); i!=arrays.end(); ++i)
82         {
83                 char kind = '?';
84                 if(i->kind==GL_VERTEX_ARRAY)
85                         kind = 'V';
86                 else if(i->kind==GL_NORMAL_ARRAY)
87                         kind = 'N';
88                 else if(i->kind==GL_COLOR_ARRAY)
89                         kind = 'C';
90                 else if(i->kind==GL_TEXTURE_COORD_ARRAY && i->index==0)
91                         kind = 'T';
92                 else if(i->kind==GL_ELEMENT_ARRAY_BUFFER)
93                         kind = 'E';
94
95                 char type[3] = { '?', 0, 0 };
96                 if(i->type==GL_FLOAT)
97                         type[0] = 'F';
98                 else if(i->type==GL_DOUBLE)
99                         type[0] = 'D';
100                 else if(i->type==GL_INT || i->type==GL_UNSIGNED_INT)
101                         type[0] = 'I';
102                 else if(i->type==GL_SHORT || i->type==GL_UNSIGNED_SHORT)
103                         type[0] = 'S';
104                 else if(i->type==GL_BYTE || i->type==GL_UNSIGNED_BYTE)
105                         type[0] = 'B';
106
107                 if(i->type==GL_UNSIGNED_INT || i->type==GL_UNSIGNED_SHORT || i->type==GL_UNSIGNED_BYTE)
108                 {
109                         type[1] = type[0];
110                         type[0] = 'U';
111                 }
112
113                 if(!result.empty())
114                         result += '_';
115                 result += strformat("%c%d%s", kind, i->size, type);
116         }
117
118         return result;
119 }
120
121
122 BufferContent::Array::Array():
123         kind(GL_NONE),
124         index(0),
125         size(1),
126         type(GL_NONE),
127         offset(0)
128 { }
129
130 BufferContent::Array::Array(const ArrayState &a):
131         kind(a.kind),
132         index(a.index),
133         size(a.size),
134         type(a.type),
135         offset(a.pointer)
136 { }
137
138
139 BufferState::BufferState():
140         id(0),
141         target(0),
142         usage(GL_STATIC_DRAW),
143         size(0),
144         data(0)
145 { }
146
147 void BufferState::set_data(unsigned sz, const void *ptr, GLenum use)
148 {
149         usage = use;
150         size = sz;
151         delete[] data;
152         data = new char[size];
153         if(ptr)
154                 set_sub_data(0, size, ptr);
155         content = BufferContent();
156 }
157
158 void BufferState::set_sub_data(unsigned off, unsigned sz, const void *ptr)
159 {
160         if(data && off+sz<=size)
161         {
162                 const char *cptr = reinterpret_cast<const char *>(ptr);
163                 copy(cptr, cptr+sz, data+off);
164         }
165 }
166
167 string BufferState::describe() const
168 {
169         if(content.stride)
170         {
171                 const char *what = (content.arrays.front().kind==GL_ELEMENT_ARRAY_BUFFER ? "indices" : "vertices");
172                 return content.describe()+strformat(", %d %s (%d bytes), %s",
173                         size/content.stride, what, size, describe_enum(usage, ""));
174         }
175         else
176                 return strformat("%d bytes, %s", size, describe_enum(usage, ""));
177 }