Logo Search packages:      
Sourcecode: blender version File versions

RAS_OpenGLRasterizer.cpp

/**
 * $Id: RAS_OpenGLRasterizer.cpp,v 1.15 2004/10/24 23:50:44 kester Exp $
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
 
#include <math.h>
 
#include "RAS_OpenGLRasterizer.h"

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifdef WIN32
#include <windows.h>
#endif // WIN32
#ifdef __APPLE__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif

#include "RAS_Rect.h"
#include "RAS_TexVert.h"
#include "MT_CmMatrix4x4.h"
#include "RAS_IRenderTools.h" // rendering text

#include "RAS_GLExtensionManager.h"

/**
 *  32x32 bit masks for vinterlace stereo mode
 */
static GLuint left_eye_vinterlace_mask[32];
static GLuint right_eye_vinterlace_mask[32];

/**
 *  32x32 bit masks for hinterlace stereo mode.
 *  Left eye = &hinterlace_mask[0]
 *  Right eye = &hinterlace_mask[1]
 */
static GLuint hinterlace_mask[33];

RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
      :RAS_IRasterizer(canvas),
      m_2DCanvas(canvas),
      m_fogenabled(false),
      m_time(0.0),
      m_stereomode(RAS_STEREO_NOSTEREO),
      m_curreye(RAS_STEREO_LEFTEYE),
      m_eyeseparation(0.0),
      m_seteyesep(false),
      m_focallength(0.0),
      m_setfocallength(false),
      m_noOfScanlines(32),
      m_materialCachingInfo(0)
{
      m_viewmatrix.Identity();
      
      for (int i = 0; i < 32; i++)
      {
            left_eye_vinterlace_mask[i] = 0x55555555;
            right_eye_vinterlace_mask[i] = 0xAAAAAAAA;
            hinterlace_mask[i] = (i&1)*0xFFFFFFFF;
      }
      hinterlace_mask[32] = 0;
}



RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
{
}



static void Myinit_gl_stuff(void)   
{
      float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
      float mat_shininess[] = { 35.0 };
/*    float one= 1.0; */
      int a, x, y;
      GLubyte pat[32*32];
      const GLubyte *patc= pat;
            
      glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
      glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);


#if defined(__FreeBSD) || defined(__linux__)
      glDisable(GL_DITHER);   /* op sgi/sun hardware && 12 bits */
#endif
      
      /* no local viewer, looks ugly in ortho mode */
      /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
      
      glDepthFunc(GL_LEQUAL);
      /* scaling matrices */
      glEnable(GL_NORMALIZE);

      glShadeModel(GL_FLAT);

      glDisable(GL_ALPHA_TEST);
      glDisable(GL_BLEND);
      glDisable(GL_DEPTH_TEST);
      glDisable(GL_FOG);
      glDisable(GL_LIGHTING);
      glDisable(GL_LOGIC_OP);
      glDisable(GL_STENCIL_TEST);
      glDisable(GL_TEXTURE_1D);
      glDisable(GL_TEXTURE_2D);

      glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
      glPixelTransferi(GL_RED_SCALE, 1);
      glPixelTransferi(GL_RED_BIAS, 0);
      glPixelTransferi(GL_GREEN_SCALE, 1);
      glPixelTransferi(GL_GREEN_BIAS, 0);
      glPixelTransferi(GL_BLUE_SCALE, 1);
      glPixelTransferi(GL_BLUE_BIAS, 0);
      glPixelTransferi(GL_ALPHA_SCALE, 1);
      glPixelTransferi(GL_ALPHA_BIAS, 0);

      a = 0;
      for(x=0; x<32; x++)
      {
            for(y=0; y<4; y++)
            {
                  if( (x) & 1) pat[a++]= 0x88;
                  else pat[a++]= 0x22;
            }
      }
      
      glPolygonStipple(patc);
}



