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 *****
32 #include "RAS_OpenGLRasterizer.h"
37 #include "RAS_TexVert.h"
38 #include "RAS_MeshObject.h"
39 #include "MT_CmMatrix4x4.h"
40 #include "RAS_IRenderTools.h" // rendering text
43 #include "GPU_material.h"
44 #include "GPU_extensions.h"
46 #include "DNA_image_types.h"
47 #include "DNA_meshdata_types.h"
48 #include "DNA_material_types.h"
49 #include "DNA_scene_types.h"
51 #include "BKE_DerivedMesh.h"
54 * 32x32 bit masks for vinterlace stereo mode
56 static GLuint left_eye_vinterlace_mask[32];
57 static GLuint right_eye_vinterlace_mask[32];
60 * 32x32 bit masks for hinterlace stereo mode.
61 * Left eye = &hinterlace_mask[0]
62 * Right eye = &hinterlace_mask[1]
64 static GLuint hinterlace_mask[33];
66 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
67 :RAS_IRasterizer(canvas),
71 m_campos(0.0f, 0.0f, 0.0f),
73 m_stereomode(RAS_STEREO_NOSTEREO),
74 m_curreye(RAS_STEREO_LEFTEYE),
77 m_setfocallength(false),
80 m_motionblurvalue(-1.0),
83 //m_last_blendmode(GPU_BLEND_SOLID),
84 m_last_frontface(true),
85 m_materialCachingInfo(0)
87 m_viewmatrix.setIdentity();
88 m_viewinvmatrix.setIdentity();
90 for (int i = 0; i < 32; i++)
92 left_eye_vinterlace_mask[i] = 0x55555555;
93 right_eye_vinterlace_mask[i] = 0xAAAAAAAA;
94 hinterlace_mask[i] = (i&1)*0xFFFFFFFF;
96 hinterlace_mask[32] = 0;
101 RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
105 bool RAS_OpenGLRasterizer::Init()
115 glDisable(GL_ALPHA_TEST);
116 //m_last_blendmode = GPU_BLEND_SOLID;
117 GPU_set_material_blend_mode(GPU_BLEND_SOLID);
120 m_last_frontface = true;
122 glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
123 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
124 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
128 m_greenback = 0.4375;
132 glShadeModel(GL_SMOOTH);
138 void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
146 void RAS_OpenGLRasterizer::SetAmbient(float factor)
148 float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
149 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
153 void RAS_OpenGLRasterizer::SetBackColor(float red,
166 void RAS_OpenGLRasterizer::SetFogColor(float r,
178 void RAS_OpenGLRasterizer::SetFogStart(float start)
186 void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
194 void RAS_OpenGLRasterizer::SetFog(float start,
210 void RAS_OpenGLRasterizer::DisableFog()
212 m_fogenabled = false;
215 bool RAS_OpenGLRasterizer::IsFogEnabled()
221 void RAS_OpenGLRasterizer::DisplayFog()
223 if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
226 glFogi(GL_FOG_MODE, GL_LINEAR);
227 glFogf(GL_FOG_DENSITY, 0.1f);
228 glFogf(GL_FOG_START, m_fogstart);
229 glFogf(GL_FOG_END, m_fogstart + m_fogdist);
234 glFogfv(GL_FOG_COLOR, params);
245 bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
247 return mat.Activate(this, m_materialCachingInfo);
252 void RAS_OpenGLRasterizer::Exit()
255 glEnable(GL_CULL_FACE);
256 glEnable(GL_DEPTH_TEST);
258 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
259 glClearColor(m_redback, m_greenback, m_blueback, m_alphaback);
260 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
261 glDepthMask (GL_TRUE);
262 glDepthFunc(GL_LEQUAL);
263 glBlendFunc(GL_ONE, GL_ZERO);
265 glDisable(GL_POLYGON_STIPPLE);
267 glDisable(GL_LIGHTING);
268 if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
269 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
274 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
277 m_drawingmode = drawingmode;
279 // Blender camera routine destroys the settings
280 if (m_drawingmode < KX_SOLID)
282 glDisable (GL_CULL_FACE);
283 glDisable (GL_DEPTH_TEST);
287 glEnable(GL_DEPTH_TEST);
288 glEnable (GL_CULL_FACE);
292 glDisable(GL_ALPHA_TEST);
293 //m_last_blendmode = GPU_BLEND_SOLID;
294 GPU_set_material_blend_mode(GPU_BLEND_SOLID);
297 m_last_frontface = true;
299 glShadeModel(GL_SMOOTH);
301 m_2DCanvas->BeginFrame();
308 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
310 m_drawingmode = drawingmode;
312 if(m_drawingmode == KX_WIREFRAME)
313 glDisable(GL_CULL_FACE);
316 int RAS_OpenGLRasterizer::GetDrawingMode()
318 return m_drawingmode;
322 void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask)
324 glDepthMask(depthmask == KX_DEPTHMASK_DISABLED ? GL_FALSE : GL_TRUE);
328 void RAS_OpenGLRasterizer::ClearColorBuffer()
330 m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
331 m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
335 void RAS_OpenGLRasterizer::ClearDepthBuffer()
337 m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
341 void RAS_OpenGLRasterizer::ClearCachingInfo(void)
343 m_materialCachingInfo = 0;
346 void RAS_OpenGLRasterizer::FlushDebugLines()
348 if(!m_debugLines.size())
352 GLboolean light, tex;
354 light= glIsEnabled(GL_LIGHTING);
355 tex= glIsEnabled(GL_TEXTURE_2D);
357 if(light) glDisable(GL_LIGHTING);
358 if(tex) glDisable(GL_TEXTURE_2D);
361 for (unsigned int i=0;i<m_debugLines.size();i++)
363 glColor4f(m_debugLines[i].m_color[0],m_debugLines[i].m_color[1],m_debugLines[i].m_color[2],1.f);
364 const MT_Scalar* fromPtr = &m_debugLines[i].m_from.x();
365 const MT_Scalar* toPtr= &m_debugLines[i].m_to.x();
367 glVertex3dv(fromPtr);
372 if(light) glEnable(GL_LIGHTING);
373 if(tex) glEnable(GL_TEXTURE_2D);
375 m_debugLines.clear();
378 void RAS_OpenGLRasterizer::EndFrame()
384 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
385 m_2DCanvas->EndFrame();
388 void RAS_OpenGLRasterizer::SetRenderArea()
391 // only above/below stereo method needs viewport adjustment
392 switch (m_stereomode)
394 case RAS_STEREO_ABOVEBELOW:
397 case RAS_STEREO_LEFTEYE:
398 // upper half of window
400 area.SetBottom(m_2DCanvas->GetHeight() -
401 int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
403 area.SetRight(int(m_2DCanvas->GetWidth()));
404 area.SetTop(int(m_2DCanvas->GetHeight()));
405 m_2DCanvas->SetDisplayArea(&area);
407 case RAS_STEREO_RIGHTEYE:
408 // lower half of window
411 area.SetRight(int(m_2DCanvas->GetWidth()));
412 area.SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
413 m_2DCanvas->SetDisplayArea(&area);
417 case RAS_STEREO_SIDEBYSIDE:
420 case RAS_STEREO_LEFTEYE:
421 // Left half of window
424 area.SetRight(m_2DCanvas->GetWidth()/2);
425 area.SetTop(m_2DCanvas->GetHeight());
426 m_2DCanvas->SetDisplayArea(&area);
428 case RAS_STEREO_RIGHTEYE:
429 // Right half of window
430 area.SetLeft(m_2DCanvas->GetWidth()/2);
432 area.SetRight(m_2DCanvas->GetWidth());
433 area.SetTop(m_2DCanvas->GetHeight());
434 m_2DCanvas->SetDisplayArea(&area);
439 // every available pixel
442 area.SetRight(int(m_2DCanvas->GetWidth()));
443 area.SetTop(int(m_2DCanvas->GetHeight()));
444 m_2DCanvas->SetDisplayArea(&area);
449 void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode)
451 m_stereomode = stereomode;
454 RAS_IRasterizer::StereoMode RAS_OpenGLRasterizer::GetStereoMode()
459 bool RAS_OpenGLRasterizer::Stereo()
461 if(m_stereomode > RAS_STEREO_NOSTEREO) // > 0
467 bool RAS_OpenGLRasterizer::InterlacedStereo()
469 return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
472 void RAS_OpenGLRasterizer::SetEye(const StereoEye eye)
475 switch (m_stereomode)
477 case RAS_STEREO_QUADBUFFERED:
478 glDrawBuffer(m_curreye == RAS_STEREO_LEFTEYE ? GL_BACK_LEFT : GL_BACK_RIGHT);
480 case RAS_STEREO_ANAGLYPH:
481 if (m_curreye == RAS_STEREO_LEFTEYE)
483 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
485 //glAccum(GL_LOAD, 1.0);
486 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
490 case RAS_STEREO_VINTERLACE:
492 glEnable(GL_POLYGON_STIPPLE);
493 glPolygonStipple((const GLubyte*) ((m_curreye == RAS_STEREO_LEFTEYE) ? left_eye_vinterlace_mask : right_eye_vinterlace_mask));
494 if (m_curreye == RAS_STEREO_RIGHTEYE)
498 case RAS_STEREO_INTERLACED:
500 glEnable(GL_POLYGON_STIPPLE);
501 glPolygonStipple((const GLubyte*) &hinterlace_mask[m_curreye == RAS_STEREO_LEFTEYE?0:1]);
502 if (m_curreye == RAS_STEREO_RIGHTEYE)
511 RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
517 void RAS_OpenGLRasterizer::SetEyeSeparation(const float eyeseparation)
519 m_eyeseparation = eyeseparation;
522 float RAS_OpenGLRasterizer::GetEyeSeparation()
524 return m_eyeseparation;
527 void RAS_OpenGLRasterizer::SetFocalLength(const float focallength)
529 m_focallength = focallength;
530 m_setfocallength = true;
533 float RAS_OpenGLRasterizer::GetFocalLength()
535 return m_focallength;
539 void RAS_OpenGLRasterizer::SwapBuffers()
541 m_2DCanvas->SwapBuffers();
546 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewMatrix() const
551 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewInvMatrix() const
553 return m_viewinvmatrix;
556 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
557 class RAS_IPolyMaterial* polymat,
558 class RAS_IRenderTools* rendertools)
560 bool obcolor = ms.m_bObjectColor;
561 MT_Vector4& rgba = ms.m_RGBAcolor;
562 RAS_MeshSlot::iterator it;
564 // handle object color
566 glDisableClientState(GL_COLOR_ARRAY);
567 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
570 glEnableClientState(GL_COLOR_ARRAY);
572 for(ms.begin(it); !ms.end(it); ms.next(it)) {
574 size_t i, j, numvert;
576 numvert = it.array->m_type;
578 if(it.array->m_type == RAS_DisplayArray::LINE) {
579 // line drawing, no text
582 for(i=0; i<it.totindex; i+=2)
584 vertex = &it.vertex[it.index[i]];
585 glVertex3fv(vertex->getXYZ());
587 vertex = &it.vertex[it.index[i+1]];
588 glVertex3fv(vertex->getXYZ());
594 // triangle and quad text drawing
595 for(i=0; i<it.totindex; i+=numvert)
600 for(j=0; j<numvert; j++) {
601 vertex = &it.vertex[it.index[i+j]];
603 v[j][0] = vertex->getXYZ()[0];
604 v[j][1] = vertex->getXYZ()[1];
605 v[j][2] = vertex->getXYZ()[2];
608 // find the right opengl attribute
610 if(GLEW_ARB_vertex_program)
611 for(unit=0; unit<m_attrib_num; unit++)
612 if(m_attrib[unit] == RAS_TEXCO_UV1)
615 rendertools->RenderText(polymat->GetDrawingMode(), polymat,
616 v[0], v[1], v[2], (numvert == 4)? v[3]: NULL, glattrib);
623 glDisableClientState(GL_COLOR_ARRAY);
626 void RAS_OpenGLRasterizer::SetTexCoordNum(int num)
629 if(m_texco_num > RAS_MAX_TEXCO)
630 m_texco_num = RAS_MAX_TEXCO;
633 void RAS_OpenGLRasterizer::SetAttribNum(int num)
636 if(m_attrib_num > RAS_MAX_ATTRIB)
637 m_attrib_num = RAS_MAX_ATTRIB;
640 void RAS_OpenGLRasterizer::SetTexCoord(TexCoGen coords, int unit)
642 // this changes from material to material
643 if(unit < RAS_MAX_TEXCO)
644 m_texco[unit] = coords;
647 void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit)
649 // this changes from material to material
650 if(unit < RAS_MAX_ATTRIB)
651 m_attrib[unit] = coords;
654 void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
658 if(GLEW_ARB_multitexture) {
659 for(unit=0; unit<m_texco_num; unit++) {
660 if(tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) {
661 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
664 switch(m_texco[unit]) {
667 glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
670 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
673 glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
676 glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
679 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
687 if(GLEW_ARB_vertex_program) {
688 for(unit=0; unit<m_attrib_num; unit++) {
689 switch(m_attrib[unit]) {
692 glVertexAttrib3fvARB(unit, tv.getXYZ());
695 glVertexAttrib2fvARB(unit, tv.getUV1());
698 glVertexAttrib3fvARB(unit, tv.getNormal());
701 glVertexAttrib4fvARB(unit, tv.getTangent());
704 glVertexAttrib2fvARB(unit, tv.getUV2());
707 glVertexAttrib4ubvARB(unit, tv.getRGBA());
717 void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
719 IndexPrimitivesInternal(ms, false);
722 void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
724 IndexPrimitivesInternal(ms, true);
727 static bool current_wireframe;
728 static RAS_MaterialBucket *current_bucket;
729 static RAS_IPolyMaterial *current_polymat;
730 static RAS_MeshSlot *current_ms;
731 static RAS_MeshObject *current_mesh;
732 static int current_blmat_nr;
733 static GPUVertexAttribs current_gpu_attribs;
734 static Image *current_image;
735 static int CheckMaterialDM(int matnr, void *attribs)
737 // only draw the current material
738 if (matnr != current_blmat_nr)
740 GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
742 memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs));
745 static int CheckTexfaceDM(void *mcol, int index)
748 // index is the original face index, retrieve the polygon
749 RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
750 current_mesh->GetPolygon(index) : NULL;
751 if (polygon && polygon->GetMaterial() == current_bucket) {
752 // must handle color.
753 if (current_wireframe)
755 if (current_ms->m_bObjectColor) {
756 MT_Vector4& rgba = current_ms->m_RGBAcolor;
757 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
762 // we have to set the color from the material
763 unsigned char rgba[4];
764 current_polymat->GetMaterialRGBAColor(rgba);
765 glColor4ubv((const GLubyte *)rgba);
773 static int CheckTexDM(MTFace *tface, MCol *mcol, int matnr)
776 // index is the original face index, retrieve the polygon
777 if (matnr == current_blmat_nr &&
778 (tface == NULL || tface->tpage == current_image)) {
779 // must handle color.
780 if (current_wireframe)
782 if (current_ms->m_bObjectColor) {
783 MT_Vector4& rgba = current_ms->m_RGBAcolor;
784 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
789 // we have to set the color from the material
790 unsigned char rgba[4];
791 current_polymat->GetMaterialRGBAColor(rgba);
792 glColor4ubv((const GLubyte *)rgba);
800 void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
802 bool obcolor = ms.m_bObjectColor;
803 bool wireframe = m_drawingmode <= KX_WIREFRAME;
804 MT_Vector4& rgba = ms.m_RGBAcolor;
805 RAS_MeshSlot::iterator it;
807 if (ms.m_pDerivedMesh) {
808 // mesh data is in derived mesh,
809 current_bucket = ms.m_bucket;
810 current_polymat = current_bucket->GetPolyMaterial();
812 current_mesh = ms.m_mesh;
813 current_wireframe = wireframe;
814 MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL);
817 if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_TWOSIDE)
818 this->SetCullFace(false);
820 this->SetCullFace(true);
822 if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
823 // GetMaterialIndex return the original mface material index,
824 // increment by 1 to match what derived mesh is doing
825 current_blmat_nr = current_polymat->GetMaterialIndex()+1;
826 // For GLSL we need to retrieve the GPU material attribute
827 Material* blmat = current_polymat->GetBlenderMaterial();
828 Scene* blscene = current_polymat->GetBlenderScene();
829 if (!wireframe && blscene && blmat)
830 GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs);
832 memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs));
833 // DM draw can mess up blending mode, restore at the end
834 int current_blend_mode = GPU_get_material_blend_mode();
835 ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
836 GPU_set_material_blend_mode(current_blend_mode);
838 //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
839 current_blmat_nr = current_polymat->GetMaterialIndex();
840 current_image = current_polymat->GetBlenderImage();
841 ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM);
845 // iterate over display arrays, each containing an index + vertex array
846 for(ms.begin(it); !ms.end(it); ms.next(it)) {
848 size_t i, j, numvert;
850 numvert = it.array->m_type;
852 if(it.array->m_type == RAS_DisplayArray::LINE) {
856 for(i=0; i<it.totindex; i+=2)
858 vertex = &it.vertex[it.index[i]];
859 glVertex3fv(vertex->getXYZ());
861 vertex = &it.vertex[it.index[i+1]];
862 glVertex3fv(vertex->getXYZ());
868 // triangle and quad drawing
869 if(it.array->m_type == RAS_DisplayArray::TRIANGLE)
870 glBegin(GL_TRIANGLES);
874 for(i=0; i<it.totindex; i+=numvert)
877 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
879 for(j=0; j<numvert; j++) {
880 vertex = &it.vertex[it.index[i+j]];
884 glColor4ubv((const GLubyte *)(vertex->getRGBA()));
886 glNormal3fv(vertex->getNormal());
891 glTexCoord2fv(vertex->getUV1());
894 glVertex3fv(vertex->getXYZ());
903 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
905 glMatrixMode(GL_PROJECTION);
906 double* matrix = &mat(0,0);
907 glLoadMatrixd(matrix);
909 m_camortho= (mat(3, 3) != 0.0f);
912 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
914 glMatrixMode(GL_PROJECTION);
916 /* Get into argument. Looks a bit dodgy, but it's ok. */
917 mat.getValue(matrix);
918 /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
919 glLoadMatrixd(matrix);
921 m_camortho= (mat[3][3] != 0.0f);
924 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
937 // correction for stereo
940 float near_div_focallength;
943 // if Rasterizer.setFocalLength is not called we use the camera focallength
944 if (!m_setfocallength)
945 // if focallength is null we use a value known to be reasonable
946 m_focallength = (focallength == 0.f) ? m_eyeseparation * 30.0
949 near_div_focallength = frustnear / m_focallength;
950 offset = 0.5 * m_eyeseparation * near_div_focallength;
953 case RAS_STEREO_LEFTEYE:
957 case RAS_STEREO_RIGHTEYE:
962 // leave bottom and top untouched
965 glMatrixMode(GL_PROJECTION);
967 glFrustum(left, right, bottom, top, frustnear, frustfar);
969 glGetDoublev(GL_PROJECTION_MATRIX, mat);
970 result.setValue(mat);
975 MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix(
986 // stereo is meaning less for orthographic, disable it
987 glMatrixMode(GL_PROJECTION);
989 glOrtho(left, right, bottom, top, frustnear, frustfar);
991 glGetDoublev(GL_PROJECTION_MATRIX, mat);
992 result.setValue(mat);
998 // next arguments probably contain redundant info, for later...
999 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat,
1000 const MT_Matrix3x3 & camOrientMat3x3,
1001 const MT_Point3 & pos,
1006 // correction for stereo
1007 if(Stereo() && perspective)
1009 MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention
1010 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
1011 MT_Vector3 viewDir, viewupVec;
1015 viewDir = camOrientMat3x3 * unitViewDir; // this is the moto convention, vector on right hand side
1016 // actual viewup vec
1017 viewupVec = camOrientMat3x3 * unitViewupVec;
1019 // vector between eyes
1020 eyeline = viewDir.cross(viewupVec);
1024 case RAS_STEREO_LEFTEYE:
1026 // translate to left by half the eye distance
1027 MT_Transform transform;
1028 transform.setIdentity();
1029 transform.translate(-(eyeline * m_eyeseparation / 2.0));
1030 m_viewmatrix *= transform;
1033 case RAS_STEREO_RIGHTEYE:
1035 // translate to right by half the eye distance
1036 MT_Transform transform;
1037 transform.setIdentity();
1038 transform.translate(eyeline * m_eyeseparation / 2.0);
1039 m_viewmatrix *= transform;
1045 m_viewinvmatrix = m_viewmatrix;
1046 m_viewinvmatrix.invert();
1048 // note: getValue gives back column major as needed by OpenGL
1049 MT_Scalar glviewmat[16];
1050 m_viewmatrix.getValue(glviewmat);
1052 glMatrixMode(GL_MODELVIEW);
1053 glLoadMatrixd(glviewmat);
1058 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
1063 bool RAS_OpenGLRasterizer::GetCameraOrtho()
1068 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
1071 glEnable(GL_CULL_FACE);
1073 glDisable(GL_CULL_FACE);
1076 void RAS_OpenGLRasterizer::SetLines(bool enable)
1079 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1081 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1084 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
1089 GLfloat mat_specular[] = {specX, specY, specZ, specval};
1090 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
1095 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
1097 GLfloat mat_shininess[] = { shiny };
1098 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
1103 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
1105 GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
1106 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
1109 void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e)
1111 GLfloat mat_emit [] = {eX,eY,eZ,e};
1112 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit);
1116 double RAS_OpenGLRasterizer::GetTime()
1121 void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
1123 glPolygonOffset(mult, add);
1124 GLint mode = GL_POLYGON_OFFSET_FILL;
1125 if (m_drawingmode < KX_SHADED)
1126 mode = GL_POLYGON_OFFSET_LINE;
1127 if (mult != 0.0f || add != 0.0f)
1133 void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue)
1135 /* don't just set m_motionblur to 1, but check if it is 0 so
1136 * we don't reset a motion blur that is already enabled */
1137 if(m_motionblur == 0)
1139 m_motionblurvalue = motionblurvalue;
1142 void RAS_OpenGLRasterizer::DisableMotionBlur()
1145 m_motionblurvalue = -1.0;
1148 void RAS_OpenGLRasterizer::SetBlendingMode(int blendmode)
1150 GPU_set_material_blend_mode(blendmode);
1152 if(blendmode == m_last_blendmode)
1155 if(blendmode == GPU_BLEND_SOLID) {
1156 glDisable(GL_BLEND);
1157 glDisable(GL_ALPHA_TEST);
1158 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1160 else if(blendmode == GPU_BLEND_ADD) {
1161 glBlendFunc(GL_ONE, GL_ONE);
1163 glDisable(GL_ALPHA_TEST);
1165 else if(blendmode == GPU_BLEND_ALPHA) {
1166 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1168 glEnable(GL_ALPHA_TEST);
1169 glAlphaFunc(GL_GREATER, 0.0f);
1171 else if(blendmode == GPU_BLEND_CLIP) {
1172 glDisable(GL_BLEND);
1173 glEnable(GL_ALPHA_TEST);
1174 glAlphaFunc(GL_GREATER, 0.5f);
1177 m_last_blendmode = blendmode;
1181 void RAS_OpenGLRasterizer::SetFrontFace(bool ccw)
1183 if(m_last_frontface == ccw)
1187 glFrontFace(GL_CCW);
1191 m_last_frontface = ccw;