3 * ***** BEGIN GPL LICENSE BLOCK *****
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20 * All rights reserved.
22 * The Original Code is: all of this file.
24 * Contributor(s): none yet.
26 * ***** END GPL LICENSE BLOCK *****
29 /** \file gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
37 #include "RAS_OpenGLRasterizer.h"
42 #include "RAS_TexVert.h"
43 #include "RAS_MeshObject.h"
44 #include "MT_CmMatrix4x4.h"
45 #include "RAS_IRenderTools.h" // rendering text
48 #include "GPU_material.h"
49 #include "GPU_extensions.h"
51 #include "DNA_image_types.h"
52 #include "DNA_meshdata_types.h"
53 #include "DNA_material_types.h"
54 #include "DNA_scene_types.h"
56 #include "BKE_DerivedMesh.h"
59 * 32x32 bit masks for vinterlace stereo mode
61 static GLuint left_eye_vinterlace_mask[32];
62 static GLuint right_eye_vinterlace_mask[32];
65 * 32x32 bit masks for hinterlace stereo mode.
66 * Left eye = &hinterlace_mask[0]
67 * Right eye = &hinterlace_mask[1]
69 static GLuint hinterlace_mask[33];
71 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
72 :RAS_IRasterizer(canvas),
76 m_campos(0.0f, 0.0f, 0.0f),
78 m_stereomode(RAS_STEREO_NOSTEREO),
79 m_curreye(RAS_STEREO_LEFTEYE),
82 m_setfocallength(false),
85 m_motionblurvalue(-1.0),
88 //m_last_blendmode(GPU_BLEND_SOLID),
89 m_last_frontface(true),
90 m_materialCachingInfo(0)
92 m_viewmatrix.setIdentity();
93 m_viewinvmatrix.setIdentity();
95 for (int i = 0; i < 32; i++)
97 left_eye_vinterlace_mask[i] = 0x55555555;
98 right_eye_vinterlace_mask[i] = 0xAAAAAAAA;
99 hinterlace_mask[i] = (i&1)*0xFFFFFFFF;
101 hinterlace_mask[32] = 0;
106 RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
110 bool RAS_OpenGLRasterizer::Init()
120 glDisable(GL_ALPHA_TEST);
121 //m_last_blendmode = GPU_BLEND_SOLID;
122 GPU_set_material_blend_mode(GPU_BLEND_SOLID);
125 m_last_frontface = true;
128 m_greenback = 0.4375;
132 glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
133 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
134 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
137 glShadeModel(GL_SMOOTH);
143 void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
151 void RAS_OpenGLRasterizer::SetAmbient(float factor)
153 float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
154 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
158 void RAS_OpenGLRasterizer::SetBackColor(float red,
171 void RAS_OpenGLRasterizer::SetFogColor(float r,
183 void RAS_OpenGLRasterizer::SetFogStart(float start)
191 void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
199 void RAS_OpenGLRasterizer::SetFog(float start,
215 void RAS_OpenGLRasterizer::DisableFog()
217 m_fogenabled = false;
220 bool RAS_OpenGLRasterizer::IsFogEnabled()
226 void RAS_OpenGLRasterizer::DisplayFog()
228 if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
231 glFogi(GL_FOG_MODE, GL_LINEAR);
232 glFogf(GL_FOG_DENSITY, 0.1f);
233 glFogf(GL_FOG_START, m_fogstart);
234 glFogf(GL_FOG_END, m_fogstart + m_fogdist);
239 glFogfv(GL_FOG_COLOR, params);
250 bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
252 return mat.Activate(this, m_materialCachingInfo);
257 void RAS_OpenGLRasterizer::Exit()
260 glEnable(GL_CULL_FACE);
261 glEnable(GL_DEPTH_TEST);
263 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
264 glClearColor(m_redback, m_greenback, m_blueback, m_alphaback);
265 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
266 glDepthMask (GL_TRUE);
267 glDepthFunc(GL_LEQUAL);
268 glBlendFunc(GL_ONE, GL_ZERO);
270 glDisable(GL_POLYGON_STIPPLE);
272 glDisable(GL_LIGHTING);
273 if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
274 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
279 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
282 m_drawingmode = drawingmode;
284 // Blender camera routine destroys the settings
285 if (m_drawingmode < KX_SOLID)
287 glDisable (GL_CULL_FACE);
288 glDisable (GL_DEPTH_TEST);
292 glEnable(GL_DEPTH_TEST);
293 glEnable (GL_CULL_FACE);
297 glDisable(GL_ALPHA_TEST);
298 //m_last_blendmode = GPU_BLEND_SOLID;
299 GPU_set_material_blend_mode(GPU_BLEND_SOLID);
302 m_last_frontface = true;
304 glShadeModel(GL_SMOOTH);
306 glEnable(GL_MULTISAMPLE_ARB);
308 m_2DCanvas->BeginFrame();
315 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
317 m_drawingmode = drawingmode;
319 if(m_drawingmode == KX_WIREFRAME)
320 glDisable(GL_CULL_FACE);
323 int RAS_OpenGLRasterizer::GetDrawingMode()
325 return m_drawingmode;
329 void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask)
331 glDepthMask(depthmask == KX_DEPTHMASK_DISABLED ? GL_FALSE : GL_TRUE);
335 void RAS_OpenGLRasterizer::ClearColorBuffer()
337 m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
338 m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
342 void RAS_OpenGLRasterizer::ClearDepthBuffer()
344 m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
348 void RAS_OpenGLRasterizer::ClearCachingInfo(void)
350 m_materialCachingInfo = 0;
353 void RAS_OpenGLRasterizer::FlushDebugLines()
355 if(!m_debugLines.size())
359 GLboolean light, tex;
361 light= glIsEnabled(GL_LIGHTING);
362 tex= glIsEnabled(GL_TEXTURE_2D);
364 if(light) glDisable(GL_LIGHTING);
365 if(tex) glDisable(GL_TEXTURE_2D);
368 for (unsigned int i=0;i<m_debugLines.size();i++)
370 glColor4f(m_debugLines[i].m_color[0],m_debugLines[i].m_color[1],m_debugLines[i].m_color[2],1.f);
371 const MT_Scalar* fromPtr = &m_debugLines[i].m_from.x();
372 const MT_Scalar* toPtr= &m_debugLines[i].m_to.x();
374 glVertex3dv(fromPtr);
379 if(light) glEnable(GL_LIGHTING);
380 if(tex) glEnable(GL_TEXTURE_2D);
382 m_debugLines.clear();
385 void RAS_OpenGLRasterizer::EndFrame()
391 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
393 glDisable(GL_MULTISAMPLE_ARB);
395 m_2DCanvas->EndFrame();
398 void RAS_OpenGLRasterizer::SetRenderArea()
401 // only above/below stereo method needs viewport adjustment
402 switch (m_stereomode)
404 case RAS_STEREO_ABOVEBELOW:
407 case RAS_STEREO_LEFTEYE:
408 // upper half of window
410 area.SetBottom(m_2DCanvas->GetHeight() -
411 int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
413 area.SetRight(int(m_2DCanvas->GetWidth()));
414 area.SetTop(int(m_2DCanvas->GetHeight()));
415 m_2DCanvas->SetDisplayArea(&area);
417 case RAS_STEREO_RIGHTEYE:
418 // lower half of window
421 area.SetRight(int(m_2DCanvas->GetWidth()));
422 area.SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
423 m_2DCanvas->SetDisplayArea(&area);
427 case RAS_STEREO_SIDEBYSIDE:
430 case RAS_STEREO_LEFTEYE:
431 // Left half of window
434 area.SetRight(m_2DCanvas->GetWidth()/2);
435 area.SetTop(m_2DCanvas->GetHeight());
436 m_2DCanvas->SetDisplayArea(&area);
438 case RAS_STEREO_RIGHTEYE:
439 // Right half of window
440 area.SetLeft(m_2DCanvas->GetWidth()/2);
442 area.SetRight(m_2DCanvas->GetWidth());
443 area.SetTop(m_2DCanvas->GetHeight());
444 m_2DCanvas->SetDisplayArea(&area);
449 // every available pixel
452 area.SetRight(int(m_2DCanvas->GetWidth()));
453 area.SetTop(int(m_2DCanvas->GetHeight()));
454 m_2DCanvas->SetDisplayArea(&area);
459 void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode)
461 m_stereomode = stereomode;
464 RAS_IRasterizer::StereoMode RAS_OpenGLRasterizer::GetStereoMode()
469 bool RAS_OpenGLRasterizer::Stereo()
471 if(m_stereomode > RAS_STEREO_NOSTEREO) // > 0
477 bool RAS_OpenGLRasterizer::InterlacedStereo()
479 return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
482 void RAS_OpenGLRasterizer::SetEye(const StereoEye eye)
485 switch (m_stereomode)
487 case RAS_STEREO_QUADBUFFERED:
488 glDrawBuffer(m_curreye == RAS_STEREO_LEFTEYE ? GL_BACK_LEFT : GL_BACK_RIGHT);
490 case RAS_STEREO_ANAGLYPH:
491 if (m_curreye == RAS_STEREO_LEFTEYE)
493 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
495 //glAccum(GL_LOAD, 1.0);
496 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
500 case RAS_STEREO_VINTERLACE:
502 glEnable(GL_POLYGON_STIPPLE);
503 glPolygonStipple((const GLubyte*) ((m_curreye == RAS_STEREO_LEFTEYE) ? left_eye_vinterlace_mask : right_eye_vinterlace_mask));
504 if (m_curreye == RAS_STEREO_RIGHTEYE)
508 case RAS_STEREO_INTERLACED:
510 glEnable(GL_POLYGON_STIPPLE);
511 glPolygonStipple((const GLubyte*) &hinterlace_mask[m_curreye == RAS_STEREO_LEFTEYE?0:1]);
512 if (m_curreye == RAS_STEREO_RIGHTEYE)
521 RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
527 void RAS_OpenGLRasterizer::SetEyeSeparation(const float eyeseparation)
529 m_eyeseparation = eyeseparation;
532 float RAS_OpenGLRasterizer::GetEyeSeparation()
534 return m_eyeseparation;
537 void RAS_OpenGLRasterizer::SetFocalLength(const float focallength)
539 m_focallength = focallength;
540 m_setfocallength = true;
543 float RAS_OpenGLRasterizer::GetFocalLength()
545 return m_focallength;
549 void RAS_OpenGLRasterizer::SwapBuffers()
551 m_2DCanvas->SwapBuffers();
556 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewMatrix() const
561 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewInvMatrix() const
563 return m_viewinvmatrix;
566 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
567 class RAS_IPolyMaterial* polymat,
568 class RAS_IRenderTools* rendertools)
570 bool obcolor = ms.m_bObjectColor;
571 MT_Vector4& rgba = ms.m_RGBAcolor;
572 RAS_MeshSlot::iterator it;
574 // handle object color
576 glDisableClientState(GL_COLOR_ARRAY);
577 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
580 glEnableClientState(GL_COLOR_ARRAY);
582 for(ms.begin(it); !ms.end(it); ms.next(it)) {
584 size_t i, j, numvert;
586 numvert = it.array->m_type;
588 if(it.array->m_type == RAS_DisplayArray::LINE) {
589 // line drawing, no text
592 for(i=0; i<it.totindex; i+=2)
594 vertex = &it.vertex[it.index[i]];
595 glVertex3fv(vertex->getXYZ());
597 vertex = &it.vertex[it.index[i+1]];
598 glVertex3fv(vertex->getXYZ());
604 // triangle and quad text drawing
605 for(i=0; i<it.totindex; i+=numvert)
610 for(j=0; j<numvert; j++) {
611 vertex = &it.vertex[it.index[i+j]];
613 v[j][0] = vertex->getXYZ()[0];
614 v[j][1] = vertex->getXYZ()[1];
615 v[j][2] = vertex->getXYZ()[2];
618 // find the right opengl attribute
620 if(GLEW_ARB_vertex_program)
621 for(unit=0; unit<m_attrib_num; unit++)
622 if(m_attrib[unit] == RAS_TEXCO_UV1)
625 rendertools->RenderText(polymat->GetDrawingMode(), polymat,
626 v[0], v[1], v[2], (numvert == 4)? v[3]: NULL, glattrib);
633 glDisableClientState(GL_COLOR_ARRAY);
636 void RAS_OpenGLRasterizer::SetTexCoordNum(int num)
639 if(m_texco_num > RAS_MAX_TEXCO)
640 m_texco_num = RAS_MAX_TEXCO;
643 void RAS_OpenGLRasterizer::SetAttribNum(int num)
646 if(m_attrib_num > RAS_MAX_ATTRIB)
647 m_attrib_num = RAS_MAX_ATTRIB;
650 void RAS_OpenGLRasterizer::SetTexCoord(TexCoGen coords, int unit)
652 // this changes from material to material
653 if(unit < RAS_MAX_TEXCO)
654 m_texco[unit] = coords;
657 void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit)
659 // this changes from material to material
660 if(unit < RAS_MAX_ATTRIB)
661 m_attrib[unit] = coords;
664 void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
668 if(GLEW_ARB_multitexture) {
669 for(unit=0; unit<m_texco_num; unit++) {
670 if(tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) {
671 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
674 switch(m_texco[unit]) {
677 glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
680 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
683 glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
686 glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
689 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
697 if(GLEW_ARB_vertex_program) {
698 for(unit=0; unit<m_attrib_num; unit++) {
699 switch(m_attrib[unit]) {
702 glVertexAttrib3fvARB(unit, tv.getXYZ());
705 glVertexAttrib2fvARB(unit, tv.getUV1());
708 glVertexAttrib3fvARB(unit, tv.getNormal());
711 glVertexAttrib4fvARB(unit, tv.getTangent());
714 glVertexAttrib2fvARB(unit, tv.getUV2());
717 glVertexAttrib4ubvARB(unit, tv.getRGBA());
727 void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
729 IndexPrimitivesInternal(ms, false);
732 void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
734 IndexPrimitivesInternal(ms, true);
737 static bool current_wireframe;
738 static RAS_MaterialBucket *current_bucket;
739 static RAS_IPolyMaterial *current_polymat;
740 static RAS_MeshSlot *current_ms;
741 static RAS_MeshObject *current_mesh;
742 static int current_blmat_nr;
743 static GPUVertexAttribs current_gpu_attribs;
744 static Image *current_image;
745 static int CheckMaterialDM(int matnr, void *attribs)
747 // only draw the current material
748 if (matnr != current_blmat_nr)
750 GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
752 memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs));
757 static int CheckTexfaceDM(void *mcol, int index)
760 // index is the original face index, retrieve the polygon
761 RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
762 current_mesh->GetPolygon(index) : NULL;
763 if (polygon && polygon->GetMaterial() == current_bucket) {
764 // must handle color.
765 if (current_wireframe)
767 if (current_ms->m_bObjectColor) {
768 MT_Vector4& rgba = current_ms->m_RGBAcolor;
769 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
774 // we have to set the color from the material
775 unsigned char rgba[4];
776 current_polymat->GetMaterialRGBAColor(rgba);
777 glColor4ubv((const GLubyte *)rgba);
786 static int CheckTexDM(MTFace *tface, int has_vcol, int matnr)
789 // index is the original face index, retrieve the polygon
790 if (matnr == current_blmat_nr &&
791 (tface == NULL || tface->tpage == current_image)) {
792 // must handle color.
793 if (current_wireframe)
795 if (current_ms->m_bObjectColor) {
796 MT_Vector4& rgba = current_ms->m_RGBAcolor;
797 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
802 // we have to set the color from the material
803 unsigned char rgba[4];
804 current_polymat->GetMaterialRGBAColor(rgba);
805 glColor4ubv((const GLubyte *)rgba);
813 void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
815 bool obcolor = ms.m_bObjectColor;
816 bool wireframe = m_drawingmode <= KX_WIREFRAME;
817 MT_Vector4& rgba = ms.m_RGBAcolor;
818 RAS_MeshSlot::iterator it;
820 if (ms.m_pDerivedMesh) {
821 // mesh data is in derived mesh,
822 current_bucket = ms.m_bucket;
823 current_polymat = current_bucket->GetPolyMaterial();
825 current_mesh = ms.m_mesh;
826 current_wireframe = wireframe;
827 // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
830 if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_TWOSIDE)
831 this->SetCullFace(false);
833 this->SetCullFace(true);
835 if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
836 // GetMaterialIndex return the original mface material index,
837 // increment by 1 to match what derived mesh is doing
838 current_blmat_nr = current_polymat->GetMaterialIndex()+1;
839 // For GLSL we need to retrieve the GPU material attribute
840 Material* blmat = current_polymat->GetBlenderMaterial();
841 Scene* blscene = current_polymat->GetBlenderScene();
842 if (!wireframe && blscene && blmat)
843 GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs);
845 memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs));
846 // DM draw can mess up blending mode, restore at the end
847 int current_blend_mode = GPU_get_material_blend_mode();
848 ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
849 GPU_set_material_blend_mode(current_blend_mode);
851 //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
852 current_blmat_nr = current_polymat->GetMaterialIndex();
853 current_image = current_polymat->GetBlenderImage();
854 ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM);
858 // iterate over display arrays, each containing an index + vertex array
859 for(ms.begin(it); !ms.end(it); ms.next(it)) {
861 size_t i, j, numvert;
863 numvert = it.array->m_type;
865 if(it.array->m_type == RAS_DisplayArray::LINE) {
869 for(i=0; i<it.totindex; i+=2)
871 vertex = &it.vertex[it.index[i]];
872 glVertex3fv(vertex->getXYZ());
874 vertex = &it.vertex[it.index[i+1]];
875 glVertex3fv(vertex->getXYZ());
881 // triangle and quad drawing
882 if(it.array->m_type == RAS_DisplayArray::TRIANGLE)
883 glBegin(GL_TRIANGLES);
887 for(i=0; i<it.totindex; i+=numvert)
890 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
892 for(j=0; j<numvert; j++) {
893 vertex = &it.vertex[it.index[i+j]];
897 glColor4ubv((const GLubyte *)(vertex->getRGBA()));
899 glNormal3fv(vertex->getNormal());
904 glTexCoord2fv(vertex->getUV1());
907 glVertex3fv(vertex->getXYZ());
916 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
918 glMatrixMode(GL_PROJECTION);
919 double* matrix = &mat(0,0);
920 glLoadMatrixd(matrix);
922 m_camortho= (mat(3, 3) != 0.0f);
925 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
927 glMatrixMode(GL_PROJECTION);
929 /* Get into argument. Looks a bit dodgy, but it's ok. */
930 mat.getValue(matrix);
931 /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
932 glLoadMatrixd(matrix);
934 m_camortho= (mat[3][3] != 0.0f);
937 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
950 // correction for stereo
953 float near_div_focallength;
956 // if Rasterizer.setFocalLength is not called we use the camera focallength
957 if (!m_setfocallength)
958 // if focallength is null we use a value known to be reasonable
959 m_focallength = (focallength == 0.f) ? m_eyeseparation * 30.0
962 near_div_focallength = frustnear / m_focallength;
963 offset = 0.5 * m_eyeseparation * near_div_focallength;
966 case RAS_STEREO_LEFTEYE:
970 case RAS_STEREO_RIGHTEYE:
975 // leave bottom and top untouched
978 glMatrixMode(GL_PROJECTION);
980 glFrustum(left, right, bottom, top, frustnear, frustfar);
982 glGetDoublev(GL_PROJECTION_MATRIX, mat);
983 result.setValue(mat);
988 MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix(
999 // stereo is meaning less for orthographic, disable it
1000 glMatrixMode(GL_PROJECTION);
1002 glOrtho(left, right, bottom, top, frustnear, frustfar);
1004 glGetDoublev(GL_PROJECTION_MATRIX, mat);
1005 result.setValue(mat);
1011 // next arguments probably contain redundant info, for later...
1012 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat,
1013 const MT_Matrix3x3 & camOrientMat3x3,
1014 const MT_Point3 & pos,
1019 // correction for stereo
1020 if(Stereo() && perspective)
1022 MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention
1023 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
1024 MT_Vector3 viewDir, viewupVec;
1028 viewDir = camOrientMat3x3 * unitViewDir; // this is the moto convention, vector on right hand side
1029 // actual viewup vec
1030 viewupVec = camOrientMat3x3 * unitViewupVec;
1032 // vector between eyes
1033 eyeline = viewDir.cross(viewupVec);
1037 case RAS_STEREO_LEFTEYE:
1039 // translate to left by half the eye distance
1040 MT_Transform transform;
1041 transform.setIdentity();
1042 transform.translate(-(eyeline * m_eyeseparation / 2.0));
1043 m_viewmatrix *= transform;
1046 case RAS_STEREO_RIGHTEYE:
1048 // translate to right by half the eye distance
1049 MT_Transform transform;
1050 transform.setIdentity();
1051 transform.translate(eyeline * m_eyeseparation / 2.0);
1052 m_viewmatrix *= transform;
1058 m_viewinvmatrix = m_viewmatrix;
1059 m_viewinvmatrix.invert();
1061 // note: getValue gives back column major as needed by OpenGL
1062 MT_Scalar glviewmat[16];
1063 m_viewmatrix.getValue(glviewmat);
1065 glMatrixMode(GL_MODELVIEW);
1066 glLoadMatrixd(glviewmat);
1071 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
1076 bool RAS_OpenGLRasterizer::GetCameraOrtho()
1081 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
1084 glEnable(GL_CULL_FACE);
1086 glDisable(GL_CULL_FACE);
1089 void RAS_OpenGLRasterizer::SetLines(bool enable)
1092 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1094 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1097 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
1102 GLfloat mat_specular[] = {specX, specY, specZ, specval};
1103 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
1108 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
1110 GLfloat mat_shininess[] = { shiny };
1111 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
1116 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
1118 GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
1119 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
1122 void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e)
1124 GLfloat mat_emit [] = {eX,eY,eZ,e};
1125 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit);
1129 double RAS_OpenGLRasterizer::GetTime()
1134 void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
1136 glPolygonOffset(mult, add);
1137 GLint mode = GL_POLYGON_OFFSET_FILL;
1138 if (m_drawingmode < KX_SHADED)
1139 mode = GL_POLYGON_OFFSET_LINE;
1140 if (mult != 0.0f || add != 0.0f)
1146 void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue)
1148 /* don't just set m_motionblur to 1, but check if it is 0 so
1149 * we don't reset a motion blur that is already enabled */
1150 if(m_motionblur == 0)
1152 m_motionblurvalue = motionblurvalue;
1155 void RAS_OpenGLRasterizer::DisableMotionBlur()
1158 m_motionblurvalue = -1.0;
1161 void RAS_OpenGLRasterizer::SetBlendingMode(int blendmode)
1163 GPU_set_material_blend_mode(blendmode);
1165 if(blendmode == m_last_blendmode)
1168 if(blendmode == GPU_BLEND_SOLID) {
1169 glDisable(GL_BLEND);
1170 glDisable(GL_ALPHA_TEST);
1171 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1173 else if(blendmode == GPU_BLEND_ADD) {
1174 glBlendFunc(GL_ONE, GL_ONE);
1176 glDisable(GL_ALPHA_TEST);
1178 else if(blendmode == GPU_BLEND_ALPHA) {
1179 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1181 glEnable(GL_ALPHA_TEST);
1182 glAlphaFunc(GL_GREATER, 0.0f);
1184 else if(blendmode == GPU_BLEND_CLIP) {
1185 glDisable(GL_BLEND);
1186 glEnable(GL_ALPHA_TEST);
1187 glAlphaFunc(GL_GREATER, 0.5f);
1190 m_last_blendmode = blendmode;
1194 void RAS_OpenGLRasterizer::SetFrontFace(bool ccw)
1196 if(m_last_frontface == ccw)
1200 glFrontFace(GL_CCW);
1204 m_last_frontface = ccw;