OpenGL: OpenGL Matrix Library

来源:互联网 发布:ipv6网络设计 编辑:程序博客网 时间:2024/05/01 17:34

OpenGL Mathematics (GLM) 

http://glm.g-truc.net/

http://people.inf.elte.hu/stbqaai/szGraf/GL/glm-0.9.B.1/

VSML

vsml in action

http://www.lighthouse3d.com/very-simple-libs/vsml/vsml-in-action/

vsml source code

vsml.h

 

/** ---------------------------------------------------------- * /class VSML * * Lighthouse3D * * VSML - Very Simple Matrix Library * * Full documentation at * http://www.lighthouse3d.com/very-simple-libs * * This class aims at easing geometric transforms, camera * placement and projection definition for programmers * working with OpenGL core versions. * * This lib requires: * * GLEW (http://glew.sourceforge.net/) * ---------------------------------------------------------------*/#ifndef __VSML__#define __VSML__ // uncomment this if you want VSML to always update// the matrices for you. Otherwise you'll have to call// a matrixTo* function to get them updated before// calling OpenGL draw commands //#define VSML_ALWAYS_SEND_TO_OPENGL  #include <vector>#include <GL/glew.h> class VSML { public:     /// Enumeration of the matrix types    enum MatrixTypes{            MODELVIEW,            PROJECTION    } ;      /// Singleton pattern    static VSML* gInstance;     /// Call this to get the single instance of VSML    static VSML* getInstance (void);     ~VSML();     /** Call this function to init the library for a particular      * program shader if using uniform variables      *      * /param modelviewLoc location of the uniform variable      * for the modelview matrix      *      * /param projLoc location of the uniform variable      * for the projection matrix    */    void initUniformLocs(GLuint modelviewLoc, GLuint projLoc);     /** Call this function to init the library for a particular      * program shader if using uniform blocks      *      * /param buffer index of the uniform buffer      * /param modelviewOffset offset within the buffer of      * the modelview matrix      * /param projOffset offset within the buffer of      * the projection matrix    */    void initUniformBlock(GLuint buffer, GLuint modelviewOffset, GLuint projOffset);     /** Similar to glTranslate*. Can be applied to both MODELVIEW      * and PROJECTION matrices.      *      * /param aType either MODELVIEW or PROJECTION      * /param x,y,z vector to perform the translation    */    void translate(MatrixTypes aType, float x, float y, float z);     /** Similar to glTranslate*. Applied to MODELVIEW only.      *      * /param x,y,z vector to perform the translation    */    void translate(float x, float y, float z);     /** Similar to glScale*. Can be applied to both MODELVIEW      * and PROJECTION matrices.      *      * /param aType either MODELVIEW or PROJECTION      * /param x,y,z scale factors    */    void scale(MatrixTypes aType, float x, float y, float z);     /** Similar to glScale*. Applied to MODELVIEW only.      *      * /param x,y,z scale factors    */    void scale(float x, float y, float z);     /** Similar to glTotate*. Can be applied to both MODELVIEW      * and PROJECTION matrices.      *      * /param aType either MODELVIEW or PROJECTION      * /param angle rotation angle in degrees      * /param x,y,z rotation axis in degrees    */    void rotate(MatrixTypes aType, float angle, float x, float y, float z);     /** Similar to glRotate*. Applied to MODELVIEW only.      *      * /param angle rotation angle in degrees      * /param x,y,z rotation axis in degrees    */    void rotate(float angle, float x, float y, float z);     /** Similar to glLoadIdentity.      *      * /param aType either MODELVIEW or PROJECTION    */    void loadIdentity(MatrixTypes aType);     /** Similar to glMultMatrix.      *      * /param aType either MODELVIEW or PROJECTION      * /param aMatrix matrix in column major order data, float[16]    */    void multMatrix(MatrixTypes aType, float *aMatrix);     /** Similar to gLoadMatrix.      *      * /param aType either MODELVIEW or PROJECTION      * /param aMatrix matrix in column major order data, float[16]    */     void loadMatrix(MatrixTypes aType, float *aMatrix);     /** Similar to glPushMatrix      *      * /param aType either MODELVIEW or PROJECTION    */    void pushMatrix(MatrixTypes aType);     /** Similar to glPopMatrix      *      * /param aType either MODELVIEW or PROJECTION    */    void popMatrix(MatrixTypes aType);     /** Similar to gluLookAt      *      * /param xPos, yPos, zPos camera position      * /param xLook, yLook, zLook point to aim the camera at      * /param xUp, yUp, zUp camera's up vector    */    void lookAt(float xPos, float yPos, float zPos,                float xLook, float yLook, float zLook,                float xUp, float yUp, float zUp);     /** Similar to gluPerspective      *      * /param fov vertical field of view      * /param ratio aspect ratio of the viewport or window      * /param nearp,farp distance to the near and far planes    */    void perspective(float fov, float ratio, float nearp, float farp);     /** Similar to glOrtho and gluOrtho2D (just leave the last two params blank).      *      * /param left,right coordinates for the left and right vertical clipping planes      * /param bottom,top coordinates for the bottom and top horizontal clipping planes      * /param nearp,farp distance to the near and far planes    */    void ortho(float left, float right, float bottom, float top, float nearp=-1.0f, float farp=1.0f);     /** Similar to glFrustum      *      * /param left,right coordinates for the left and right vertical clipping planes      * /param bottom,top coordinates for the bottom and top horizontal clipping planes      * /param nearp,farp distance to the near and far planes    */    void frustum(float left, float right, float bottom, float top, float nearp, float farp);     /** Similar to glGet      *      * /param aType either MODELVIEW or PROJECTION      * /returns pointer to the matrix (float[16])    */    float *get(MatrixTypes aType);     /** Updates the uniform buffer data      *      * /param aType  either MODELVIEW or PROJECTION    */    void matrixToBuffer(MatrixTypes aType);     /** Updates the uniform variables      *      * /param aType  either MODELVIEW or PROJECTION    */    void matrixToUniform(MatrixTypes aType);     /** Updates either the buffer or the uniform variables      * based on which init* function was called last      *      * /param aType  either MODELVIEW or PROJECTION    */    void matrixToGL(MatrixTypes aType); protected:     VSML();     /// Has an init* function been called?    bool mInit;     /// Using uniform blocks?    bool mBlocks;     ///brief Matrix stacks for modelview and projection matrices    std::vector<float *> mMatrixStack[2];     /// The storage for the two matrices    float mMatrix[2][16];     /// Storage for the uniform locations    GLuint mUniformLoc[2];     /// Storage for the buffer index    GLuint mBuffer;     /// Storage for the offsets within the buffer    GLuint mOffset[2];     /** Set a float* to an identity matrix      *      * /param size the order of the matrix    */    void setIdentityMatrix( float *mat, int size=4);     /** vector cross product      *      * res = a x b    */    void crossProduct( float *a, float *b, float *res);     /// normalize a vec3    void normalize(float *a); }; #endif


