1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: oglstuff.h 3 // Purpose: OpenGL manager for pyramid sample 4 // Author: Manuel Martin 5 // Created: 2015/01/31 6 // Copyright: (c) 2015 Manuel Martin 7 // Licence: wxWindows licence 8 ///////////////////////////////////////////////////////////////////////////// 9 10 #ifndef OGLSTUFF_H 11 #define OGLSTUFF_H 12 13 #include <string> 14 #include <vector> 15 16 #include "mathstuff.h" 17 18 // This file allows access to OpenGL functions used in this sample. 19 #include "oglpfuncs.h" 20 21 /* 22 ************ NOTES ******************************************************* 23 This is not an OGL tutorial, I mean, this is just a sample of how OGL stuff 24 may be arranged. I tried to keep it simple. 25 It's likely that the novice to OGL reads this sample, so here are some brief 26 notes: 27 * Starting with OpenGL >= 2.0 the user defines some special programs that are 28 going to be executed in the GPU, not in the CPU. These programs are called 29 "Shaders". Since OGL >= 3.2, and if a "Core Profile" context is set, the use 30 of shaders is the only way to make an OGL application. 31 * A program consists (at least) of a 'vertex shader' who operates on the 32 vertices that define the primitive (a triangle, a line, etc) and a 'fragment 33 shader' which deals with fragments (points) interpolated from the previously 34 processed vertices in the vertex shader. 35 * Shaders must be compiled and linked, both operations are done on the GPU. 36 * Shaders are written in the GLSL language, that looks like C, but it isn't C. 37 * Data (vertices, textures) are stored in GPU memory, so they don't need to be 38 loaded each time the scene must be redrawn. 39 * Rotations and translations are matrix operations that the GPU may do in the 40 [vertex]shaders. The user must define the needed matrices. 41 * A vertex shader defines special vars ("attributes") used for reading the 42 data from the GPU buffers. Other special vars ("uniforms") are used for 43 values that don't change with each vertex (i.e. the matrices). 44 * The relationship between a data buffer and the input attributes in a vertex 45 shader can be saved in a "Vertex Array Object" (VAO). 46 47 I use several classes for typical OGL jobs: Shaders, Data, Camera. 48 Because different GPU cards may behave on their own, I also use very often 49 an error-helper. It will inform of the point where something went wrong. 50 51 I decided to keep apart all of this from wxWidgets. You won't find anything 52 related to wxWidgets in the oglstuff[.h][.cpp] files. 53 That's why I use std::vector and std:string instead of those provided by wx. 54 */ 55 56 57 // Define our own GL errors 58 enum 59 { 60 myoglERR_CLEAR = 0, 61 myoglERR_JUSTLOG, 62 63 myoglERR_SHADERCREATE, 64 myoglERR_SHADERCOMPILE, 65 myoglERR_SHADERLINK, 66 myoglERR_SHADERLOCATION, 67 68 myoglERR_BUFFER, 69 myoglERR_TEXTIMAGE, 70 71 myoglERR_DRAWING_TRI, 72 myoglERR_DRAWING_STR 73 }; 74 75 // Used to handle GL errors in other part of the app. 76 typedef void myOGLErrHandler(int err, int glerr, const GLchar* glMsg); 77 78 // For shader attributes 79 struct shaVars 80 { 81 GLuint loc; //The attribute "location", some kind of index in the shader 82 std::string name; //The name of the attribute 83 }; 84 85 typedef std::vector<shaVars> shaVars_v; 86 87 // For shader code 88 struct shaShas 89 { 90 GLuint shaId; 91 GLenum typeSha; //The type of shader 92 const GLchar* scode; //The NULL terminated GLSL code 93 }; 94 95 typedef std::vector<shaShas> shaShas_v; 96 97 98 //----------------------------------------------------------------------------- 99 // This object builds a GPU program by joining several shaders. 100 class myOGLShaders 101 { 102 public: 103 myOGLShaders(); 104 ~myOGLShaders(); 105 106 void Init(); 107 bool Use(); 108 void StopUse(); 109 void CleanUp(); 110 111 void AddCode(const GLchar* shaString, GLenum shaType); 112 void AddAttrib(const std::string& name); 113 void AddUnif(const std::string& name); 114 GLuint GetAttribLoc(const std::string& name); 115 GLuint GetUnifLoc(const std::string& name); 116 // Disable generic vertex attribute array 117 void DisableGenericVAA(); 118 119 private: 120 void SetAttribLocations(); 121 bool AskUnifLocations(); 122 bool Compile(GLuint shaId); 123 bool LinkProg(GLuint proId); 124 125 shaVars_v m_shaAttrib; // 'attributes' names and locations 126 shaVars_v m_shaUnif; // 'uniforms' names and locations 127 shaShas_v m_shaCode; // shaders code and their types 128 GLuint m_proId; // program Id 129 130 bool m_SHAinitializated; 131 }; 132 133 //----------------------------------------------------------------------------- 134 // A "point light" 135 class myLight 136 { 137 public: myLight()138 myLight() {} ~myLight()139 ~myLight() {} 140 141 void Set(const myVec3& position, GLfloat intensity, 142 GLfloat R, GLfloat G, GLfloat B); 143 // Return position and intensity GetFLightPos()144 const GLfloat* GetFLightPos() const 145 { return m_PosAndIntensisty; } 146 // Return colour GetFLightColour()147 const GLfloat* GetFLightColour() const 148 { return m_Colour; } 149 150 private: 151 // Light position and intensity 152 GLfloat m_PosAndIntensisty[4]; 153 // Light colour 154 GLfloat m_Colour[3]; 155 }; 156 157 //----------------------------------------------------------------------------- 158 // An object for triangles 159 class myOGLTriangles 160 { 161 public: 162 myOGLTriangles(); 163 ~myOGLTriangles(); 164 165 // Clean up 166 void Clear(); 167 // Load data into the GPU 168 void SetBuffers(myOGLShaders* theShader, GLsizei nuPoints, GLsizei nuTriangs, 169 const GLfloat* vert, const GLfloat* colo, 170 const GLfloat* norm, const GLushort* indices); 171 172 //Draw the triangles 173 void Draw(const GLfloat* unifMvp, const GLfloat* unifToVw, 174 const myLight* theLight); 175 176 private: 177 GLsizei m_nuTriangs; 178 // Buffers ids 179 GLuint m_bufVertId; 180 GLuint m_bufColNorId; 181 GLuint m_bufIndexId; 182 // Vertex Arrays Object 183 GLuint m_triangVAO; 184 // GPU Program used to draw the triangles 185 myOGLShaders* m_triangShaders; 186 }; 187 188 //----------------------------------------------------------------------------- 189 // An object for strings 190 class myOGLString 191 { 192 public: 193 myOGLString(); 194 ~myOGLString(); 195 196 // Clean up 197 void Clear(); 198 // Load data into the GPU 199 void SetStringWithVerts(myOGLShaders* theShader, 200 const unsigned char* tImage, int tWidth, int tHeigh, 201 const GLfloat* vert, const GLfloat* norm); 202 // Draw the string 203 void Draw(const GLfloat* unifMvp, const GLfloat* unifToVw, 204 const myLight* theLight); 205 206 207 private: 208 GLuint m_bufPosId; // Buffer id 209 GLuint m_stringVAO; // Vertex Arrays Object 210 GLuint m_textureUnit; // The context unit 211 GLuint m_textureId; // Texture name 212 // GPU Program used to draw the texture 213 myOGLShaders* m_stringShaders; 214 }; 215 216 //----------------------------------------------------------------------------- 217 // An object for the immutable string 218 class myOGLImmutString : public myOGLString 219 { 220 public: myOGLImmutString()221 myOGLImmutString(){} ~myOGLImmutString()222 ~myOGLImmutString(){} 223 224 // Load data into the GPU 225 void SetImmutString(myOGLShaders* theShader, 226 const unsigned char* tImage, int tWidth, int tHeigh); 227 // Update orthogonal projection matrix 228 void SetOrtho(int winWidth, int winHeight); 229 // The transformation matrix GetFloatMVP()230 const GLfloat* GetFloatMVP() { return m_fOrtho; } 231 232 private: 233 double m_dOrtho[16]; // The orthogonal projection matrix 234 GLfloat m_fOrtho[16]; // Same as float 235 }; 236 237 //----------------------------------------------------------------------------- 238 // The "camera", or the point of view 239 class myOGLCamera 240 { 241 public: 242 myOGLCamera(); ~myOGLCamera()243 ~myOGLCamera() {} 244 245 // Initial positions 246 void InitPositions(); 247 // When the size of the window changes 248 void ViewSizeChanged(int newWidth, int newHeight); 249 // The whole transformation matrix 250 const GLfloat* GetFloatMVP(); 251 // The 'To View Space' transformation matrix 252 const GLfloat* GetFloatToVw(); 253 // The camera position GetPosition()254 myVec3 GetPosition() {return m_camPosition;} 255 256 // Simulates a virtual trackball and rotates the 'world' 257 void MouseRotation(int fromX, int fromY, int toX, int toY); 258 double GetTrackballZ(double x, double y, double r); 259 260 // The used matrices 261 double m_dMode[16]; // The model matrix, rotation in this sample 262 double m_dView[16]; // The view matrix 263 double m_dProj[16]; // The projection matrix 264 double m_dMVP[16]; // The whole transform matrix 265 double m_dToVw[16]; // The 'to View' transform matrix 266 // GLFloat versions. GLdouble is available since OGL 4.0, and we use 3.2 267 GLfloat m_fMVP[16]; 268 GLfloat m_fToVw[16]; 269 private: 270 bool m_needMVPUpdate; 271 272 void UpdateMatrices(); 273 274 // Coordinates in model space 275 myVec3 m_centerOfWorld; 276 double m_radiusOfWorld; 277 myVec3 m_camPosition; 278 myVec3 m_camTarget; 279 myVec3 m_camUp; 280 281 // Window size in pixels 282 int m_winWidth; 283 int m_winHeight; 284 285 // Parameters for the projection 286 double m_fov; 287 double m_nearD; 288 double m_farD; 289 }; 290 291 //----------------------------------------------------------------------------- 292 // General manager 293 class myOGLManager 294 { 295 public: 296 myOGLManager(myOGLErrHandler* extErrHnd = NULL); 297 ~myOGLManager(); 298 299 // Constants, prototypes and pointers to OGL functions 300 static bool Init(); 301 // Strings describing the current GL connection 302 const GLubyte* GetGLVersion(); 303 const GLubyte* GetGLVendor(); 304 const GLubyte* GetGLRenderer(); 305 306 // Load data into the GPU 307 void SetShadersAndTriangles(); 308 // Load the texture for the string in the pyramid 309 void SetStringOnPyr(const unsigned char* strImage, int iWidth, int iHeigh); 310 // Load the texture for the immutable string 311 void SetImmutableString(const unsigned char* strImage, int iWidth, int iHeigh); 312 313 // For window size change 314 void SetViewport(int x, int y, int width, int height); 315 316 void Render(); // Total rendering 317 318 // Action events in OpenGL win coordinates (bottom is y=0) 319 void OnMouseButDown(int posX, int posY); 320 void OnMouseRotDragging(int posX, int posY); 321 322 private: 323 // Members 324 myOGLShaders m_TriangShaders; 325 myOGLShaders m_StringShaders; 326 myOGLShaders m_ImmutStringSha; 327 myLight m_Light; 328 myOGLCamera m_Camera; 329 330 myOGLTriangles m_Triangles; 331 myOGLString m_StringOnPyr; 332 myOGLImmutString m_ImmString; 333 334 // For mouse event 335 int m_mousePrevX; 336 int m_mousePrevY; 337 }; 338 339 #endif //OGLSTUFF_H 340 341