341 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			341 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        oglstuff.h
 | 
						|
// Purpose:     OpenGL manager for pyramid sample
 | 
						|
// Author:      Manuel Martin
 | 
						|
// Created:     2015/01/31
 | 
						|
// Copyright:   (c) 2015 Manuel Martin
 | 
						|
// Licence:     wxWindows licence
 | 
						|
/////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#ifndef OGLSTUFF_H
 | 
						|
#define OGLSTUFF_H
 | 
						|
 | 
						|
#include <string>
 | 
						|
#include <vector>
 | 
						|
 | 
						|
#include "mathstuff.h"
 | 
						|
 | 
						|
// This file allows access to OpenGL functions used in this sample.
 | 
						|
#include "oglpfuncs.h"
 | 
						|
 | 
						|
/*
 | 
						|
  ************  NOTES  *******************************************************
 | 
						|
  This is not an OGL tutorial, I mean, this is just a sample of how OGL stuff
 | 
						|
  may be arranged. I tried to keep it simple.
 | 
						|
  It's likely that the novice to OGL reads this sample, so here are some brief
 | 
						|
  notes:
 | 
						|
  * Starting with OpenGL >= 2.0 the user defines some special programs that are
 | 
						|
    going to be executed in the GPU, not in the CPU. These programs are called
 | 
						|
    "Shaders". Since OGL >= 3.2, and if a "Core Profile" context is set, the use
 | 
						|
    of shaders is the only way to make an OGL application.
 | 
						|
  * A program consists (at least) of a 'vertex shader' who operates on the
 | 
						|
    vertices that define the primitive (a triangle, a line, etc) and a 'fragment
 | 
						|
    shader' which deals with fragments (points) interpolated from the previously
 | 
						|
    processed vertices in the vertex shader.
 | 
						|
  * Shaders must be compiled and linked, both operations are done on the GPU.
 | 
						|
  * Shaders are written in the GLSL language, that looks like C, but it isn't C.
 | 
						|
  * Data (vertices, textures) are stored in GPU memory, so they don't need to be
 | 
						|
    loaded each time the scene must be redrawn.
 | 
						|
  * Rotations and translations are matrix operations that the GPU may do in the
 | 
						|
    [vertex]shaders. The user must define the needed matrices.
 | 
						|
  * A vertex shader defines special vars ("attributes") used for reading the
 | 
						|
    data from the GPU buffers. Other special vars ("uniforms") are used for
 | 
						|
    values that don't change with each vertex (i.e. the matrices).
 | 
						|
  * The relationship between a data buffer and the input attributes in a vertex
 | 
						|
    shader can be saved in a "Vertex Array Object" (VAO).
 | 
						|
 | 
						|
  I use several classes for typical OGL jobs: Shaders, Data, Camera.
 | 
						|
  Because different GPU cards may behave on their own, I also use very often
 | 
						|
  an error-helper. It will inform of the point where something went wrong.
 | 
						|
 | 
						|
  I decided to keep apart all of this from wxWidgets. You won't find anything
 | 
						|
  related to wxWidgets in the oglstuff[.h][.cpp] files.
 | 
						|
  That's why I use std::vector and std:string instead of those provided by wx.
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
// Define our own GL errors
 | 
						|
enum
 | 
						|
{
 | 
						|
    myoglERR_CLEAR = 0,
 | 
						|
    myoglERR_JUSTLOG,
 | 
						|
 | 
						|
    myoglERR_SHADERCREATE,
 | 
						|
    myoglERR_SHADERCOMPILE,
 | 
						|
    myoglERR_SHADERLINK,
 | 
						|
    myoglERR_SHADERLOCATION,
 | 
						|
 | 
						|
    myoglERR_BUFFER,
 | 
						|
    myoglERR_TEXTIMAGE,
 | 
						|
 | 
						|
    myoglERR_DRAWING_TRI,
 | 
						|
    myoglERR_DRAWING_STR
 | 
						|
};
 | 
						|
 | 
						|
// Used to handle GL errors in other part of the app.
 | 
						|
typedef void myOGLErrHandler(int err, int glerr, const GLchar* glMsg);
 | 
						|
 | 
						|
// For shader attributes
 | 
						|
struct shaVars
 | 
						|
{
 | 
						|
    GLuint loc; //The attribute "location", some kind of index in the shader
 | 
						|
    std::string name; //The name of the attribute
 | 
						|
};
 | 
						|
 | 
						|
typedef std::vector<shaVars> shaVars_v;
 | 
						|
 | 
						|
// For shader code
 | 
						|
struct shaShas
 | 
						|
{
 | 
						|
    GLuint shaId;
 | 
						|
    GLenum typeSha; //The type of shader
 | 
						|
    const GLchar* scode; //The NULL terminated GLSL code
 | 
						|
};
 | 
						|
 | 
						|
typedef std::vector<shaShas> shaShas_v;
 | 
						|
 | 
						|
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
// This object builds a GPU program by joining several shaders.
 | 
						|
class myOGLShaders
 | 
						|
{
 | 
						|
public:
 | 
						|
    myOGLShaders();
 | 
						|
    ~myOGLShaders();
 | 
						|
 | 
						|
    void Init();
 | 
						|
    bool Use();
 | 
						|
    void StopUse();
 | 
						|
    void CleanUp();
 | 
						|
 | 
						|
    void AddCode(const GLchar* shaString, GLenum shaType);
 | 
						|
    void AddAttrib(const std::string& name);
 | 
						|
    void AddUnif(const std::string& name);
 | 
						|
    GLuint GetAttribLoc(const std::string& name);
 | 
						|
    GLuint GetUnifLoc(const std::string& name);
 | 
						|
    // Disable generic vertex attribute array
 | 
						|
    void DisableGenericVAA();
 | 
						|
 | 
						|
private:
 | 
						|
    void SetAttribLocations();
 | 
						|
    bool AskUnifLocations();
 | 
						|
    bool Compile(GLuint shaId);
 | 
						|
    bool LinkProg(GLuint proId);
 | 
						|
 | 
						|
    shaVars_v m_shaAttrib; // 'attributes' names and locations
 | 
						|
    shaVars_v m_shaUnif; // 'uniforms' names and locations
 | 
						|
    shaShas_v m_shaCode; // shaders code and their types
 | 
						|
    GLuint m_proId; // program Id
 | 
						|
 | 
						|
    bool m_SHAinitializated;
 | 
						|
};
 | 
						|
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
// A "point light"
 | 
						|
class myLight
 | 
						|
{
 | 
						|
public:
 | 
						|
    myLight() {}
 | 
						|
    ~myLight() {}
 | 
						|
 | 
						|
    void Set(const myVec3& position, GLfloat intensity,
 | 
						|
             GLfloat R, GLfloat G, GLfloat B);
 | 
						|
    // Return position and intensity
 | 
						|
    const GLfloat* GetFLightPos() const
 | 
						|
        { return m_PosAndIntensisty; }
 | 
						|
    // Return colour
 | 
						|
    const GLfloat* GetFLightColour() const
 | 
						|
        { return m_Colour; }
 | 
						|
 | 
						|
private:
 | 
						|
    // Light position and intensity
 | 
						|
    GLfloat m_PosAndIntensisty[4];
 | 
						|
    // Light colour
 | 
						|
    GLfloat m_Colour[3];
 | 
						|
};
 | 
						|
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
// An object for triangles
 | 
						|
class myOGLTriangles
 | 
						|
{
 | 
						|
public:
 | 
						|
    myOGLTriangles();
 | 
						|
    ~myOGLTriangles();
 | 
						|
 | 
						|
    // Clean up
 | 
						|
    void Clear();
 | 
						|
    // Load data into the GPU
 | 
						|
    void SetBuffers(myOGLShaders* theShader, GLsizei nuPoints, GLsizei nuTriangs,
 | 
						|
                    const GLfloat* vert, const GLfloat* colo,
 | 
						|
                    const GLfloat* norm, const GLushort* indices);
 | 
						|
 | 
						|
    //Draw the triangles
 | 
						|
    void Draw(const GLfloat* unifMvp, const GLfloat* unifToVw,
 | 
						|
              const myLight* theLight);
 | 
						|
 | 
						|
private:
 | 
						|
    GLsizei m_nuTriangs;
 | 
						|
    // Buffers ids
 | 
						|
    GLuint m_bufVertId;
 | 
						|
    GLuint m_bufColNorId;
 | 
						|
    GLuint m_bufIndexId;
 | 
						|
    // Vertex Arrays Object
 | 
						|
    GLuint m_triangVAO;
 | 
						|
    // GPU Program used to draw the triangles
 | 
						|
    myOGLShaders* m_triangShaders;
 | 
						|
};
 | 
						|
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
// An object for strings
 | 
						|
class myOGLString
 | 
						|
{
 | 
						|
public:
 | 
						|
    myOGLString();
 | 
						|
    ~myOGLString();
 | 
						|
 | 
						|
    // Clean up
 | 
						|
    void Clear();
 | 
						|
    // Load data into the GPU
 | 
						|
    void SetStringWithVerts(myOGLShaders* theShader,
 | 
						|
                             const unsigned char* tImage, int tWidth, int tHeigh,
 | 
						|
                             const GLfloat* vert, const GLfloat* norm);
 | 
						|
    // Draw the string
 | 
						|
    void Draw(const GLfloat* unifMvp, const GLfloat* unifToVw,
 | 
						|
              const myLight* theLight);
 | 
						|
 | 
						|
 | 
						|
private:
 | 
						|
    GLuint m_bufPosId;    // Buffer id
 | 
						|
    GLuint m_stringVAO;   // Vertex Arrays Object
 | 
						|
    GLuint m_textureUnit; // The context unit
 | 
						|
    GLuint m_textureId;   // Texture name
 | 
						|
    // GPU Program used to draw the texture
 | 
						|
    myOGLShaders* m_stringShaders;
 | 
						|
};
 | 
						|
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
// An object for the immutable string
 | 
						|
class myOGLImmutString : public myOGLString
 | 
						|
{
 | 
						|
public:
 | 
						|
    myOGLImmutString(){}
 | 
						|
    ~myOGLImmutString(){}
 | 
						|
 | 
						|
    // Load data into the GPU
 | 
						|
    void SetImmutString(myOGLShaders* theShader,
 | 
						|
                        const unsigned char* tImage, int tWidth, int tHeigh);
 | 
						|
    // Update orthogonal projection matrix
 | 
						|
    void SetOrtho(int winWidth, int winHeight);
 | 
						|
    // The transformation matrix
 | 
						|
    const GLfloat* GetFloatMVP() { return m_fOrtho; }
 | 
						|
 | 
						|
private:
 | 
						|
    double m_dOrtho[16]; // The orthogonal projection matrix
 | 
						|
    GLfloat m_fOrtho[16]; // Same as float
 | 
						|
};
 | 
						|
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
// The "camera", or the point of view
 | 
						|
class myOGLCamera
 | 
						|
{
 | 
						|
public:
 | 
						|
    myOGLCamera();
 | 
						|
    ~myOGLCamera() {}
 | 
						|
 | 
						|
    // Initial positions
 | 
						|
    void InitPositions();
 | 
						|
    // When the size of the window changes
 | 
						|
    void ViewSizeChanged(int newWidth, int newHeight);
 | 
						|
    // The whole transformation matrix
 | 
						|
    const GLfloat* GetFloatMVP();
 | 
						|
    // The 'To View Space' transformation matrix
 | 
						|
    const GLfloat* GetFloatToVw();
 | 
						|
    // The camera position
 | 
						|
    myVec3 GetPosition() {return m_camPosition;}
 | 
						|
 | 
						|
    // Simulates a virtual trackball and rotates the 'world'
 | 
						|
    void MouseRotation(int fromX, int fromY, int toX, int toY);
 | 
						|
    double GetTrackballZ(double x, double y, double r);
 | 
						|
 | 
						|
    // The used matrices
 | 
						|
    double m_dMode[16]; // The model matrix, rotation in this sample
 | 
						|
    double m_dView[16]; // The view matrix
 | 
						|
    double m_dProj[16]; // The projection matrix
 | 
						|
    double m_dMVP[16];  // The whole transform matrix
 | 
						|
    double m_dToVw[16]; // The 'to View' transform matrix
 | 
						|
    // GLFloat versions. GLdouble is available since OGL 4.0, and we use 3.2
 | 
						|
    GLfloat m_fMVP[16];
 | 
						|
    GLfloat m_fToVw[16];
 | 
						|
private:
 | 
						|
    bool m_needMVPUpdate;
 | 
						|
 | 
						|
    void UpdateMatrices();
 | 
						|
 | 
						|
    // Coordinates in model space
 | 
						|
    myVec3 m_centerOfWorld;
 | 
						|
    double m_radiusOfWorld;
 | 
						|
    myVec3 m_camPosition;
 | 
						|
    myVec3 m_camTarget;
 | 
						|
    myVec3 m_camUp;
 | 
						|
 | 
						|
    // Window size in pixels
 | 
						|
    int m_winWidth;
 | 
						|
    int m_winHeight;
 | 
						|
 | 
						|
    // Parameters for the projection
 | 
						|
    double m_fov;
 | 
						|
    double m_nearD;
 | 
						|
    double m_farD;
 | 
						|
};
 | 
						|
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
// General manager
 | 
						|
class myOGLManager
 | 
						|
{
 | 
						|
public:
 | 
						|
    myOGLManager(myOGLErrHandler* extErrHnd = NULL);
 | 
						|
    ~myOGLManager();
 | 
						|
 | 
						|
    // Constants, prototypes and pointers to OGL functions
 | 
						|
    static bool Init();
 | 
						|
    // Strings describing the current GL connection
 | 
						|
    const GLubyte* GetGLVersion();
 | 
						|
    const GLubyte* GetGLVendor();
 | 
						|
    const GLubyte* GetGLRenderer();
 | 
						|
 | 
						|
    // Load data into the GPU
 | 
						|
    void SetShadersAndTriangles();
 | 
						|
    // Load the texture for the string in the pyramid
 | 
						|
    void SetStringOnPyr(const unsigned char* strImage, int iWidth, int iHeigh);
 | 
						|
    // Load the texture for the immutable string
 | 
						|
    void SetImmutableString(const unsigned char* strImage, int iWidth, int iHeigh);
 | 
						|
 | 
						|
    // For window size change
 | 
						|
    void SetViewport(int x, int y, int width, int height);
 | 
						|
 | 
						|
    void Render(); // Total rendering
 | 
						|
 | 
						|
    // Action events in OpenGL win coordinates (bottom is y=0)
 | 
						|
    void OnMouseButDown(int posX, int posY);
 | 
						|
    void OnMouseRotDragging(int posX, int posY);
 | 
						|
 | 
						|
private:
 | 
						|
    // Members
 | 
						|
    myOGLShaders   m_TriangShaders;
 | 
						|
    myOGLShaders   m_StringShaders;
 | 
						|
    myOGLShaders   m_ImmutStringSha;
 | 
						|
    myLight        m_Light;
 | 
						|
    myOGLCamera    m_Camera;
 | 
						|
 | 
						|
    myOGLTriangles    m_Triangles;
 | 
						|
    myOGLString       m_StringOnPyr;
 | 
						|
    myOGLImmutString  m_ImmString;
 | 
						|
 | 
						|
    // For mouse event
 | 
						|
    int m_mousePrevX;
 | 
						|
    int m_mousePrevY;
 | 
						|
};
 | 
						|
 | 
						|
#endif //OGLSTUFF_H
 | 
						|
 |