vsml.cpp

/* -------------------------------------------------- Lighthouse3D VSML - Very Simple Matrix Library http://www.lighthouse3d.com/very-simple-libs ----------------------------------------------------*/ #include "vsml.h"#include <math.h> // This var keeps track of the single instance of VSMLVSML* VSML::gInstance = 0; #define M_PI       3.14159265358979323846f static inline floatDegToRad(float degrees){    return (float)(degrees * (M_PI / 180.0f));}; // Singleton implementation// use this function to get the instance of VSMLVSML*VSML::getInstance (void) {     if (0 != gInstance)        return gInstance;    else        gInstance = new VSML();     return gInstance;} // VSML constructorVSML::VSML():        mInit(false),        mBlocks(false){ } // VSML destructorVSML::~VSML(){} // send the buffer data and offsets to VSMLvoidVSML::initUniformBlock(GLuint buffer, GLuint modelviewOffset, GLuint projOffset){    mInit = true;    mBlocks = true;    mBuffer = buffer;    mOffset[MODELVIEW] = modelviewOffset;    mOffset[PROJECTION] = projOffset;} // send the uniform locations to VSMLvoidVSML::initUniformLocs(GLuint modelviewLoc, GLuint projLoc){    mInit = true;    mBlocks = false;    mUniformLoc[MODELVIEW] = modelviewLoc;    mUniformLoc[PROJECTION] = projLoc;} // glPushMatrix implementationvoidVSML::pushMatrix(MatrixTypes aType) {     float *aux = (float *)malloc(sizeof(float) * 16);    memcpy(aux, mMatrix[aType], sizeof(float) * 16);    mMatrixStack[aType].push_back(aux);} // glPopMatrix implementationvoidVSML::popMatrix(MatrixTypes aType) {     float *m = mMatrixStack[aType][mMatrixStack[aType].size()-1];    memcpy(mMatrix[aType], m, sizeof(float) * 16);    mMatrixStack[aType].pop_back();    free(m); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(aType);#endif } // glLoadIdentity implementationvoidVSML::loadIdentity(MatrixTypes aType){    setIdentityMatrix(mMatrix[aType]); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(aType);#endif} // glMultMatrix implementationvoidVSML::multMatrix(MatrixTypes aType, float *aMatrix){     float *a, *b, res[16];    a = mMatrix[aType];    b = aMatrix;     for (int i = 0; i < 4; ++i) {        for (int j = 0; j < 4; ++j) {            res[j*4 + i] = 0.0f;            for (int k = 0; k < 4; ++k) {                res[j*4 + i] += a[k*4 + i] * b[j*4 + k];            }        }    }    memcpy(mMatrix[aType], res, 16 * sizeof(float)); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(aType);#endif} // glLoadMatrix implementationvoidVSML::loadMatrix(MatrixTypes aType, float *aMatrix){    memcpy(mMatrix[aType], aMatrix, 16 * sizeof(float)); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(aType);#endif} // glTranslate implementation with matrix selectionvoidVSML::translate(MatrixTypes aType, float x, float y, float z){    float mat[16];     setIdentityMatrix(mat);    mat[12] = x;    mat[13] = y;    mat[14] = z;     multMatrix(aType,mat); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(aType);#endif} // glTranslate on the MODELVIEW matrixvoidVSML::translate(float x, float y, float z){    translate(MODELVIEW, x,y,z);} // glScale implementation with matrix selectionvoidVSML::scale(MatrixTypes aType, float x, float y, float z){    float mat[16];     setIdentityMatrix(mat,4);    mat[0] = x;    mat[5] = y;    mat[10] = z;     multMatrix(aType,mat); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(aType);#endif} // glScale on the MODELVIEW matrixvoidVSML::scale(float x, float y, float z){    scale(MODELVIEW, x, y, z);} // glRotate implementation with matrix selectionvoidVSML::rotate(MatrixTypes aType, float angle, float x, float y, float z){    float mat[16];     float radAngle = DegToRad(angle);    float co = cos(radAngle);    float si = sin(radAngle);    float x2 = x*x;    float y2 = y*y;    float z2 = z*z;     mat[0] = x2 + (y2 + z2) * co;    mat[4] = x * y * (1 - co) - z * si;    mat[8] = x * z * (1 - co) + y * si;    mat[12]= 0.0f;     mat[1] = x * y * (1 - co) + z * si;    mat[5] = y2 + (x2 + z2) * co;    mat[9] = y * z * (1 - co) - x * si;    mat[13]= 0.0f;     mat[2] = x * z * (1 - co) - y * si;    mat[6] = y * z * (1 - co) + x * si;    mat[10]= z2 + (x2 + y2) * co;    mat[14]= 0.0f;     mat[3] = 0.0f;    mat[7] = 0.0f;    mat[11]= 0.0f;    mat[15]= 1.0f;     multMatrix(aType,mat); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(aType);#endif} // glRotate implementation in the MODELVIEW matrixvoidVSML::rotate(float angle, float x, float y, float z){    rotate(MODELVIEW,angle,x,y,z);} // gluLookAt implementationvoidVSML::lookAt(float xPos, float yPos, float zPos,                    float xLook, float yLook, float zLook,                    float xUp, float yUp, float zUp){    float dir[3], right[3], up[3];     up[0] = xUp;    up[1] = yUp;    up[2] = zUp;     dir[0] =  (xLook - xPos);    dir[1] =  (yLook - yPos);    dir[2] =  (zLook - zPos);    normalize(dir);     crossProduct(dir,up,right);    normalize(right);     crossProduct(right,dir,up);    normalize(up);     float m1[16],m2[16];     m1[0]  = right[0];    m1[4]  = right[1];    m1[8]  = right[2];    m1[12] = 0.0f;     m1[1]  = up[0];    m1[5]  = up[1];    m1[9]  = up[2];    m1[13] = 0.0f;     m1[2]  = -dir[0];    m1[6]  = -dir[1];    m1[10] = -dir[2];    m1[14] =  0.0f;     m1[3]  = 0.0f;    m1[7]  = 0.0f;    m1[11] = 0.0f;    m1[15] = 1.0f;     setIdentityMatrix(m2,4);    m2[12] = -xPos;    m2[13] = -yPos;    m2[14] = -zPos;     multMatrix(MODELVIEW, m1);    multMatrix(MODELVIEW, m2); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(MODELVIEW);#endif} // gluPerspective implementationvoidVSML::perspective(float fov, float ratio, float nearp, float farp){    float projMatrix[16];     float f = 1.0f / tan (fov * (M_PI / 360.0f));     setIdentityMatrix(projMatrix,4);     projMatrix[0] = f / ratio;    projMatrix[1 * 4 + 1] = f;    projMatrix[2 * 4 + 2] = (farp + nearp) / (nearp - farp);    projMatrix[3 * 4 + 2] = (2.0f * farp * nearp) / (nearp - farp);    projMatrix[2 * 4 + 3] = -1.0f;    projMatrix[3 * 4 + 3] = 0.0f;     multMatrix(PROJECTION, projMatrix); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(PROJECTION);#endif} // glOrtho implementationvoidVSML::ortho(float left, float right, float bottom, float top, float nearp, float farp){    float m[16];     setIdentityMatrix(m,4);     m[0 * 4 + 0] = 2 / (right - left);    m[1 * 4 + 1] = 2 / (top - bottom);    m[2 * 4 + 2] = -2 / (farp - nearp);    m[3 * 4 + 0] = -(right + left) / (right - left);    m[3 * 4 + 1] = -(top + bottom) / (top - bottom);    m[3 * 4 + 2] = -(farp + nearp) / (farp - nearp);     multMatrix(PROJECTION, m); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(PROJECTION);#endif} // glFrustum implementationvoidVSML::frustum(float left, float right, float bottom, float top, float nearp, float farp){    float m[16];     setIdentityMatrix(m,4);     m[0 * 4 + 0] = 2 * nearp / (right-left);    m[1 * 4 + 1] = 2 * nearp / (top - bottom);    m[2 * 4 + 0] = (right + left) / (right - left);    m[2 * 4 + 1] = (top + bottom) / (top - bottom);    m[2 * 4 + 2] = - (farp + nearp) / (farp - nearp);    m[2 * 4 + 3] = -1.0f;    m[3 * 4 + 2] = - 2 * farp * nearp / (farp-nearp);    m[3 * 4 + 3] = 0.0f;     multMatrix(PROJECTION, m); #ifdef VSML_ALWAYS_SEND_TO_OPENGL    matrixToGL(PROJECTION);#endif} // returns a pointer to the requested matrixfloat *VSML::get(MatrixTypes aType){    return mMatrix[aType];} /* -----------------------------------------------------             SEND MATRICES TO OPENGL------------------------------------------------------*/ // to be used with uniform blocksvoidVSML::matrixToBuffer(MatrixTypes aType){    if (mInit && mBlocks) {        glBindBuffer(GL_UNIFORM_BUFFER,mBuffer);        glBufferSubData(GL_UNIFORM_BUFFER, mOffset[aType], 16 * sizeof(float), mMatrix[aType]);        glBindBuffer(GL_UNIFORM_BUFFER,0);     }} // to be used with uniform variablesvoidVSML::matrixToUniform(MatrixTypes aType){    if (mInit && !mBlocks) {         glUniformMatrix4fv(mUniformLoc[aType], 1, false, mMatrix[aType]);    }} // universalvoidVSML::matrixToGL(MatrixTypes aType){    if (mInit) {         if (mBlocks) {            glBindBuffer(GL_UNIFORM_BUFFER,mBuffer);            glBufferSubData(GL_UNIFORM_BUFFER, mOffset[aType], 16 * sizeof(float), mMatrix[aType]);            glBindBuffer(GL_UNIFORM_BUFFER,0);        }        else {            glUniformMatrix4fv(mUniformLoc[aType], 1, false, mMatrix[aType]);        }     }} // -----------------------------------------------------//                      AUX functions// ----------------------------------------------------- // sets the square matrix mat to the identity matrix,// size refers to the number of rows (or columns)voidVSML::setIdentityMatrix( float *mat, int size) {     // fill matrix with 0s    for (int i = 0; i < size * size; ++i)            mat[i] = 0.0f;     // fill diagonal with 1s    for (int i = 0; i < size; ++i)        mat[i + i * size] = 1.0f;} // res = a cross b;voidVSML::crossProduct( float *a, float *b, float *res) {     res[0] = a[1] * b[2]  -  b[1] * a[2];    res[1] = a[2] * b[0]  -  b[2] * a[0];    res[2] = a[0] * b[1]  -  b[0] * a[1];} // Normalize a vec3voidVSML::normalize(float *a) {     float mag = sqrt(a[0] * a[0]  +  a[1] * a[1]  +  a[2] * a[2]);     a[0] /= mag;    a[1] /= mag;    a[2] /= mag;}


http://blog.csdn.net/ryfdizuo/article/details/6419793

0 0