00164 bool RAS_OpenGLRasterizer::Init()
{

      Myinit_gl_stuff();

      m_redback = 0.4375;
      m_greenback = 0.4375;
      m_blueback = 0.4375;
      m_alphaback = 0.0;
      
      glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
      glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

      glShadeModel(GL_SMOOTH);

      return true;
}



void RAS_OpenGLRasterizer::SetBackColor(float red,
                                                            float green,
                                                            float blue,
                                                            float alpha)
{
      m_redback = red;
      m_greenback = green;
      m_blueback = blue;
      m_alphaback = alpha;
}



void RAS_OpenGLRasterizer::SetFogColor(float r,
                                                         float g,
                                                         float b)
{
      m_fogr = r;
      m_fogg = g;
      m_fogb = b;
      m_fogenabled = true;
}



void RAS_OpenGLRasterizer::SetFogStart(float start)
{
      m_fogstart = start;
      m_fogenabled = true;
}



void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
{
      m_fogdist = fogend;
      m_fogenabled = true;
}



void RAS_OpenGLRasterizer::SetFog(float start,
                                                  float dist,
                                                  float r,
                                                  float g,
                                                  float b)
{
      m_fogstart = start;
      m_fogdist = dist;
      m_fogr = r;
      m_fogg = g;
      m_fogb = b;
      m_fogenabled = true;
}



void RAS_OpenGLRasterizer::DisableFog()
{
      m_fogenabled = false;
}



void RAS_OpenGLRasterizer::DisplayFog()
{
      if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
      {
            float params[5];
            glFogi(GL_FOG_MODE, GL_LINEAR);
            glFogf(GL_FOG_DENSITY, 0.1f);
            glFogf(GL_FOG_START, m_fogstart);
            glFogf(GL_FOG_END, m_fogstart + m_fogdist);
            params[0]= m_fogr;
            params[1]= m_fogg;
            params[2]= m_fogb;
            params[3]= 0.0;
            glFogfv(GL_FOG_COLOR, params); 
            glEnable(GL_FOG);
      } 
      else
      {
            glDisable(GL_FOG);
      }
}



00273 void RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
{
      if (mat.GetCachingInfo() != m_materialCachingInfo)
      {
            mat.Activate(this, m_materialCachingInfo);
      }
}



00283 void RAS_OpenGLRasterizer::Exit()
{

      glEnable(GL_CULL_FACE);
      glEnable(GL_DEPTH_TEST);
      glClearDepth(1.0); 
      glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      glClearColor(m_redback, m_greenback, m_blueback, m_alphaback);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glDepthMask (GL_TRUE);
      glDepthFunc(GL_LEQUAL);
      glBlendFunc(GL_ONE, GL_ZERO);
      
      glDisable(GL_POLYGON_STIPPLE);
      
      glDisable(GL_LIGHTING);
      if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
            glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
      
      EndFrame();
}

bool RAS_OpenGLRasterizer::InterlacedStereo() const
{
      return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
}

00310 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
{
      m_time = time;
      m_drawingmode = drawingmode;
      
      if (!InterlacedStereo() || m_curreye == RAS_STEREO_LEFTEYE)
      {
            m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
            m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
      }

      // Blender camera routine destroys the settings
      if (m_drawingmode < KX_SOLID)
      {
            glDisable (GL_CULL_FACE);
            glDisable (GL_DEPTH_TEST);
      }
      else
      {
            glEnable(GL_DEPTH_TEST);
            glEnable (GL_CULL_FACE);
      }

      glShadeModel(GL_SMOOTH);

      m_2DCanvas->BeginFrame();
      
      return true;
}



00342 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
{
      m_drawingmode = drawingmode;

      switch (m_drawingmode)
      {
      case KX_BOUNDINGBOX:
            {
            }
      case KX_WIREFRAME:
            {
                  glDisable (GL_CULL_FACE);
                  break;
            }
      case KX_TEXTURED:
            {
            }
      case KX_SHADED:
            {
            }
      case KX_SOLID:
            {
            }
      default:
            {
            }
      }
}



