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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "MT_CmMatrix4x4.h"
39 #include "RAS_IRenderTools.h" // rendering text
42 #include "GPU_material.h"
45 * 32x32 bit masks for vinterlace stereo mode
47 static GLuint left_eye_vinterlace_mask[32];
48 static GLuint right_eye_vinterlace_mask[32];
51 * 32x32 bit masks for hinterlace stereo mode.
52 * Left eye = &hinterlace_mask[0]
53 * Right eye = &hinterlace_mask[1]
55 static GLuint hinterlace_mask[33];
57 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
58 :RAS_IRasterizer(canvas),
62 m_campos(0.0f, 0.0f, 0.0f),
64 m_stereomode(RAS_STEREO_NOSTEREO),
65 m_curreye(RAS_STEREO_LEFTEYE),
69 m_setfocallength(false),
72 m_motionblurvalue(-1.0),
75 m_last_blendmode(GPU_BLEND_SOLID),
76 m_last_frontface(true),
77 m_materialCachingInfo(0)
79 m_viewmatrix.setIdentity();
80 m_viewinvmatrix.setIdentity();
82 for (int i = 0; i < 32; i++)
84 left_eye_vinterlace_mask[i] = 0x55555555;
85 right_eye_vinterlace_mask[i] = 0xAAAAAAAA;
86 hinterlace_mask[i] = (i&1)*0xFFFFFFFF;
88 hinterlace_mask[32] = 0;
93 RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
97 bool RAS_OpenGLRasterizer::Init()
102 m_greenback = 0.4375;
111 glDisable(GL_ALPHA_TEST);
112 m_last_blendmode = GPU_BLEND_SOLID;
115 m_last_frontface = true;
117 glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
118 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
119 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
121 glShadeModel(GL_SMOOTH);
127 void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
135 void RAS_OpenGLRasterizer::SetAmbient(float factor)
137 float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
138 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
142 void RAS_OpenGLRasterizer::SetBackColor(float red,
155 void RAS_OpenGLRasterizer::SetFogColor(float r,
167 void RAS_OpenGLRasterizer::SetFogStart(float start)
175 void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
183 void RAS_OpenGLRasterizer::SetFog(float start,
199 void RAS_OpenGLRasterizer::DisableFog()
201 m_fogenabled = false;
206 void RAS_OpenGLRasterizer::DisplayFog()
208 if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
211 glFogi(GL_FOG_MODE, GL_LINEAR);
212 glFogf(GL_FOG_DENSITY, 0.1f);
213 glFogf(GL_FOG_START, m_fogstart);
214 glFogf(GL_FOG_END, m_fogstart + m_fogdist);
219 glFogfv(GL_FOG_COLOR, params);
230 bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
232 return mat.Activate(this, m_materialCachingInfo);
237 void RAS_OpenGLRasterizer::Exit()
240 glEnable(GL_CULL_FACE);
241 glEnable(GL_DEPTH_TEST);
243 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
244 glClearColor(m_redback, m_greenback, m_blueback, m_alphaback);
245 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
246 glDepthMask (GL_TRUE);
247 glDepthFunc(GL_LEQUAL);
248 glBlendFunc(GL_ONE, GL_ZERO);
250 glDisable(GL_POLYGON_STIPPLE);
252 glDisable(GL_LIGHTING);
253 if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
254 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
259 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
262 m_drawingmode = drawingmode;
264 // Blender camera routine destroys the settings
265 if (m_drawingmode < KX_SOLID)
267 glDisable (GL_CULL_FACE);
268 glDisable (GL_DEPTH_TEST);
272 glEnable(GL_DEPTH_TEST);
273 glEnable (GL_CULL_FACE);
277 glDisable(GL_ALPHA_TEST);
278 m_last_blendmode = GPU_BLEND_SOLID;
281 m_last_frontface = true;
283 glShadeModel(GL_SMOOTH);
285 m_2DCanvas->BeginFrame();
292 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
294 m_drawingmode = drawingmode;
296 if(m_drawingmode == KX_WIREFRAME)
297 glDisable(GL_CULL_FACE);
300 int RAS_OpenGLRasterizer::GetDrawingMode()
302 return m_drawingmode;
306 void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask)
308 glDepthMask(depthmask == KX_DEPTHMASK_DISABLED ? GL_FALSE : GL_TRUE);
312 void RAS_OpenGLRasterizer::ClearColorBuffer()
314 m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
315 m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
319 void RAS_OpenGLRasterizer::ClearDepthBuffer()
321 m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER);
325 void RAS_OpenGLRasterizer::ClearCachingInfo(void)
327 m_materialCachingInfo = 0;
330 void RAS_OpenGLRasterizer::FlushDebugLines()
332 if(!m_debugLines.size())
336 GLboolean light, tex;
338 light= glIsEnabled(GL_LIGHTING);
339 tex= glIsEnabled(GL_TEXTURE_2D);
341 if(light) glDisable(GL_LIGHTING);
342 if(tex) glDisable(GL_TEXTURE_2D);
345 for (unsigned int i=0;i<m_debugLines.size();i++)
347 glColor4f(m_debugLines[i].m_color[0],m_debugLines[i].m_color[1],m_debugLines[i].m_color[2],1.f);
348 const MT_Scalar* fromPtr = &m_debugLines[i].m_from.x();
349 const MT_Scalar* toPtr= &m_debugLines[i].m_to.x();
351 glVertex3dv(fromPtr);
356 if(light) glEnable(GL_LIGHTING);
357 if(tex) glEnable(GL_TEXTURE_2D);
359 m_debugLines.clear();
362 void RAS_OpenGLRasterizer::EndFrame()
368 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
369 m_2DCanvas->EndFrame();
372 void RAS_OpenGLRasterizer::SetRenderArea()
374 // only above/below stereo method needs viewport adjustment
375 switch (m_stereomode)
377 case RAS_STEREO_ABOVEBELOW:
380 case RAS_STEREO_LEFTEYE:
381 // upper half of window
382 m_2DCanvas->GetDisplayArea().SetLeft(0);
383 m_2DCanvas->GetDisplayArea().SetBottom(m_2DCanvas->GetHeight() -
384 int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
386 m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
387 m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
389 case RAS_STEREO_RIGHTEYE:
390 // lower half of window
391 m_2DCanvas->GetDisplayArea().SetLeft(0);
392 m_2DCanvas->GetDisplayArea().SetBottom(0);
393 m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
394 m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2);
398 case RAS_STEREO_SIDEBYSIDE:
401 case RAS_STEREO_LEFTEYE:
402 // Left half of window
403 m_2DCanvas->GetDisplayArea().SetLeft(0);
404 m_2DCanvas->GetDisplayArea().SetBottom(0);
405 m_2DCanvas->GetDisplayArea().SetRight(m_2DCanvas->GetWidth()/2);
406 m_2DCanvas->GetDisplayArea().SetTop(m_2DCanvas->GetHeight());
408 case RAS_STEREO_RIGHTEYE:
409 // Right half of window
410 m_2DCanvas->GetDisplayArea().SetLeft(m_2DCanvas->GetWidth()/2);
411 m_2DCanvas->GetDisplayArea().SetBottom(0);
412 m_2DCanvas->GetDisplayArea().SetRight(m_2DCanvas->GetWidth());
413 m_2DCanvas->GetDisplayArea().SetTop(m_2DCanvas->GetHeight());
418 // every available pixel
419 m_2DCanvas->GetDisplayArea().SetLeft(0);
420 m_2DCanvas->GetDisplayArea().SetBottom(0);
421 m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth()));
422 m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight()));
427 void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode)
429 m_stereomode = stereomode;
432 RAS_IRasterizer::StereoMode RAS_OpenGLRasterizer::GetStereoMode()
437 bool RAS_OpenGLRasterizer::Stereo()
439 if(m_stereomode == RAS_STEREO_NOSTEREO || m_stereomode == RAS_STEREO_DOME)
445 bool RAS_OpenGLRasterizer::InterlacedStereo()
447 return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
450 void RAS_OpenGLRasterizer::SetEye(const StereoEye eye)
453 switch (m_stereomode)
455 case RAS_STEREO_QUADBUFFERED:
456 glDrawBuffer(m_curreye == RAS_STEREO_LEFTEYE ? GL_BACK_LEFT : GL_BACK_RIGHT);
458 case RAS_STEREO_ANAGLYPH:
459 if (m_curreye == RAS_STEREO_LEFTEYE)
461 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
463 //glAccum(GL_LOAD, 1.0);
464 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
468 case RAS_STEREO_VINTERLACE:
470 glEnable(GL_POLYGON_STIPPLE);
471 glPolygonStipple((const GLubyte*) ((m_curreye == RAS_STEREO_LEFTEYE) ? left_eye_vinterlace_mask : right_eye_vinterlace_mask));
472 if (m_curreye == RAS_STEREO_RIGHTEYE)
476 case RAS_STEREO_INTERLACED:
478 glEnable(GL_POLYGON_STIPPLE);
479 glPolygonStipple((const GLubyte*) &hinterlace_mask[m_curreye == RAS_STEREO_LEFTEYE?0:1]);
480 if (m_curreye == RAS_STEREO_RIGHTEYE)
489 RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
495 void RAS_OpenGLRasterizer::SetEyeSeparation(const float eyeseparation)
497 m_eyeseparation = eyeseparation;
501 float RAS_OpenGLRasterizer::GetEyeSeparation()
503 return m_eyeseparation;
506 void RAS_OpenGLRasterizer::SetFocalLength(const float focallength)
508 m_focallength = focallength;
509 m_setfocallength = true;
512 float RAS_OpenGLRasterizer::GetFocalLength()
514 return m_focallength;
518 void RAS_OpenGLRasterizer::SwapBuffers()
520 m_2DCanvas->SwapBuffers();
525 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewMatrix() const
530 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewInvMatrix() const
532 return m_viewinvmatrix;
535 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms,
536 class RAS_IPolyMaterial* polymat,
537 class RAS_IRenderTools* rendertools)
539 bool obcolor = ms.m_bObjectColor;
540 MT_Vector4& rgba = ms.m_RGBAcolor;
541 RAS_MeshSlot::iterator it;
543 // handle object color
545 glDisableClientState(GL_COLOR_ARRAY);
546 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
549 glEnableClientState(GL_COLOR_ARRAY);
551 for(ms.begin(it); !ms.end(it); ms.next(it)) {
553 size_t i, j, numvert;
555 numvert = it.array->m_type;
557 if(it.array->m_type == RAS_DisplayArray::LINE) {
558 // line drawing, no text
561 for(i=0; i<it.totindex; i+=2)
563 vertex = &it.vertex[it.index[i]];
564 glVertex3fv(vertex->getXYZ());
566 vertex = &it.vertex[it.index[i+1]];
567 glVertex3fv(vertex->getXYZ());
573 // triangle and quad text drawing
574 for(i=0; i<it.totindex; i+=numvert)
579 for(j=0; j<numvert; j++) {
580 vertex = &it.vertex[it.index[i+j]];
582 v[j][0] = vertex->getXYZ()[0];
583 v[j][1] = vertex->getXYZ()[1];
584 v[j][2] = vertex->getXYZ()[2];
587 // find the right opengl attribute
589 if(GLEW_ARB_vertex_program)
590 for(unit=0; unit<m_attrib_num; unit++)
591 if(m_attrib[unit] == RAS_TEXCO_UV1)
594 rendertools->RenderText(polymat->GetDrawingMode(), polymat,
595 v[0], v[1], v[2], (numvert == 4)? v[3]: NULL, glattrib);
602 glDisableClientState(GL_COLOR_ARRAY);
605 void RAS_OpenGLRasterizer::SetTexCoordNum(int num)
608 if(m_texco_num > RAS_MAX_TEXCO)
609 m_texco_num = RAS_MAX_TEXCO;
612 void RAS_OpenGLRasterizer::SetAttribNum(int num)
615 if(m_attrib_num > RAS_MAX_ATTRIB)
616 m_attrib_num = RAS_MAX_ATTRIB;
619 void RAS_OpenGLRasterizer::SetTexCoord(TexCoGen coords, int unit)
621 // this changes from material to material
622 if(unit < RAS_MAX_TEXCO)
623 m_texco[unit] = coords;
626 void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit)
628 // this changes from material to material
629 if(unit < RAS_MAX_ATTRIB)
630 m_attrib[unit] = coords;
633 void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
637 if(GLEW_ARB_multitexture) {
638 for(unit=0; unit<m_texco_num; unit++) {
639 if(tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) {
640 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
643 switch(m_texco[unit]) {
646 glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ());
649 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1());
652 glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal());
655 glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent());
658 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2());
666 if(GLEW_ARB_vertex_program) {
667 for(unit=0; unit<m_attrib_num; unit++) {
668 switch(m_attrib[unit]) {
671 glVertexAttrib3fvARB(unit, tv.getXYZ());
674 glVertexAttrib2fvARB(unit, tv.getUV1());
677 glVertexAttrib3fvARB(unit, tv.getNormal());
680 glVertexAttrib4fvARB(unit, tv.getTangent());
683 glVertexAttrib2fvARB(unit, tv.getUV2());
686 glVertexAttrib4ubvARB(unit, tv.getRGBA());
696 void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
698 IndexPrimitivesInternal(ms, false);
701 void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
703 IndexPrimitivesInternal(ms, true);
706 void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
708 bool obcolor = ms.m_bObjectColor;
709 bool wireframe = m_drawingmode <= KX_WIREFRAME;
710 MT_Vector4& rgba = ms.m_RGBAcolor;
711 RAS_MeshSlot::iterator it;
713 // iterate over display arrays, each containing an index + vertex array
714 for(ms.begin(it); !ms.end(it); ms.next(it)) {
716 size_t i, j, numvert;
718 numvert = it.array->m_type;
720 if(it.array->m_type == RAS_DisplayArray::LINE) {
724 for(i=0; i<it.totindex; i+=2)
726 vertex = &it.vertex[it.index[i]];
727 glVertex3fv(vertex->getXYZ());
729 vertex = &it.vertex[it.index[i+1]];
730 glVertex3fv(vertex->getXYZ());
736 // triangle and quad drawing
737 if(it.array->m_type == RAS_DisplayArray::TRIANGLE)
738 glBegin(GL_TRIANGLES);
742 for(i=0; i<it.totindex; i+=numvert)
745 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
747 for(j=0; j<numvert; j++) {
748 vertex = &it.vertex[it.index[i+j]];
752 glColor4ubv((const GLubyte *)(vertex->getRGBA()));
754 glNormal3fv(vertex->getNormal());
759 glTexCoord2fv(vertex->getUV1());
762 glVertex3fv(vertex->getXYZ());
771 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
773 glMatrixMode(GL_PROJECTION);
774 double* matrix = &mat(0,0);
775 glLoadMatrixd(matrix);
777 m_camortho= (mat(3, 3) != 0.0f);
780 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
782 glMatrixMode(GL_PROJECTION);
784 /* Get into argument. Looks a bit dodgy, but it's ok. */
785 mat.getValue(matrix);
786 /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
787 glLoadMatrixd(matrix);
789 m_camortho= (mat[3][3] != 0.0f);
792 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
805 // correction for stereo
808 float near_div_focallength;
809 // next 2 params should be specified on command line and in Blender publisher
810 if (!m_setfocallength)
811 m_focallength = (focallength == 0.f) ? 1.5 * right // derived from example
814 m_eyeseparation = m_focallength/30; // reasonable value...
816 near_div_focallength = frustnear / m_focallength;
819 case RAS_STEREO_LEFTEYE:
820 left += 0.5 * m_eyeseparation * near_div_focallength;
821 right += 0.5 * m_eyeseparation * near_div_focallength;
823 case RAS_STEREO_RIGHTEYE:
824 left -= 0.5 * m_eyeseparation * near_div_focallength;
825 right -= 0.5 * m_eyeseparation * near_div_focallength;
828 // leave bottom, top, bottom and top untouched
831 glMatrixMode(GL_PROJECTION);
833 glFrustum(left, right, bottom, top, frustnear, frustfar);
835 glGetDoublev(GL_PROJECTION_MATRIX, mat);
836 result.setValue(mat);
842 // next arguments probably contain redundant info, for later...
843 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
844 const MT_Point3 &, const MT_Quaternion &camOrientQuat)
848 // correction for stereo
851 MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
852 MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention
853 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
854 MT_Vector3 viewDir, viewupVec;
858 viewDir = camOrientMat3x3 * unitViewDir; // this is the moto convention, vector on right hand side
860 viewupVec = camOrientMat3x3 * unitViewupVec;
862 // vector between eyes
863 eyeline = viewDir.cross(viewupVec);
867 case RAS_STEREO_LEFTEYE:
869 // translate to left by half the eye distance
870 MT_Transform transform;
871 transform.setIdentity();
872 transform.translate(-(eyeline * m_eyeseparation / 2.0));
873 m_viewmatrix *= transform;
876 case RAS_STEREO_RIGHTEYE:
878 // translate to right by half the eye distance
879 MT_Transform transform;
880 transform.setIdentity();
881 transform.translate(eyeline * m_eyeseparation / 2.0);
882 m_viewmatrix *= transform;
888 m_viewinvmatrix = m_viewmatrix;
889 m_viewinvmatrix.invert();
891 // note: getValue gives back column major as needed by OpenGL
892 MT_Scalar glviewmat[16];
893 m_viewmatrix.getValue(glviewmat);
895 glMatrixMode(GL_MODELVIEW);
896 glLoadMatrixd(glviewmat);
901 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
906 bool RAS_OpenGLRasterizer::GetCameraOrtho()
911 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
914 glEnable(GL_CULL_FACE);
916 glDisable(GL_CULL_FACE);
919 void RAS_OpenGLRasterizer::SetLines(bool enable)
922 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
924 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
927 void RAS_OpenGLRasterizer::SetSpecularity(float specX,
932 GLfloat mat_specular[] = {specX, specY, specZ, specval};
933 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
938 void RAS_OpenGLRasterizer::SetShinyness(float shiny)
940 GLfloat mat_shininess[] = { shiny };
941 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
946 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse)
948 GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse};
949 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
952 void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e)
954 GLfloat mat_emit [] = {eX,eY,eZ,e};
955 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit);
959 double RAS_OpenGLRasterizer::GetTime()
964 void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
966 glPolygonOffset(mult, add);
967 GLint mode = GL_POLYGON_OFFSET_FILL;
968 if (m_drawingmode < KX_SHADED)
969 mode = GL_POLYGON_OFFSET_LINE;
970 if (mult != 0.0f || add != 0.0f)
976 void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue)
978 /* don't just set m_motionblur to 1, but check if it is 0 so
979 * we don't reset a motion blur that is already enabled */
980 if(m_motionblur == 0)
982 m_motionblurvalue = motionblurvalue;
985 void RAS_OpenGLRasterizer::DisableMotionBlur()
988 m_motionblurvalue = -1.0;
991 void RAS_OpenGLRasterizer::SetBlendingMode(int blendmode)
993 if(blendmode == m_last_blendmode)
996 if(blendmode == GPU_BLEND_SOLID) {
998 glDisable(GL_ALPHA_TEST);
999 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1001 else if(blendmode == GPU_BLEND_ADD) {
1002 glBlendFunc(GL_ONE, GL_ONE);
1004 glDisable(GL_ALPHA_TEST);
1006 else if(blendmode == GPU_BLEND_ALPHA) {
1007 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1009 glEnable(GL_ALPHA_TEST);
1010 glAlphaFunc(GL_GREATER, 0.0f);
1012 else if(blendmode == GPU_BLEND_CLIP) {
1013 glDisable(GL_BLEND);
1014 glEnable(GL_ALPHA_TEST);
1015 glAlphaFunc(GL_GREATER, 0.5f);
1018 m_last_blendmode = blendmode;
1021 void RAS_OpenGLRasterizer::SetFrontFace(bool ccw)
1023 if(m_last_frontface == ccw)
1027 glFrontFace(GL_CCW);
1031 m_last_frontface = ccw;