1 /* This file is part of the Pangolin Project.
2  * http://github.com/stevenlovegrove/Pangolin
3  *
4  * Copyright (c) 2011 Steven Lovegrove
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following
13  * conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  */
27 
28 #pragma once
29 
30 #include <pangolin/gl/gl.h>
31 
32 namespace pangolin
33 {
34 
35 ////////////////////////////////////////////////
36 // Interface
37 ////////////////////////////////////////////////
38 
39 void MakeTriangleStripIboForVbo(GlBuffer& ibo, int w, int h);
40 
41 GlBuffer MakeTriangleStripIboForVbo(int w, int h);
42 
43 void RenderVbo(GlBuffer& vbo, GLenum mode = GL_POINTS);
44 
45 void RenderVboCbo(GlBuffer& vbo, GlBuffer& cbo, bool draw_color = true, GLenum mode = GL_POINTS);
46 
47 void RenderVboIbo(GlBuffer& vbo, GlBuffer& ibo, bool draw_mesh = true);
48 
49 void RenderVboIboCbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, bool draw_mesh = true, bool draw_color = true);
50 
51 void RenderVboIboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& nbo, bool draw_mesh = true, bool draw_normals = true);
52 
53 void RenderVboIboCboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, GlBuffer& nbo, bool draw_mesh = true, bool draw_color = true, bool draw_normals = true);
54 
55 ////////////////////////////////////////////////
56 // Implementation
57 ////////////////////////////////////////////////
58 
MakeTriangleStripIboForVbo(GlBuffer & ibo,int w,int h)59 inline void MakeTriangleStripIboForVbo(GlBuffer& ibo, int w, int h)
60 {
61     const int num_elements = w*(h-1)*2;
62     unsigned int* buffer = new unsigned int[num_elements];
63     unsigned int* ptr = buffer;
64 
65     for(int y=0; y < (h-1);)
66     {
67         for(int x=0; x<w; ++x) {
68             (*ptr++) = y*w+x;
69             (*ptr++) = (y+1)*w+x;
70         }
71         ++y;
72 
73         if(y>=(h-1)) break;
74         for(int x=w-1; x>=0; --x) {
75             (*ptr++) = y*w+x;
76             (*ptr++) = (y+1)*w+x;
77         }
78         ++y;
79     }
80 
81     ibo.Reinitialise(GlElementArrayBuffer, num_elements, GL_UNSIGNED_INT, 1, GL_STATIC_DRAW );
82     ibo.Upload(buffer, sizeof(unsigned int)*num_elements );
83 
84     delete[] buffer;
85 }
86 
MakeTriangleStripIboForVbo(int w,int h)87 inline GlBuffer MakeTriangleStripIboForVbo(int w, int h)
88 {
89     GlBuffer ibo;
90     MakeTriangleStripIboForVbo(ibo,w,h);
91     return ibo;
92 }
93 
RenderVbo(GlBuffer & vbo,GLenum mode)94 inline void RenderVbo(GlBuffer& vbo, GLenum mode)
95 {
96     vbo.Bind();
97     glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0);
98     glEnableClientState(GL_VERTEX_ARRAY);
99 
100     glDrawArrays(mode, 0, vbo.num_elements);
101 
102     glDisableClientState(GL_VERTEX_ARRAY);
103     vbo.Unbind();
104 }
105 
RenderVboCbo(GlBuffer & vbo,GlBuffer & cbo,bool draw_color,GLenum mode)106 inline void RenderVboCbo(GlBuffer& vbo, GlBuffer& cbo, bool draw_color, GLenum mode )
107 {
108     if(draw_color) {
109         cbo.Bind();
110         glColorPointer(cbo.count_per_element, cbo.datatype, 0, 0);
111         glEnableClientState(GL_COLOR_ARRAY);
112     }
113 
114     RenderVbo(vbo,mode);
115 
116     if(draw_color) {
117         glDisableClientState(GL_COLOR_ARRAY);
118         cbo.Unbind();
119     }
120 }
121 
RenderVboIbo(GlBuffer & vbo,GlBuffer & ibo,bool draw_mesh)122 inline void RenderVboIbo(GlBuffer& vbo, GlBuffer& ibo, bool draw_mesh)
123 {
124     vbo.Bind();
125     glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0);
126     glEnableClientState(GL_VERTEX_ARRAY);
127 
128     if(draw_mesh) {
129         ibo.Bind();
130         glDrawElements(GL_TRIANGLE_STRIP,ibo.num_elements, ibo.datatype, 0);
131         ibo.Unbind();
132     }else{
133         glDrawArrays(GL_POINTS, 0, vbo.num_elements);
134     }
135 
136     glDisableClientState(GL_VERTEX_ARRAY);
137     vbo.Unbind();
138 }
139 
RenderVboIboCbo(GlBuffer & vbo,GlBuffer & ibo,GlBuffer & cbo,bool draw_mesh,bool draw_color)140 inline void RenderVboIboCbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, bool draw_mesh, bool draw_color )
141 {
142     if(draw_color) {
143         cbo.Bind();
144         glColorPointer(cbo.count_per_element, cbo.datatype, 0, 0);
145         glEnableClientState(GL_COLOR_ARRAY);
146     }
147 
148     RenderVboIbo(vbo,ibo,draw_mesh);
149 
150     if(draw_color) {
151         glDisableClientState(GL_COLOR_ARRAY);
152         cbo.Unbind();
153     }
154 }
155 
RenderVboIboCboNbo(GlBuffer & vbo,GlBuffer & ibo,GlBuffer & cbo,GlBuffer & nbo,bool draw_mesh,bool draw_color,bool draw_normals)156 inline void RenderVboIboCboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, GlBuffer& nbo, bool draw_mesh, bool draw_color, bool draw_normals)
157 {
158     if(draw_color) {
159         cbo.Bind();
160         glColorPointer(cbo.count_per_element, cbo.datatype, 0, 0);
161         glEnableClientState(GL_COLOR_ARRAY);
162     }
163 
164     if(draw_normals) {
165         nbo.Bind();
166         glNormalPointer(nbo.datatype, (GLsizei)(nbo.count_per_element * GlDataTypeBytes(nbo.datatype)),0);
167         glEnableClientState(GL_NORMAL_ARRAY);
168     }
169 
170     vbo.Bind();
171     glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0);
172     glEnableClientState(GL_VERTEX_ARRAY);
173 
174     if(draw_mesh) {
175         ibo.Bind();
176         glDrawElements(GL_TRIANGLE_STRIP,ibo.num_elements, ibo.datatype, 0);
177         ibo.Unbind();
178     }else{
179         glDrawArrays(GL_POINTS, 0, vbo.num_elements);
180     }
181 
182     if(draw_color) {
183         glDisableClientState(GL_COLOR_ARRAY);
184         cbo.Unbind();
185     }
186 
187     if(draw_normals) {
188         glDisableClientState(GL_NORMAL_ARRAY);
189         nbo.Unbind();
190     }
191 
192     glDisableClientState(GL_VERTEX_ARRAY);
193     vbo.Unbind();
194 }
195 
RenderVboIboNbo(GlBuffer & vbo,GlBuffer & ibo,GlBuffer & nbo,bool draw_mesh,bool draw_normals)196 inline void RenderVboIboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& nbo, bool draw_mesh, bool draw_normals)
197 {
198     vbo.Bind();
199     glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0);
200     glEnableClientState(GL_VERTEX_ARRAY);
201 
202     if(draw_normals) {
203         nbo.Bind();
204         glNormalPointer(nbo.datatype, (GLsizei)(nbo.count_per_element * GlDataTypeBytes(nbo.datatype)), 0);
205         glEnableClientState(GL_NORMAL_ARRAY);
206     }
207 
208     if(draw_mesh) {
209         ibo.Bind();
210         glDrawElements(GL_TRIANGLE_STRIP,ibo.num_elements, ibo.datatype, 0);
211         ibo.Unbind();
212     }else{
213         glDrawArrays(GL_POINTS, 0, vbo.num_elements);
214     }
215 
216     if(draw_normals) {
217         glDisableClientState(GL_NORMAL_ARRAY);
218         nbo.Unbind();
219     }
220 
221     glDisableClientState(GL_VERTEX_ARRAY);
222     vbo.Unbind();
223 }
224 
225 }
226