00373 int RAS_OpenGLRasterizer::GetDrawingMode()
{
      return m_drawingmode;
}



00380 void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask)
{
      glDepthMask(depthmask == KX_DEPTHMASK_DISABLED ? GL_FALSE : GL_TRUE);
}



00387 void RAS_OpenGLRasterizer::ClearDepthBuffer()
{
      m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
}


00393 void RAS_OpenGLRasterizer::ClearCachingInfo(void)
{
      m_materialCachingInfo = 0;
}


00399 void RAS_OpenGLRasterizer::EndFrame()
{
      glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      m_2DCanvas->EndFrame();
}     

00405 void RAS_OpenGLRasterizer::SetRenderArea()
{
      // only above/below stereo method needs viewport adjustment
      switch (m_stereomode)
      {
            case RAS_STEREO_ABOVEBELOW:
                  switch(m_curreye)
                  {
                        case RAS_STEREO_LEFTEYE:
                              // upper half of window
                              m_2DCanvas->GetDisplayArea().SetLeft(0);
                              m_2DCanvas->GetDisplayArea().SetBottom(m_2DCanvas->GetHeight() -
                                    int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
      
                              m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
                              m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
                              break;
                        case RAS_STEREO_RIGHTEYE:
                              // lower half of window
                              m_2DCanvas->GetDisplayArea().SetLeft(0);
                              m_2DCanvas->GetDisplayArea().SetBottom(0);
                              m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
                              m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
                              break;
                  }
                  break;
            case RAS_STEREO_SIDEBYSIDE:
                  switch (m_curreye)
                  {
                        case RAS_STEREO_LEFTEYE:
                              // Left half of window
                              m_2DCanvas->GetDisplayArea().SetLeft(0);
                              m_2DCanvas->GetDisplayArea().SetBottom(0);
                              m_2DCanvas->GetDisplayArea().SetRight(m_2DCanvas->GetWidth()/2);
                              m_2DCanvas->GetDisplayArea().SetTop(m_2DCanvas->GetHeight());
                              break;
                        case RAS_STEREO_RIGHTEYE:
                              // Right half of window
                              m_2DCanvas->GetDisplayArea().SetLeft(m_2DCanvas->GetWidth()/2);
                              m_2DCanvas->GetDisplayArea().SetBottom(0);
                              m_2DCanvas->GetDisplayArea().SetRight(m_2DCanvas->GetWidth());
                              m_2DCanvas->GetDisplayArea().SetTop(m_2DCanvas->GetHeight());
                              break;
                  }
                  break;
            default:
                  // every available pixel
                  m_2DCanvas->GetDisplayArea().SetLeft(0);
                  m_2DCanvas->GetDisplayArea().SetBottom(0);
                  m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
                  m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
                  break;
      }
}

      
00461 void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode)
{
      m_stereomode = stereomode;
}



00468 bool RAS_OpenGLRasterizer::Stereo()
{
      if(m_stereomode == RAS_STEREO_NOSTEREO)
            return false;
      else
            return true;
}


