glc_context.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021  *****************************************************************************/
00023 
00024 #include "glc_context.h"
00025 #include "glc_contextmanager.h"
00026 #include "shading/glc_shader.h"
00027 
00028 #include "glc_state.h"
00029 
00030 GLC_Context* GLC_Context::m_pCurrentContext= NULL;
00031 
00032 GLC_Context::GLC_Context(const QGLFormat& format)
00033 : QGLContext(format)
00034 , m_CurrentMatrixMode()
00035 , m_MatrixStackHash()
00036 , m_ContextSharedData()
00037 , m_UniformShaderData()
00038 , m_LightingIsEnable()
00039 {
00040         qDebug() << "GLC_Context::GLC_Context";
00041         GLC_ContextManager::instance()->addContext(this);
00042         init();
00043 }
00044 
00045 GLC_Context::~GLC_Context()
00046 {
00047         qDebug() << "GLC_Context::~GLC_Context()";
00048         GLC_ContextManager::instance()->remove(this);
00049         QHash<GLenum, QStack<GLC_Matrix4x4>* >::iterator iStack= m_MatrixStackHash.begin();
00050         while (iStack != m_MatrixStackHash.end())
00051         {
00052                 delete iStack.value();
00053                 ++iStack;
00054         }
00055 }
00056 
00057 
00059 // Get Functions
00061 
00062 GLC_Context* GLC_Context::current()
00063 {
00064         return m_pCurrentContext;
00065 }
00066 
00068 // OpenGL Functions
00070 void GLC_Context::glcMatrixMode(GLenum mode)
00071 {
00072         Q_ASSERT(QGLContext::isValid());
00073         Q_ASSERT((mode == GL_MODELVIEW) || (mode == GL_PROJECTION));
00074 
00075         m_CurrentMatrixMode= mode;
00076 #ifdef GLC_OPENGL_ES_2
00077 
00078 #else
00079         glMatrixMode(m_CurrentMatrixMode);
00080 #endif
00081 
00082 }
00083 
00084 void GLC_Context::glcLoadIdentity()
00085 {
00086         Q_ASSERT(QGLContext::isValid());
00087         m_MatrixStackHash.value(m_CurrentMatrixMode)->top().setToIdentity();
00088 
00089 #ifdef GLC_OPENGL_ES_2
00090         m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
00091 #else
00092         if (GLC_Shader::hasActiveShader())
00093         {
00094                 m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
00095         }
00096         glLoadIdentity();
00097 #endif
00098 
00099 }
00100 
00101 void GLC_Context::glcPushMatrix()
00102 {
00103         Q_ASSERT(QGLContext::isValid());
00104         m_MatrixStackHash.value(m_CurrentMatrixMode)->push(m_MatrixStackHash.value(m_CurrentMatrixMode)->top());
00105 
00106 #ifndef GLC_OPENGL_ES_2
00107         glPushMatrix();
00108 #endif
00109 
00110 }
00111 
00112 void GLC_Context::glcPopMatrix()
00113 {
00114         Q_ASSERT(QGLContext::isValid());
00115         m_MatrixStackHash.value(m_CurrentMatrixMode)->pop();
00116 
00117 #ifdef GLC_OPENGL_ES_2
00118         this->glcLoadMatrix(m_MatrixStackHash.value(m_CurrentMatrixMode)->top());
00119 #else
00120         if (GLC_Shader::hasActiveShader())
00121         {
00122                 this->glcLoadMatrix(m_MatrixStackHash.value(m_CurrentMatrixMode)->top());
00123         }
00124         glPopMatrix();
00125 #endif
00126 
00127 }
00128 
00129 
00130 void GLC_Context::glcLoadMatrix(const GLC_Matrix4x4& matrix)
00131 {
00132         m_MatrixStackHash.value(m_CurrentMatrixMode)->top()= matrix;
00133 
00134 #ifdef GLC_OPENGL_ES_2
00135         m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
00136 #else
00137         if (GLC_Shader::hasActiveShader())
00138         {
00139                 m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
00140         }
00141         ::glLoadMatrixd(matrix.getData());
00142 #endif
00143 
00144 }
00145 
00146 void GLC_Context::glcMultMatrix(const GLC_Matrix4x4& matrix)
00147 {
00148         const GLC_Matrix4x4 current= m_MatrixStackHash.value(m_CurrentMatrixMode)->top();
00149         m_MatrixStackHash.value(m_CurrentMatrixMode)->top()= m_MatrixStackHash.value(m_CurrentMatrixMode)->top() * matrix;
00150 #ifdef GLC_OPENGL_ES_2
00151         m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
00152 #else
00153         if (GLC_Shader::hasActiveShader())
00154         {
00155                 m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
00156         }
00157         ::glMultMatrixd(matrix.getData());
00158 #endif
00159 
00160 }
00161 
00162 void GLC_Context::glcScaled(double x, double y, double z)
00163 {
00164         GLC_Matrix4x4 scale;
00165         scale.setMatScaling(x, y, z);
00166         glcMultMatrix(scale);
00167 }
00168 
00169 void GLC_Context::glcOrtho(double left, double right, double bottom, double top, double nearVal, double farVal)
00170 {
00171         GLC_Matrix4x4 orthoMatrix;
00172         double* m= orthoMatrix.setData();
00173 
00174         const double tx= - (right + left) / (right - left);
00175         const double ty= - (top + bottom) / (top - bottom);
00176         const double tz= - (farVal + nearVal) / (farVal - nearVal);
00177         m[0]= 2.0 / (right - left);
00178         m[5]= 2.0 / (top - bottom);
00179         m[10]= -2.0 / (farVal - nearVal);
00180         m[12]= tx;
00181         m[13]= ty;
00182         m[14]= tz;
00183 
00184         glcMultMatrix(orthoMatrix);
00185 }
00186 
00187 void GLC_Context::glcFrustum(double left, double right, double bottom, double top, double nearVal, double farVal)
00188 {
00189         GLC_Matrix4x4 perspMatrix;
00190         double* m= perspMatrix.setData();
00191 
00192         const double a= (right + left) / (right - left);
00193         const double b= (top + bottom) / (top - bottom);
00194         const double c= - (farVal + nearVal) / (farVal - nearVal);
00195         const double d= - (2.0 * farVal * nearVal) / (farVal - nearVal);
00196 
00197         m[0]= (2.0 * nearVal) / (right - left);
00198         m[5]= (2.0 * nearVal) / (top - bottom);
00199         m[8]= a;
00200         m[9]= b;
00201         m[10]= c;
00202         m[11]= -1.0;
00203         m[14]= d;
00204         m[15]= 0.0;
00205 
00206         glcMultMatrix(perspMatrix);
00207 }
00208 
00209 void GLC_Context::glcEnableLighting(bool enable)
00210 {
00211         if (enable != m_LightingIsEnable.top())
00212         {
00213                 m_LightingIsEnable.top()= enable;
00214 
00215 #ifdef GLC_OPENGL_ES_2
00216 
00217                 m_UniformShaderData.setLightingState(m_LightingIsEnable);
00218 #else
00219                 if (GLC_Shader::hasActiveShader())
00220                 {
00221                         m_UniformShaderData.setLightingState(m_LightingIsEnable.top());
00222                 }
00223                 if (m_LightingIsEnable.top()) ::glEnable(GL_LIGHTING);
00224                 else ::glDisable(GL_LIGHTING);
00225 #endif
00226 
00227         }
00228 }
00229 
00231 // Set Functions
00233 
00234 void GLC_Context::makeCurrent()
00235 {
00236         QGLContext::makeCurrent();
00237         if (!GLC_State::isValid())
00238         {
00239                 GLC_State::init();
00240         }
00241         GLC_ContextManager::instance()->setCurrent(this);
00242         m_pCurrentContext= this;
00243 }
00244 
00245 void GLC_Context::doneCurrent()
00246 {
00247         QGLContext::doneCurrent();
00248         GLC_ContextManager::instance()->setCurrent(NULL);
00249         m_pCurrentContext= NULL;
00250 }
00251 
00252 bool GLC_Context::chooseContext(const QGLContext* shareContext)
00253 {
00254         qDebug() << "GLC_Context::chooseContext";
00255         const bool success= QGLContext::chooseContext(shareContext);
00256         if (!success)
00257         {
00258                 qDebug() << "enable to create context " << this;
00259         }
00260         else if (NULL != shareContext)
00261         {
00262                 GLC_Context* pContext= const_cast<GLC_Context*>(dynamic_cast<const GLC_Context*>(shareContext));
00263                 Q_ASSERT(NULL != pContext);
00264                 m_ContextSharedData= pContext->m_ContextSharedData;
00265         }
00266         else
00267         {
00268                 m_ContextSharedData= QSharedPointer<GLC_ContextSharedData>(new GLC_ContextSharedData());
00269         }
00270 
00271         return success;
00272 }
00273 
00275 // Private services Functions
00277 void GLC_Context::init()
00278 {
00279         QStack<GLC_Matrix4x4>* pStack1= new QStack<GLC_Matrix4x4>();
00280         pStack1->push(GLC_Matrix4x4());
00281         m_MatrixStackHash.insert(GL_MODELVIEW, pStack1);
00282 
00283         QStack<GLC_Matrix4x4>* pStack2= new QStack<GLC_Matrix4x4>();
00284         pStack2->push(GLC_Matrix4x4());
00285         m_MatrixStackHash.insert(GL_PROJECTION, pStack2);
00286 
00287         m_LightingIsEnable.push(false);
00288 }
00289 

SourceForge.net Logo

©2005-2011 Laurent Ribon