1 /*
2     Copyright (C) 2011 Andrew Caudwell (acaudwell@gmail.com)
3 
4     This program is free software; you can redistribute it and/or
5     modify it under the terms of the GNU General Public License
6     as published by the Free Software Foundation; either version
7     3 of the License, or (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include "bloom.h"
19 
20 //bloombuf
21 
bloombuf(int data_size)22 bloombuf::bloombuf(int data_size) : data_size(data_size) {
23     bufferid     = 0;
24     buffer_size  = 0;
25     vertex_count = 0;
26 
27     data = data_size > 0 ? new bloom_vertex[data_size] : 0;
28 
29     //fprintf(stderr, "size of bloom_vertex = %d\n", sizeof(bloom_vertex));
30 }
31 
~bloombuf()32 bloombuf::~bloombuf() {
33     if(bufferid !=0) glDeleteBuffers(1, &bufferid);
34     if(data != 0) delete[] data;
35 }
36 
resize(int new_size)37 void bloombuf::resize(int new_size) {
38 
39     bloom_vertex* _data = data;
40 
41     data = new bloom_vertex[new_size];
42 
43     for(int i=0;i<data_size;i++) {
44         data[i] = _data[i];
45     }
46 
47     data_size = new_size;
48 
49     if(_data != 0) delete[] _data;
50 }
51 
reset()52 void bloombuf::reset() {
53     vertex_count = 0;
54 }
55 
unload()56 void bloombuf::unload() {
57     if(bufferid !=0) glDeleteBuffers(1, &bufferid);
58     bufferid = 0;
59     buffer_size = 0;
60 }
61 
vertices()62 size_t bloombuf::vertices() {
63     return vertex_count;
64 }
65 
capacity()66 size_t bloombuf::capacity() {
67     return data_size;
68 }
69 
add(GLuint textureid,const vec2 & pos,const vec2 & dims,const vec4 & colour,const vec4 & texcoord)70 void bloombuf::add(GLuint textureid, const vec2& pos, const vec2& dims, const vec4& colour, const vec4& texcoord) {
71 
72     bloom_vertex v1(pos,                       colour, texcoord);
73     bloom_vertex v2(pos + vec2(dims.x, 0.0f), colour, texcoord);
74     bloom_vertex v3(pos + dims,                colour, texcoord);
75     bloom_vertex v4(pos + vec2(0.0f, dims.y), colour, texcoord);
76 
77     int i = vertex_count;
78 
79     vertex_count += 4;
80 
81     if(vertex_count > data_size) {
82         resize(vertex_count*2);
83     }
84 
85     data[i]   = v1;
86     data[i+1] = v2;
87     data[i+2] = v3;
88     data[i+3] = v4;
89 }
90 
update()91 void bloombuf::update() {
92     if(vertex_count==0) return;
93 
94     //note possibly better to have a queue and cycle them here
95     if(bufferid==0) {
96         glGenBuffers(1, &bufferid);
97     }
98 
99     glBindBuffer(GL_ARRAY_BUFFER, bufferid);
100 
101     //recreate buffer if less than the vertex_count
102     if(buffer_size < vertex_count) {
103         buffer_size = data_size;
104         glBufferData(GL_ARRAY_BUFFER, buffer_size*sizeof(bloom_vertex), &(data[0].pos.x), GL_DYNAMIC_DRAW);
105     } else {
106         glBufferSubData(GL_ARRAY_BUFFER, 0, vertex_count*sizeof(bloom_vertex), &(data[0].pos.x));
107     }
108 
109     glBindBuffer(GL_ARRAY_BUFFER, 0);
110 }
111 
draw()112 void bloombuf::draw() {
113     if(vertex_count==0 || bufferid==0) return;
114 
115     glBindBuffer(GL_ARRAY_BUFFER, bufferid);
116 
117     glEnableClientState(GL_VERTEX_ARRAY);
118     glEnableClientState(GL_COLOR_ARRAY);
119     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
120 
121     glVertexPointer(2,   GL_FLOAT, sizeof(bloom_vertex), 0);
122     glColorPointer(4,    GL_FLOAT, sizeof(bloom_vertex), (GLvoid*)8);  // offset pos (2x4 bytes)
123     glTexCoordPointer(4, GL_FLOAT, sizeof(bloom_vertex), (GLvoid*)24); // offset pos + colour (2x4 + 4x4 bytes)
124 
125     glDrawArrays(GL_QUADS, 0, vertex_count);
126 
127     glDisableClientState(GL_VERTEX_ARRAY);
128     glDisableClientState(GL_COLOR_ARRAY);
129     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
130 
131     glBindBuffer(GL_ARRAY_BUFFER, 0);
132 }
133