void RAS_OpenGLRasterizer::SetEye(StereoEye eye)
{
      m_curreye = eye;
      switch (m_stereomode)
      {
            case RAS_STEREO_QUADBUFFERED:
                  glDrawBuffer(m_curreye == RAS_STEREO_LEFTEYE ? GL_BACK_LEFT : GL_BACK_RIGHT);
                  break;
            case RAS_STEREO_ANAGLYPH:
                  if (m_curreye == RAS_STEREO_LEFTEYE)
                  {
                        glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
                  } else {
                        //glAccum(GL_LOAD, 1.0);
                        glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
                        ClearDepthBuffer();
                  }
                  break;
            case RAS_STEREO_VINTERLACE:
            {
                  glEnable(GL_POLYGON_STIPPLE);
                  glPolygonStipple((const GLubyte*) ((m_curreye == RAS_STEREO_LEFTEYE) ? left_eye_vinterlace_mask : right_eye_vinterlace_mask));
                  if (m_curreye == RAS_STEREO_RIGHTEYE)
                        ClearDepthBuffer();
                  break;
            }
            case RAS_STEREO_INTERLACED:
            {
                  glEnable(GL_POLYGON_STIPPLE);
                  glPolygonStipple((const GLubyte*) &hinterlace_mask[m_curreye == RAS_STEREO_LEFTEYE?0:1]);
                  if (m_curreye == RAS_STEREO_RIGHTEYE)
                        ClearDepthBuffer();
                  break;
            }
            default:
                  break;
      }
}

RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
{
      return m_curreye;
}


00522 void RAS_OpenGLRasterizer::SetEyeSeparation(float eyeseparation)
{
      m_eyeseparation = eyeseparation;
      m_seteyesep = true;
}

float RAS_OpenGLRasterizer::GetEyeSeparation()
{
      return m_eyeseparation;
}

00533 void RAS_OpenGLRasterizer::SetFocalLength(float focallength)
{
      m_focallength = focallength;
      m_setfocallength = true;
}

float RAS_OpenGLRasterizer::GetFocalLength()
{
      return m_focallength;
}


00545 void RAS_OpenGLRasterizer::SwapBuffers()
{
      m_2DCanvas->SwapBuffers();
}



00552 void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
                                                      const vecIndexArrays & indexarrays,
                                                      int mode,
                                                      class RAS_IPolyMaterial* polymat,
                                                      class RAS_IRenderTools* rendertools,
                                                      bool useObjectColor,
                                                      const MT_Vector4& rgbacolor
                                                      )
{ 
      GLenum drawmode;
      switch (mode)
      {
      case 0:
            drawmode = GL_TRIANGLES;
            break;
      case 1:
            drawmode = GL_LINES;
            break;
      case 2:
            drawmode = GL_QUADS;
            break;
      default:
            drawmode = GL_LINES;
            break;
      }
      
      const RAS_TexVert* vertexarray ;
      unsigned int numindices,vt;

      for (vt=0;vt<vertexarrays.size();vt++)
      {
            vertexarray = &((*vertexarrays[vt]) [0]);
            const KX_IndexArray & indexarray = (*indexarrays[vt]);
            numindices = indexarray.size();
            
            if (!numindices)
                  break;
            
            int vindex=0;
            switch (mode)
            {
            case 1:
                  {
                        glBegin(GL_LINES);
                        vindex=0;
                        for (unsigned int i=0;i<numindices;i+=2)
                        {
                              glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
                              glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
                        }
                        glEnd();
                  }
                  break;
            case 2:
                  {
                        glBegin(GL_QUADS);
                        vindex=0;
                        if (useObjectColor)
                        {
                              for (unsigned int i=0;i<numindices;i+=4)
                              {

                                    glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);

                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                              }
                        }
                        else
                        {
                              for (unsigned int i=0;i<numindices;i+=4)
                              {
                                    // This looks curiously endian unsafe to me.
                                    // However it depends on the way the colors are packed into 
                                    // the m_rgba field of RAS_TexVert

                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                              }
                        }
                        glEnd();    
                        break;
                  }
            case 0:
                  {
                        glBegin(GL_TRIANGLES);
                        vindex=0;
                        if (useObjectColor)
                        {
                              for (unsigned int i=0;i<numindices;i+=3)
                              {

                                    glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);

                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                              }
                        }
                        else 
                        {
                              for (unsigned int i=0;i<numindices;i+=3)
                              {

                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                              }
                        }
                        glEnd();    
                        break;
                  }
            default:
                  {
                  }
                  
            } // switch
      } // for each vertexarray

}

