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