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));
747 static int CheckTexfaceDM(void *mcol, int index)
750 // index is the original face index, retrieve the polygon
751 RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
752 current_mesh->GetPolygon(index) : NULL;
753 if (polygon && polygon->GetMaterial() == current_bucket) {
754 // must handle color.
755 if (current_wireframe)
757 if (current_ms->m_bObjectColor) {
758 MT_Vector4& rgba = current_ms->m_RGBAcolor;
759 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
764 // we have to set the color from the material
765 unsigned char rgba[4];
766 current_polymat->GetMaterialRGBAColor(rgba);
767 glColor4ubv((const GLubyte *)rgba);
776 static int CheckTexDM(MTFace *tface, MCol *mcol, int matnr)
779 // index is the original face index, retrieve the polygon
780 if (matnr == current_blmat_nr &&
781 (tface == NULL || tface->tpage == current_image)) {
782 // must handle color.
783 if (current_wireframe)
785 if (current_ms->m_bObjectColor) {
786 MT_Vector4& rgba = current_ms->m_RGBAcolor;
787 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
792 // we have to set the color from the material
793 unsigned char rgba[4];
794 current_polymat->GetMaterialRGBAColor(rgba);
795 glColor4ubv((const GLubyte *)rgba);
803 void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
805 bool obcolor = ms.m_bObjectColor;
806 bool wireframe = m_drawingmode <= KX_WIREFRAME;
807 MT_Vector4& rgba = ms.m_RGBAcolor;
808 RAS_MeshSlot::iterator it;
810 if (ms.m_pDerivedMesh) {
811 // mesh data is in derived mesh,
812 current_bucket = ms.m_bucket;
813 current_polymat = current_bucket->GetPolyMaterial();
815 current_mesh = ms.m_mesh;
816 current_wireframe = wireframe;
817 // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */
820 if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_TWOSIDE)
821 this->SetCullFace(false);
823 this->SetCullFace(true);
825 if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
826 // GetMaterialIndex return the original mface material index,
827 // increment by 1 to match what derived mesh is doing
828 current_blmat_nr = current_polymat->GetMaterialIndex()+1;
829 // For GLSL we need to retrieve the GPU material attribute
830 Material* blmat = current_polymat->GetBlenderMaterial();
831 Scene* blscene = current_polymat->GetBlenderScene();
832 if (!wireframe && blscene && blmat)
833 GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs);
835 memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs));
836 // DM draw can mess up blending mode, restore at the end
837 int current_blend_mode = GPU_get_material_blend_mode();
838 ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
839 GPU_set_material_blend_mode(current_blend_mode);
841 //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
842 current_blmat_nr = current_polymat->GetMaterialIndex();
843 current_image = current_polymat->GetBlenderImage();
844 ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM);
848 // iterate over display arrays, each containing an index + vertex array
849 for(ms.begin(it); !ms.end(it); ms.next(it)) {
851 size_t i, j, numvert;
853 numvert = it.array->m_type;
855 if(it.array->m_type == RAS_DisplayArray::LINE) {
859 for(i=0; i<it.totindex; i+=2)
861 vertex = &it.vertex[it.index[i]];
862 glVertex3fv(vertex->getXYZ());
864 vertex = &it.vertex[it.index[i+1]];
865 glVertex3fv(vertex->getXYZ());
871 // triangle and quad drawing
872 if(it.array->m_type == RAS_DisplayArray::TRIANGLE)
873 glBegin(GL_TRIANGLES);
877 for(i=0; i<it.totindex; i+=numvert)
880 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
882 for(j=0; j<numvert; j++) {
883 vertex = &it.vertex[it.index[i+j]];
887 glColor4ubv((const GLubyte *)(vertex->getRGBA()));
889 glNormal3fv(vertex->getNormal());
894 glTexCoord2fv(vertex->getUV1());
897 glVertex3fv(vertex->getXYZ());
906 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
908 glMatrixMode(GL_PROJECTION);
909 double* matrix = &mat(0,0);
910 glLoadMatrixd(matrix);
912 m_camortho= (mat(3, 3) != 0.0f);
915 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
917 glMatrixMode(GL_PROJECTION);
919 /* Get into argument. Looks a bit dodgy, but it's ok. */
920 mat.getValue(matrix);
921 /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
922 glLoadMatrixd(matrix);
924 m_camortho= (mat[3][3] != 0.0f);
927 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
940 // correction for stereo
943 float near_div_focallength;
946 // if Rasterizer.setFocalLength is not called we use the camera focallength
947 if (!m_setfocallength)
948 // if focallength is null we use a value known to be reasonable
949 m_focallength = (focallength == 0.f) ? m_eyeseparation * 30.0
952 near_div_focallength = frustnear / m_focallength;
953 offset = 0.5 * m_eyeseparation * near_div_focallength;
956 case RAS_STEREO_LEFTEYE:
960 case RAS_STEREO_RIGHTEYE:
965 // leave bottom and top untouched
968 glMatrixMode(GL_PROJECTION);
970 glFrustum(left, right, bottom, top, frustnear, frustfar);
972 glGetDoublev(GL_PROJECTION_MATRIX, mat);
973 result.setValue(mat);
978 MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix(
989 // stereo is meaning less for orthographic, disable it
990 glMatrixMode(GL_PROJECTION);
992 glOrtho(left, right, bottom, top, frustnear, frustfar);
994 glGetDoublev(GL_PROJECTION_MATRIX, mat);
995 result.setValue(mat);
1001 // next arguments probably contain redundant info, for later...
1002 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat,
1003 const MT_Matrix3x3 & camOrientMat3x3,
1004 const MT_Point3 & pos,
1009 // correction for stereo
1010 if(Stereo() && perspective)
1012 MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention
1013 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
1014 MT_Vector3 viewDir, viewupVec;
1018 viewDir = camOrientMat3x3 * unitViewDir; // this is the moto convention, vector on right hand side
1019 // actual viewup vec
1020 viewupVec = camOrientMat3x3 * unitViewupVec;
1022 // vector between eyes
1023 eyeline = viewDir.cross(viewupVec);
1027 case RAS_STEREO_LEFTEYE:
1029 // translate to left by half the eye distance
1030 MT_Transform transform;
1031 transform.setIdentity();
1032 transform.translate(-(eyeline * m_eyeseparation / 2.0));
1033 m_viewmatrix *= transform;
1036 case RAS_STEREO_RIGHTEYE:
1038 // translate to right by half the eye distance
1039 MT_Transform transform;
1040 transform.setIdentity();
1041 transform.translate(eyeline * m_eyeseparation / 2.0);
1042 m_viewmatrix *= transform;
1048 m_viewinvmatrix = m_viewmatrix;
1049 m_viewinvmatrix.invert();
1051 // note: getValue gives back column major as needed by OpenGL
1052 MT_Scalar glviewmat[16];
1053 m_viewmatrix.getValue(glviewmat);
1055 glMatrixMode(GL_MODELVIEW);
1056 glLoadMatrixd(glviewmat);
1061 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
1066 bool RAS_OpenGLRasterizer::GetCameraOrtho()
1071 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
1074 glEnable(GL_CULL_FACE);
1076 glDisable(GL_CULL_FACE);
1079 void RAS_OpenGLRasterizer::SetLines(bool enable)
1082 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1084 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1087 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
1092 GLfloat mat_specular[] = {specX, specY, specZ, specval};
1093 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
1098 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
1100 GLfloat mat_shininess[] = { shiny };
1101 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
1106 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
1108 GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
1109 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
1112 void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e)
1114 GLfloat mat_emit [] = {eX,eY,eZ,e};
1115 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit);
1119 double RAS_OpenGLRasterizer::GetTime()
1124 void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
1126 glPolygonOffset(mult, add);
1127 GLint mode = GL_POLYGON_OFFSET_FILL;
1128 if (m_drawingmode < KX_SHADED)
1129 mode = GL_POLYGON_OFFSET_LINE;
1130 if (mult != 0.0f || add != 0.0f)
1136 void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue)
1138 /* don't just set m_motionblur to 1, but check if it is 0 so
1139 * we don't reset a motion blur that is already enabled */
1140 if(m_motionblur == 0)
1142 m_motionblurvalue = motionblurvalue;
1145 void RAS_OpenGLRasterizer::DisableMotionBlur()
1148 m_motionblurvalue = -1.0;
1151 void RAS_OpenGLRasterizer::SetBlendingMode(int blendmode)
1153 GPU_set_material_blend_mode(blendmode);
1155 if(blendmode == m_last_blendmode)
1158 if(blendmode == GPU_BLEND_SOLID) {
1159 glDisable(GL_BLEND);
1160 glDisable(GL_ALPHA_TEST);
1161 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1163 else if(blendmode == GPU_BLEND_ADD) {
1164 glBlendFunc(GL_ONE, GL_ONE);
1166 glDisable(GL_ALPHA_TEST);
1168 else if(blendmode == GPU_BLEND_ALPHA) {
1169 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1171 glEnable(GL_ALPHA_TEST);
1172 glAlphaFunc(GL_GREATER, 0.0f);
1174 else if(blendmode == GPU_BLEND_CLIP) {
1175 glDisable(GL_BLEND);
1176 glEnable(GL_ALPHA_TEST);
1177 glAlphaFunc(GL_GREATER, 0.5f);
1180 m_last_blendmode = blendmode;
1184 void RAS_OpenGLRasterizer::SetFrontFace(bool ccw)
1186 if(m_last_frontface == ccw)
1190 glFrontFace(GL_CCW);
1194 m_last_frontface = ccw;