00736 void RAS_OpenGLRasterizer::IndexPrimitives_Ex(const vecVertexArray & vertexarrays,
                                                      const vecIndexArrays & indexarrays,
                                                      int mode,
                                                      class RAS_IPolyMaterial* polymat,
                                                      class RAS_IRenderTools* rendertools,
                                                      bool useObjectColor,
                                                      const MT_Vector4& rgbacolor
                                                      )
{ 
      bool  recalc;
      GLenum drawmode;
      switch (mode)
      {
      case 0:
            drawmode = GL_TRIANGLES;
            break;
      case 1:
            drawmode = GL_LINES;
            break;
      case 2:
            drawmode = GL_QUADS;
            break;
      default:
            drawmode = GL_LINES;
            break;
      }
      
      const RAS_TexVert* vertexarray ;
      unsigned int numindices,vt;

      for (vt=0;vt<vertexarrays.size();vt++)
      {
            vertexarray = &((*vertexarrays[vt]) [0]);
            const KX_IndexArray & indexarray = (*indexarrays[vt]);
            numindices = indexarray.size();
            
            if (!numindices)
                  continue;
            
            int vindex=0;
            switch (mode)
            {
            case 1:
                  {
                        glBegin(GL_LINES);
                        vindex=0;
                        for (unsigned int i=0;i<numindices;i+=2)
                        {
                              glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
                              glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
                        }
                        glEnd();
                  }
                  break;
            case 2:
                  {
                        glBegin(GL_QUADS);
                        vindex=0;
                        if (useObjectColor)
                        {
                              for (unsigned int i=0;i<numindices;i+=4)
                              {
                                    MT_Point3 mv1, mv2, mv3, mv4, fnor;
                                    /* Calc a new face normal */

                                    if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
                                          recalc= true;
                                    else
                                          recalc=false;

                                    if (recalc){
                                          mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                          mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
                                          mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
                                          mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
                                          
                                          fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();

                                          glNormal3f(fnor[0], fnor[1], fnor[2]);
                                    }

                                    glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);

                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());                               
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                              }
                        }
                        else
                        {
                              for (unsigned int i=0;i<numindices;i+=4)
                              {
                                    // This looks curiously endian unsafe to me.
                                    // However it depends on the way the colors are packed into 
                                    // the m_rgba field of RAS_TexVert
                                    MT_Point3 mv1, mv2, mv3, mv4, fnor;
                                    /* Calc a new face normal */

                                    if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
                                          recalc= true;
                                    else
                                          recalc=false;


                                    if (recalc){
                                          mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                          mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
                                          mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
                                          mv4 = MT_Point3(vertexarray[(indexarray[vindex+3])].getLocalXYZ());
                                          
                                          fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized();

                                          glNormal3f(fnor[0], fnor[1], fnor[2]);
                                    }

                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                              }
                        }
                        glEnd();    
                        break;
                  }
            case 0:
                  {
                        glBegin(GL_TRIANGLES);
                        vindex=0;
                        if (useObjectColor)
                        {
                              for (unsigned int i=0;i<numindices;i+=3)
                              {
                                    MT_Point3 mv1, mv2, mv3, fnor;
                                    /* Calc a new face normal */

                                    if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
                                          recalc= true;
                                    else
                                          recalc=false;

                                    if (recalc){
                                          mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                          mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
                                          mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
                                          
                                          fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
                                          glNormal3f(fnor[0], fnor[1], fnor[2]);
                                    }

                                    glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);

                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                              }
                        }
                        else 
                        {
                              for (unsigned int i=0;i<numindices;i+=3)
                              {
                                    MT_Point3 mv1, mv2, mv3, fnor;
                                    /* Calc a new face normal */

                                    if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL)
                                          recalc= true;
                                    else
                                          recalc=false;


                                    if (recalc){
                                          mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                          mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ());
                                          mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ());
                                          
                                          fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized();
                                          glNormal3f(fnor[0], fnor[1], fnor[2]);
                                    }

                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                                    
                                    glColor4ubv((const GLubyte *)(vertexarray[(indexarray[vindex])].getRGBA()));
                                    if (!recalc)
                                          glNormal3fv(vertexarray[(indexarray[vindex])].getNormal());
                                    glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
                                    glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
                                    vindex++;
                              }
                        }
                        glEnd();    
                        break;
                  }
            default:
                  {
                  }
                  
            } // switch
      } // for each vertexarray

}



