1 // This file belongs to the "MiniCore" game engine.
2 // Copyright (C) 2013 Jussi Lind <jussi.lind@iki.fi>
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 2
7 // 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, write to the Free Software
16 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 // MA  02110-1301, USA.
18 //
19 
20 #ifndef MCGLOBJECTBASE_HH
21 #define MCGLOBJECTBASE_HH
22 
23 #include "mcglmaterial.hh"
24 #include "mcglshaderprogram.hh"
25 #include "mcgltexcoord.hh"
26 #include "mcglvertex.hh"
27 #include <MCGLEW>
28 
29 class MCCamera;
30 
31 /*! Base class for GL renderables in MiniCore. Automatically creates VBO, VAO and
32  *  basic texturing support. */
33 #ifdef __MC_QOPENGLFUNCTIONS__
34 #include <QOpenGLFunctions>
35 #include <QOpenGLVertexArrayObject>
36 class MCGLObjectBase : protected QOpenGLFunctions
37 #else
38 class MCGLObjectBase
39 #endif
40 {
41 public:
42     //! Constructor.
43     explicit MCGLObjectBase(std::string handle);
44 
45     //! Destructor.
46     virtual ~MCGLObjectBase();
47 
48     //! Create the VAO. Return false if VAO not available.
49     bool createVAO();
50 
51     //! Bind the VAO. VAO will be created when constructed.
52     void bindVAO();
53 
54     //! Release the VAO.
55     void releaseVAO();
56 
57     //! Create the VBO.
58     void createVBO();
59 
60     //! Bind the VBO. VBO will be created when constructed.
61     void bindVBO();
62 
63     //! Release the VBO.
64     void releaseVBO();
65 
66     /*! Render by using the default size.
67      * \param pos The position.
68      * \param wr Half of the wanted width.
69      * \param hr Half of the wanted height. */
70     virtual void render(MCCamera * camera, MCVector3dFR pos, float angle);
71 
72     //! Render (fake) shadow
73     virtual void renderShadow(MCCamera * camera, MCVector3dFR pos, float angle);
74 
75     //! Render the vertex buffer only. bind() must be called separately.
76     virtual void render();
77 
78     //! Helper to bind texturing and VAO.
79     virtual void bind();
80 
81     //! Helper to bind texturing and VAO for shadow rendering.
82     virtual void bindShadow();
83 
84     //! Helper to bind texturing and VAO.
85     virtual void release();
86 
87     //! Helper to bind texturing and VAO for shadow rendering.
88     virtual void releaseShadow();
89 
90     //! Set the shader program to be used.
91     void setShaderProgram(MCGLShaderProgramPtr program);
92 
93     //! Set the shader program to be used for 2d shadows.
94     void setShadowShaderProgram(MCGLShaderProgramPtr program);
95 
96     //! Get the shader program to be used.
97     MCGLShaderProgramPtr shaderProgram() const;
98 
99     //! Get the shader program to be used for 2d shadows.
100     MCGLShaderProgramPtr shadowShaderProgram() const;
101 
102     //! Set material.
103     void setMaterial(MCGLMaterialPtr material);
104 
105     //! Get material if set.
106     MCGLMaterialPtr material() const;
107 
108     //! Get vertex
109     const MCGLVertex & vertex(size_t index) const;
110 
111     //! Get vertices
112     const GLfloat * verticesAsGlArray() const;
113 
114     size_t vertexCount() const;
115 
116     const MCGLVertex & normal(size_t index) const;
117 
118     const GLfloat * normalsAsGlArray() const;
119 
120     //! Set mesh color.
121     void setColor(const MCGLColor & color);
122 
123     //! Get mesh color.
124     MCGLColor color() const;
125 
126     //! Get a vertex color, needed for batching
127     const MCGLColor & color(size_t index) const;
128 
129     //! Get a vertex colors
130     const GLfloat * colorsAsGlArray() const;
131 
132     //! Get texture coord of a vertex
133     const MCGLTexCoord & texCoord(size_t index) const;
134 
135     //! Get texture coords
136     const GLfloat * texCoordsAsGlArray() const;
137 
138     //! Get scale
139     MCVector3dF scale() const;
140 
141     //! Set scaling factors.
142     void setScale(const MCVector3dF & scale);
143 
144     //! Set object size. Actually this just calculates the corresponding scale.
145     void setSize(float width, float height);
146 
147     //! Get width
148     float width() const;
149 
150     void setWidth(float width);
151 
152     //! Get height
153     float height() const;
154 
155     void setHeight(float height);
156 
157     //! Get minimum Z
158     float minZ() const;
159 
160     void setMinZ(float minZ);
161 
162     //! Get maximum Z
163     float maxZ() const;
164 
165     void setMaxZ(float maxZ);
166 
167     std::string handle() const;
168 
169     void setHandle(const std::string & handle);
170 
171 protected:
172     //! Store a vertex, needed for batching
173     void addVertex(const MCGLVertex & vertex);
174 
175     //! Set vertices
176     template<typename T>
177     using Container = std::vector<T>;
178     using VertexVector = Container<MCGLVertex>;
179     void setVertices(const VertexVector & vertices);
180 
181     //! Store a normal, needed for batching
182     void addNormal(const MCGLVertex & normal);
183 
184     //! Set normals
185     void setNormals(const VertexVector & normals);
186 
187     //! Store a tex coord, needed for batching
188     void addTexCoord(const MCGLTexCoord & texCoord);
189 
190     //! Set texture coords
191     using TexCoordVector = Container<MCGLTexCoord>;
192     void setTexCoords(const TexCoordVector & texCoords);
193 
194     //! Store a vertex color, needed for batching
195     void addColor(const MCGLColor & color);
196 
197     //! Set vertex colors
198     using ColorVector = Container<MCGLColor>;
199     void setColors(const ColorVector & colors);
200 
201     //! This should be called after setting vertices, texture coords, normals and colors
202     void initBufferData(size_t totalDataSize, GLuint drawType = GL_STATIC_DRAW);
203 
204     void addBufferSubData(MCGLShaderProgram::VertexAttribLocations dataType, size_t dataSize, const GLfloat * data);
205 
206     void addBufferSubData(MCGLShaderProgram::VertexAttribLocations dataType, size_t dataSize, size_t offsetJump, const GLfloat * data);
207 
208     void finishBufferData();
209 
210     void initUpdateBufferData();
211 
212     size_t totalDataSize() const;
213 
214     virtual void setAttributePointers();
215 
216     void enableAttributePointers();
217 
218     void disableAttributePointers();
219 
220 private:
221     static GLuint m_boundVbo;
222 
223     std::string m_handle;
224 
225 #ifdef __MC_QOPENGLFUNCTIONS__
226     QOpenGLVertexArrayObject m_vao;
227 #else
228     GLuint m_vao = 0;
229 #endif
230     GLuint m_vbo = 0;
231 
232     MCGLShaderProgramPtr m_program;
233 
234     MCGLShaderProgramPtr m_shadowProgram;
235 
236     MCGLMaterialPtr m_material;
237 
238     size_t m_bufferDataOffset = 0;
239 
240     size_t m_vertexDataSize = 0;
241 
242     size_t m_normalDataSize = 0;
243 
244     size_t m_texCoordDataSize = 0;
245 
246     size_t m_colorDataSize = 0;
247 
248     size_t m_totalDataSize = 0;
249 
250     bool m_hasVao = false;
251 
252     VertexVector m_vertices;
253 
254     VertexVector m_normals;
255 
256     std::vector<MCGLTexCoord> m_texCoords;
257 
258     std::vector<MCGLColor> m_colors;
259 
260     MCGLColor m_color;
261 
262     float m_width = 0;
263 
264     float m_height = 0;
265 
266     float m_minZ = 0;
267 
268     float m_maxZ = 0;
269 
270     MCVector3dF m_scale = MCVector3dF(1.0f, 1.0f, 1.0f);
271 
272     friend class MCGLRectParticle; // Direct access to protected methods without inheritance
273 };
274 
275 #endif // MCGLOBJECTBASE_HH
276