01007 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays,
                                                      const vecIndexArrays & indexarrays,
                                                      int mode,
                                                      class RAS_IPolyMaterial* polymat,
                                                      class RAS_IRenderTools* rendertools,
                                                      bool useObjectColor,
                                                      const MT_Vector4& rgbacolor
                                                      )
{ 
      GLenum drawmode;
      switch (mode)
      {
      case 0:
            drawmode = GL_TRIANGLES;
            break;
      case 1:
            drawmode = GL_LINES;
            break;
      case 2:
            drawmode = GL_QUADS;
            break;
      default:
            drawmode = GL_LINES;
            break;
      }
      
      const RAS_TexVert* vertexarray ;
      
      unsigned int numindices, vt;
      
      if (useObjectColor)
      {
            glDisableClientState(GL_COLOR_ARRAY);
            glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
      }
      else
      {
            glEnableClientState(GL_COLOR_ARRAY);
      }
      
      for (vt=0;vt<vertexarrays.size();vt++)
      {
            vertexarray = &((*vertexarrays[vt]) [0]);
            const KX_IndexArray & indexarray = (*indexarrays[vt]);
            numindices = indexarray.size();
            
            if (!numindices)
                  break;
            
            int vindex=0;
            switch (mode)
            {
            case 1:
                  {
                        glBegin(GL_LINES);
                        vindex=0;
                        for (unsigned int i=0;i<numindices;i+=2)
                        {
                              glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
                              glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
                        }
                        glEnd();
                  }
                  break;
            case 2:
                  {
                        vindex=0;
                        for (unsigned int i=0;i<numindices;i+=4)
                        {
                              float v1[3],v2[3],v3[3],v4[3];
                              
                              v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
                              v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
                              v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
                              vindex++;
                              
                              v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
                              v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
                              v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
                              vindex++;
                              
                              v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
                              v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
                              v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
                              vindex++;
                              
                              v4[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
                              v4[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
                              v4[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
                              
                              vindex++;
                              
                              rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,v4);
                              ClearCachingInfo();
                        }
                        break;
                  }
            case 0:
                  {
                        glBegin(GL_TRIANGLES);
                        vindex=0;
                        for (unsigned int i=0;i<numindices;i+=3)
                        {
                              float v1[3],v2[3],v3[3];
                              
                              v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
                              v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
                              v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
                              vindex++;
                              
                              v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
                              v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
                              v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
                              vindex++;
                              
                              v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
                              v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
                              v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
                              vindex++;
                              
                              rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,NULL);           
                              ClearCachingInfo();
                        }
                        glEnd();    
                        break;
                  }
            default:
                  {
                  }
            }     //switch
      }     //for each vertexarray
}



void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
{
      glMatrixMode(GL_PROJECTION);
      double* matrix = &mat(0,0);
      glLoadMatrixd(matrix);
}


01150 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
{
      glMatrixMode(GL_PROJECTION);
      double matrix[16];
      /* Get into argument. Looks a bit dodgy, but it's ok. */
      mat.getValue(matrix);
      /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
      glLoadMatrixd(matrix);  
}

01160 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
      float left,
      float right,
      float bottom,
      float top,
      float frustnear,
      float frustfar,
      bool
){
      MT_Matrix4x4 result;
      double mat[16];

      // correction for stereo
      if(m_stereomode != RAS_STEREO_NOSTEREO)
      {
                  float near_div_focallength;
                  // next 2 params should be specified on command line and in Blender publisher
                  if (!m_setfocallength)
                        m_focallength = 1.5 * right;  // derived from example
                  if (!m_seteyesep)
                        m_eyeseparation = 0.18 * right;  // just a guess...

                  near_div_focallength = frustnear / m_focallength;
                  switch(m_curreye)
                  {
                        case RAS_STEREO_LEFTEYE:
                                    left += 0.5 * m_eyeseparation * near_div_focallength;
                                    right += 0.5 * m_eyeseparation * near_div_focallength;
                                    break;
                        case RAS_STEREO_RIGHTEYE:
                                    left -= 0.5 * m_eyeseparation * near_div_focallength;
                                    right -= 0.5 * m_eyeseparation * near_div_focallength;
                                    break;
                  }
                  // leave bottom, top, bottom and top untouched
      }
      
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glFrustum(left, right, bottom, top, frustnear, frustfar);
            
      glGetDoublev(GL_PROJECTION_MATRIX, mat);
      result.setValue(mat);

      return result;
}


// next arguments probably contain redundant info, for later...
01209 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
            const MT_Point3 &, const MT_Quaternion &camOrientQuat)
{
      MT_Matrix4x4 viewMat = mat;

      // correction for stereo
      if(m_stereomode != RAS_STEREO_NOSTEREO)
      {
            MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
            MT_Vector3 unitViewDir(0.0, -1.0, 0.0);  // minus y direction, Blender convention
            MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
            MT_Vector3 viewDir, viewupVec;
            MT_Vector3 eyeline;

            // actual viewDir
            viewDir = camOrientMat3x3 * unitViewDir;  // this is the moto convention, vector on right hand side
            // actual viewup vec
            viewupVec = camOrientMat3x3 * unitViewupVec;

            // vector between eyes
            eyeline = viewDir.cross(viewupVec);

            switch(m_curreye)
            {
                  case RAS_STEREO_LEFTEYE:
                        {
                        // translate to left by half the eye distance
                        MT_Transform transform;
                        transform.setIdentity();
                        transform.translate(-(eyeline * m_eyeseparation / 2.0));
                        viewMat *= transform;
                        }
                        break;
                  case RAS_STEREO_RIGHTEYE:
                        {
                        // translate to right by half the eye distance
                        MT_Transform transform;
                        transform.setIdentity();
                        transform.translate(eyeline * m_eyeseparation / 2.0);
                        viewMat *= transform;
                        }
                        break;
            }
      }

      // convert row major matrix 'viewMat' to column major for OpenGL
      MT_Scalar cammat[16];
      viewMat.getValue(cammat);
      MT_CmMatrix4x4 viewCmmat = cammat;

      glMatrixMode(GL_MODELVIEW);
      m_viewmatrix = viewCmmat;
      glLoadMatrixd(&m_viewmatrix(0,0));
      m_campos = campos;
}


const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
{
      return m_campos;
}



void RAS_OpenGLRasterizer::LoadViewMatrix()
{
      glLoadMatrixd(&m_viewmatrix(0,0));
}



void RAS_OpenGLRasterizer::EnableTextures(bool enable)
{
}



01286 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
{
      if (enable)
            glEnable(GL_CULL_FACE);
      else
            glDisable(GL_CULL_FACE);
}

01294 void RAS_OpenGLRasterizer::SetLines(bool enable)
{
      if (enable)
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      else
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}

01302 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
                                                              float specY,
                                                              float specZ,
                                                              float specval)
{
      GLfloat mat_specular[] = {specX, specY, specZ, specval};
      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
}



01313 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
{
      GLfloat mat_shininess[] = {   shiny };
      glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
}



01321 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
{
      GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
      glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
}

double RAS_OpenGLRasterizer::GetTime()
{
      return m_time;
}



Generated by  Doxygen 1.6.0   Back to index