Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <math.h> 00034 #include <stdlib.h> 00035 00036 #include "RAS_OpenGLRasterizer.h" 00037 00038 #include "GL/glew.h" 00039 00040 #include "RAS_Rect.h" 00041 #include "RAS_TexVert.h" 00042 #include "RAS_MeshObject.h" 00043 #include "MT_CmMatrix4x4.h" 00044 #include "RAS_IRenderTools.h" // rendering text 00045 00046 #include "GPU_draw.h" 00047 #include "GPU_material.h" 00048 #include "GPU_extensions.h" 00049 00050 #include "DNA_image_types.h" 00051 #include "DNA_meshdata_types.h" 00052 #include "DNA_material_types.h" 00053 #include "DNA_scene_types.h" 00054 00055 #include "BKE_DerivedMesh.h" 00056 00057 #ifndef M_PI 00058 #define M_PI 3.14159265358979323846 00059 #endif 00060 00064 static GLuint left_eye_vinterlace_mask[32]; 00065 static GLuint right_eye_vinterlace_mask[32]; 00066 00072 static GLuint hinterlace_mask[33]; 00073 00074 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) 00075 :RAS_IRasterizer(canvas), 00076 m_2DCanvas(canvas), 00077 m_fogenabled(false), 00078 m_time(0.0), 00079 m_campos(0.0f, 0.0f, 0.0f), 00080 m_camortho(false), 00081 m_stereomode(RAS_STEREO_NOSTEREO), 00082 m_curreye(RAS_STEREO_LEFTEYE), 00083 m_eyeseparation(0.0), 00084 m_focallength(0.0), 00085 m_setfocallength(false), 00086 m_noOfScanlines(32), 00087 m_motionblur(0), 00088 m_motionblurvalue(-1.0), 00089 m_texco_num(0), 00090 m_attrib_num(0), 00091 //m_last_alphablend(GPU_BLEND_SOLID), 00092 m_last_frontface(true), 00093 m_materialCachingInfo(0) 00094 { 00095 m_viewmatrix.setIdentity(); 00096 m_viewinvmatrix.setIdentity(); 00097 00098 for (int i = 0; i < 32; i++) 00099 { 00100 left_eye_vinterlace_mask[i] = 0x55555555; 00101 right_eye_vinterlace_mask[i] = 0xAAAAAAAA; 00102 hinterlace_mask[i] = (i&1)*0xFFFFFFFF; 00103 } 00104 hinterlace_mask[32] = 0; 00105 00106 m_prevafvalue = GPU_get_anisotropic(); 00107 } 00108 00109 00110 00111 RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer() 00112 { 00113 // Restore the previous AF value 00114 GPU_set_anisotropic(m_prevafvalue); 00115 } 00116 00117 bool RAS_OpenGLRasterizer::Init() 00118 { 00119 GPU_state_init(); 00120 00121 00122 m_ambr = 0.0f; 00123 m_ambg = 0.0f; 00124 m_ambb = 0.0f; 00125 00126 glDisable(GL_BLEND); 00127 glDisable(GL_ALPHA_TEST); 00128 //m_last_alphablend = GPU_BLEND_SOLID; 00129 GPU_set_material_alpha_blend(GPU_BLEND_SOLID); 00130 00131 glFrontFace(GL_CCW); 00132 m_last_frontface = true; 00133 00134 m_redback = 0.4375; 00135 m_greenback = 0.4375; 00136 m_blueback = 0.4375; 00137 m_alphaback = 0.0; 00138 00139 glClearColor(m_redback,m_greenback,m_blueback,m_alphaback); 00140 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00141 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00142 00143 00144 glShadeModel(GL_SMOOTH); 00145 00146 return true; 00147 } 00148 00149 00150 void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue) 00151 { 00152 m_ambr = red; 00153 m_ambg = green; 00154 m_ambb = blue; 00155 } 00156 00157 00158 void RAS_OpenGLRasterizer::SetAmbient(float factor) 00159 { 00160 float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f }; 00161 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); 00162 } 00163 00164 00165 void RAS_OpenGLRasterizer::SetBackColor(float red, 00166 float green, 00167 float blue, 00168 float alpha) 00169 { 00170 m_redback = red; 00171 m_greenback = green; 00172 m_blueback = blue; 00173 m_alphaback = alpha; 00174 } 00175 00176 00177 00178 void RAS_OpenGLRasterizer::SetFogColor(float r, 00179 float g, 00180 float b) 00181 { 00182 m_fogr = r; 00183 m_fogg = g; 00184 m_fogb = b; 00185 m_fogenabled = true; 00186 } 00187 00188 00189 00190 void RAS_OpenGLRasterizer::SetFogStart(float start) 00191 { 00192 m_fogstart = start; 00193 m_fogenabled = true; 00194 } 00195 00196 00197 00198 void RAS_OpenGLRasterizer::SetFogEnd(float fogend) 00199 { 00200 m_fogdist = fogend; 00201 m_fogenabled = true; 00202 } 00203 00204 00205 00206 void RAS_OpenGLRasterizer::SetFog(float start, 00207 float dist, 00208 float r, 00209 float g, 00210 float b) 00211 { 00212 m_fogstart = start; 00213 m_fogdist = dist; 00214 m_fogr = r; 00215 m_fogg = g; 00216 m_fogb = b; 00217 m_fogenabled = true; 00218 } 00219 00220 00221 00222 void RAS_OpenGLRasterizer::DisableFog() 00223 { 00224 m_fogenabled = false; 00225 } 00226 00227 bool RAS_OpenGLRasterizer::IsFogEnabled() 00228 { 00229 return m_fogenabled; 00230 } 00231 00232 00233 void RAS_OpenGLRasterizer::DisplayFog() 00234 { 00235 if ((m_drawingmode >= KX_SOLID) && m_fogenabled) 00236 { 00237 float params[5]; 00238 glFogi(GL_FOG_MODE, GL_LINEAR); 00239 glFogf(GL_FOG_DENSITY, 0.1f); 00240 glFogf(GL_FOG_START, m_fogstart); 00241 glFogf(GL_FOG_END, m_fogstart + m_fogdist); 00242 params[0]= m_fogr; 00243 params[1]= m_fogg; 00244 params[2]= m_fogb; 00245 params[3]= 0.0; 00246 glFogfv(GL_FOG_COLOR, params); 00247 glEnable(GL_FOG); 00248 } 00249 else 00250 { 00251 glDisable(GL_FOG); 00252 } 00253 } 00254 00255 00256 00257 bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat) 00258 { 00259 return mat.Activate(this, m_materialCachingInfo); 00260 } 00261 00262 00263 00264 void RAS_OpenGLRasterizer::Exit() 00265 { 00266 00267 glEnable(GL_CULL_FACE); 00268 glEnable(GL_DEPTH_TEST); 00269 glClearDepth(1.0); 00270 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00271 glClearColor(m_redback, m_greenback, m_blueback, m_alphaback); 00272 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00273 glDepthMask (GL_TRUE); 00274 glDepthFunc(GL_LEQUAL); 00275 glBlendFunc(GL_ONE, GL_ZERO); 00276 00277 glDisable(GL_POLYGON_STIPPLE); 00278 00279 glDisable(GL_LIGHTING); 00280 if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2) 00281 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); 00282 00283 EndFrame(); 00284 } 00285 00286 bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time) 00287 { 00288 m_time = time; 00289 m_drawingmode = drawingmode; 00290 00291 // Blender camera routine destroys the settings 00292 if (m_drawingmode < KX_SOLID) 00293 { 00294 glDisable (GL_CULL_FACE); 00295 glDisable (GL_DEPTH_TEST); 00296 } 00297 else 00298 { 00299 glEnable(GL_DEPTH_TEST); 00300 glEnable (GL_CULL_FACE); 00301 } 00302 00303 glDisable(GL_BLEND); 00304 glDisable(GL_ALPHA_TEST); 00305 //m_last_alphablend = GPU_BLEND_SOLID; 00306 GPU_set_material_alpha_blend(GPU_BLEND_SOLID); 00307 00308 glFrontFace(GL_CCW); 00309 m_last_frontface = true; 00310 00311 glShadeModel(GL_SMOOTH); 00312 00313 glEnable(GL_MULTISAMPLE_ARB); 00314 00315 m_2DCanvas->BeginFrame(); 00316 00317 return true; 00318 } 00319 00320 00321 00322 void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode) 00323 { 00324 m_drawingmode = drawingmode; 00325 00326 if(m_drawingmode == KX_WIREFRAME) 00327 glDisable(GL_CULL_FACE); 00328 } 00329 00330 int RAS_OpenGLRasterizer::GetDrawingMode() 00331 { 00332 return m_drawingmode; 00333 } 00334 00335 00336 void RAS_OpenGLRasterizer::SetDepthMask(DepthMask depthmask) 00337 { 00338 glDepthMask(depthmask == KX_DEPTHMASK_DISABLED ? GL_FALSE : GL_TRUE); 00339 } 00340 00341 00342 void RAS_OpenGLRasterizer::ClearColorBuffer() 00343 { 00344 m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback); 00345 m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER); 00346 } 00347 00348 00349 void RAS_OpenGLRasterizer::ClearDepthBuffer() 00350 { 00351 m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER); 00352 } 00353 00354 00355 void RAS_OpenGLRasterizer::ClearCachingInfo(void) 00356 { 00357 m_materialCachingInfo = 0; 00358 } 00359 00360 void RAS_OpenGLRasterizer::FlushDebugShapes() 00361 { 00362 if(!m_debugShapes.size()) 00363 return; 00364 00365 // DrawDebugLines 00366 GLboolean light, tex; 00367 00368 light= glIsEnabled(GL_LIGHTING); 00369 tex= glIsEnabled(GL_TEXTURE_2D); 00370 00371 if(light) glDisable(GL_LIGHTING); 00372 if(tex) glDisable(GL_TEXTURE_2D); 00373 00374 //draw lines 00375 glBegin(GL_LINES); 00376 for (unsigned int i=0;i<m_debugShapes.size();i++) 00377 { 00378 if (m_debugShapes[i].m_type != OglDebugShape::LINE) 00379 continue; 00380 glColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f); 00381 const MT_Scalar* fromPtr = &m_debugShapes[i].m_pos.x(); 00382 const MT_Scalar* toPtr= &m_debugShapes[i].m_param.x(); 00383 glVertex3dv(fromPtr); 00384 glVertex3dv(toPtr); 00385 } 00386 glEnd(); 00387 00388 //draw circles 00389 for (unsigned int i=0;i<m_debugShapes.size();i++) 00390 { 00391 if (m_debugShapes[i].m_type != OglDebugShape::CIRCLE) 00392 continue; 00393 glBegin(GL_LINE_LOOP); 00394 glColor4f(m_debugShapes[i].m_color[0],m_debugShapes[i].m_color[1],m_debugShapes[i].m_color[2],1.f); 00395 00396 static const MT_Vector3 worldUp(0.,0.,1.); 00397 MT_Vector3 norm = m_debugShapes[i].m_param; 00398 MT_Matrix3x3 tr; 00399 if (norm.fuzzyZero() || norm == worldUp) 00400 { 00401 tr.setIdentity(); 00402 } 00403 else 00404 { 00405 MT_Vector3 xaxis, yaxis; 00406 xaxis = MT_cross(norm, worldUp); 00407 yaxis = MT_cross(xaxis, norm); 00408 tr.setValue(xaxis.x(), xaxis.y(), xaxis.z(), 00409 yaxis.x(), yaxis.y(), yaxis.z(), 00410 norm.x(), norm.y(), norm.z()); 00411 } 00412 MT_Scalar rad = m_debugShapes[i].m_param2.x(); 00413 int n = (int) m_debugShapes[i].m_param2.y(); 00414 for (int j = 0; j<n; j++) 00415 { 00416 MT_Scalar theta = j*M_PI*2/n; 00417 MT_Vector3 pos(cos(theta)*rad, sin(theta)*rad, 0.); 00418 pos = pos*tr; 00419 pos += m_debugShapes[i].m_pos; 00420 const MT_Scalar* posPtr = &pos.x(); 00421 glVertex3dv(posPtr); 00422 } 00423 glEnd(); 00424 } 00425 00426 if(light) glEnable(GL_LIGHTING); 00427 if(tex) glEnable(GL_TEXTURE_2D); 00428 00429 m_debugShapes.clear(); 00430 } 00431 00432 void RAS_OpenGLRasterizer::EndFrame() 00433 { 00434 FlushDebugShapes(); 00435 00436 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00437 00438 glDisable(GL_MULTISAMPLE_ARB); 00439 00440 m_2DCanvas->EndFrame(); 00441 } 00442 00443 void RAS_OpenGLRasterizer::SetRenderArea() 00444 { 00445 RAS_Rect area; 00446 // only above/below stereo method needs viewport adjustment 00447 switch (m_stereomode) 00448 { 00449 case RAS_STEREO_ABOVEBELOW: 00450 switch(m_curreye) 00451 { 00452 case RAS_STEREO_LEFTEYE: 00453 // upper half of window 00454 area.SetLeft(0); 00455 area.SetBottom(m_2DCanvas->GetHeight() - 00456 int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2); 00457 00458 area.SetRight(int(m_2DCanvas->GetWidth())); 00459 area.SetTop(int(m_2DCanvas->GetHeight())); 00460 m_2DCanvas->SetDisplayArea(&area); 00461 break; 00462 case RAS_STEREO_RIGHTEYE: 00463 // lower half of window 00464 area.SetLeft(0); 00465 area.SetBottom(0); 00466 area.SetRight(int(m_2DCanvas->GetWidth())); 00467 area.SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2); 00468 m_2DCanvas->SetDisplayArea(&area); 00469 break; 00470 } 00471 break; 00472 case RAS_STEREO_SIDEBYSIDE: 00473 switch (m_curreye) 00474 { 00475 case RAS_STEREO_LEFTEYE: 00476 // Left half of window 00477 area.SetLeft(0); 00478 area.SetBottom(0); 00479 area.SetRight(m_2DCanvas->GetWidth()/2); 00480 area.SetTop(m_2DCanvas->GetHeight()); 00481 m_2DCanvas->SetDisplayArea(&area); 00482 break; 00483 case RAS_STEREO_RIGHTEYE: 00484 // Right half of window 00485 area.SetLeft(m_2DCanvas->GetWidth()/2); 00486 area.SetBottom(0); 00487 area.SetRight(m_2DCanvas->GetWidth()); 00488 area.SetTop(m_2DCanvas->GetHeight()); 00489 m_2DCanvas->SetDisplayArea(&area); 00490 break; 00491 } 00492 break; 00493 default: 00494 // every available pixel 00495 area.SetLeft(0); 00496 area.SetBottom(0); 00497 area.SetRight(int(m_2DCanvas->GetWidth())); 00498 area.SetTop(int(m_2DCanvas->GetHeight())); 00499 m_2DCanvas->SetDisplayArea(&area); 00500 break; 00501 } 00502 } 00503 00504 void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode) 00505 { 00506 m_stereomode = stereomode; 00507 } 00508 00509 RAS_IRasterizer::StereoMode RAS_OpenGLRasterizer::GetStereoMode() 00510 { 00511 return m_stereomode; 00512 } 00513 00514 bool RAS_OpenGLRasterizer::Stereo() 00515 { 00516 if(m_stereomode > RAS_STEREO_NOSTEREO) // > 0 00517 return true; 00518 else 00519 return false; 00520 } 00521 00522 bool RAS_OpenGLRasterizer::InterlacedStereo() 00523 { 00524 return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED; 00525 } 00526 00527 void RAS_OpenGLRasterizer::SetEye(const StereoEye eye) 00528 { 00529 m_curreye = eye; 00530 switch (m_stereomode) 00531 { 00532 case RAS_STEREO_QUADBUFFERED: 00533 glDrawBuffer(m_curreye == RAS_STEREO_LEFTEYE ? GL_BACK_LEFT : GL_BACK_RIGHT); 00534 break; 00535 case RAS_STEREO_ANAGLYPH: 00536 if (m_curreye == RAS_STEREO_LEFTEYE) 00537 { 00538 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE); 00539 } else { 00540 //glAccum(GL_LOAD, 1.0); 00541 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); 00542 ClearDepthBuffer(); 00543 } 00544 break; 00545 case RAS_STEREO_VINTERLACE: 00546 { 00547 glEnable(GL_POLYGON_STIPPLE); 00548 glPolygonStipple((const GLubyte*) ((m_curreye == RAS_STEREO_LEFTEYE) ? left_eye_vinterlace_mask : right_eye_vinterlace_mask)); 00549 if (m_curreye == RAS_STEREO_RIGHTEYE) 00550 ClearDepthBuffer(); 00551 break; 00552 } 00553 case RAS_STEREO_INTERLACED: 00554 { 00555 glEnable(GL_POLYGON_STIPPLE); 00556 glPolygonStipple((const GLubyte*) &hinterlace_mask[m_curreye == RAS_STEREO_LEFTEYE?0:1]); 00557 if (m_curreye == RAS_STEREO_RIGHTEYE) 00558 ClearDepthBuffer(); 00559 break; 00560 } 00561 default: 00562 break; 00563 } 00564 } 00565 00566 RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye() 00567 { 00568 return m_curreye; 00569 } 00570 00571 00572 void RAS_OpenGLRasterizer::SetEyeSeparation(const float eyeseparation) 00573 { 00574 m_eyeseparation = eyeseparation; 00575 } 00576 00577 float RAS_OpenGLRasterizer::GetEyeSeparation() 00578 { 00579 return m_eyeseparation; 00580 } 00581 00582 void RAS_OpenGLRasterizer::SetFocalLength(const float focallength) 00583 { 00584 m_focallength = focallength; 00585 m_setfocallength = true; 00586 } 00587 00588 float RAS_OpenGLRasterizer::GetFocalLength() 00589 { 00590 return m_focallength; 00591 } 00592 00593 00594 void RAS_OpenGLRasterizer::SwapBuffers() 00595 { 00596 m_2DCanvas->SwapBuffers(); 00597 } 00598 00599 00600 00601 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewMatrix() const 00602 { 00603 return m_viewmatrix; 00604 } 00605 00606 const MT_Matrix4x4& RAS_OpenGLRasterizer::GetViewInvMatrix() const 00607 { 00608 return m_viewinvmatrix; 00609 } 00610 00611 void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms, 00612 class RAS_IPolyMaterial* polymat, 00613 class RAS_IRenderTools* rendertools) 00614 { 00615 bool obcolor = ms.m_bObjectColor; 00616 MT_Vector4& rgba = ms.m_RGBAcolor; 00617 RAS_MeshSlot::iterator it; 00618 00619 // handle object color 00620 if (obcolor) { 00621 glDisableClientState(GL_COLOR_ARRAY); 00622 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); 00623 } 00624 else 00625 glEnableClientState(GL_COLOR_ARRAY); 00626 00627 for(ms.begin(it); !ms.end(it); ms.next(it)) { 00628 RAS_TexVert *vertex; 00629 size_t i, j, numvert; 00630 00631 numvert = it.array->m_type; 00632 00633 if(it.array->m_type == RAS_DisplayArray::LINE) { 00634 // line drawing, no text 00635 glBegin(GL_LINES); 00636 00637 for(i=0; i<it.totindex; i+=2) 00638 { 00639 vertex = &it.vertex[it.index[i]]; 00640 glVertex3fv(vertex->getXYZ()); 00641 00642 vertex = &it.vertex[it.index[i+1]]; 00643 glVertex3fv(vertex->getXYZ()); 00644 } 00645 00646 glEnd(); 00647 } 00648 else { 00649 // triangle and quad text drawing 00650 for(i=0; i<it.totindex; i+=numvert) 00651 { 00652 float v[4][3]; 00653 int glattrib, unit; 00654 00655 for(j=0; j<numvert; j++) { 00656 vertex = &it.vertex[it.index[i+j]]; 00657 00658 v[j][0] = vertex->getXYZ()[0]; 00659 v[j][1] = vertex->getXYZ()[1]; 00660 v[j][2] = vertex->getXYZ()[2]; 00661 } 00662 00663 // find the right opengl attribute 00664 glattrib = -1; 00665 if(GLEW_ARB_vertex_program) 00666 for(unit=0; unit<m_attrib_num; unit++) 00667 if(m_attrib[unit] == RAS_TEXCO_UV1) 00668 glattrib = unit; 00669 00670 rendertools->RenderText(polymat->GetDrawingMode(), polymat, 00671 v[0], v[1], v[2], (numvert == 4)? v[3]: NULL, glattrib); 00672 00673 ClearCachingInfo(); 00674 } 00675 } 00676 } 00677 00678 glDisableClientState(GL_COLOR_ARRAY); 00679 } 00680 00681 void RAS_OpenGLRasterizer::SetTexCoordNum(int num) 00682 { 00683 m_texco_num = num; 00684 if(m_texco_num > RAS_MAX_TEXCO) 00685 m_texco_num = RAS_MAX_TEXCO; 00686 } 00687 00688 void RAS_OpenGLRasterizer::SetAttribNum(int num) 00689 { 00690 m_attrib_num = num; 00691 if(m_attrib_num > RAS_MAX_ATTRIB) 00692 m_attrib_num = RAS_MAX_ATTRIB; 00693 } 00694 00695 void RAS_OpenGLRasterizer::SetTexCoord(TexCoGen coords, int unit) 00696 { 00697 // this changes from material to material 00698 if(unit < RAS_MAX_TEXCO) 00699 m_texco[unit] = coords; 00700 } 00701 00702 void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit) 00703 { 00704 // this changes from material to material 00705 if(unit < RAS_MAX_ATTRIB) 00706 m_attrib[unit] = coords; 00707 } 00708 00709 void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv) 00710 { 00711 int unit; 00712 00713 if(GLEW_ARB_multitexture) { 00714 for(unit=0; unit<m_texco_num; unit++) { 00715 if(tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) { 00716 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2()); 00717 continue; 00718 } 00719 switch(m_texco[unit]) { 00720 case RAS_TEXCO_ORCO: 00721 case RAS_TEXCO_GLOB: 00722 glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ()); 00723 break; 00724 case RAS_TEXCO_UV1: 00725 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1()); 00726 break; 00727 case RAS_TEXCO_NORM: 00728 glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal()); 00729 break; 00730 case RAS_TEXTANGENT: 00731 glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent()); 00732 break; 00733 case RAS_TEXCO_UV2: 00734 glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2()); 00735 break; 00736 default: 00737 break; 00738 } 00739 } 00740 } 00741 00742 if(GLEW_ARB_vertex_program) { 00743 for(unit=0; unit<m_attrib_num; unit++) { 00744 switch(m_attrib[unit]) { 00745 case RAS_TEXCO_ORCO: 00746 case RAS_TEXCO_GLOB: 00747 glVertexAttrib3fvARB(unit, tv.getXYZ()); 00748 break; 00749 case RAS_TEXCO_UV1: 00750 glVertexAttrib2fvARB(unit, tv.getUV1()); 00751 break; 00752 case RAS_TEXCO_NORM: 00753 glVertexAttrib3fvARB(unit, tv.getNormal()); 00754 break; 00755 case RAS_TEXTANGENT: 00756 glVertexAttrib4fvARB(unit, tv.getTangent()); 00757 break; 00758 case RAS_TEXCO_UV2: 00759 glVertexAttrib2fvARB(unit, tv.getUV2()); 00760 break; 00761 case RAS_TEXCO_VCOL: 00762 glVertexAttrib4ubvARB(unit, tv.getRGBA()); 00763 break; 00764 default: 00765 break; 00766 } 00767 } 00768 } 00769 00770 } 00771 00772 void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms) 00773 { 00774 IndexPrimitivesInternal(ms, false); 00775 } 00776 00777 void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) 00778 { 00779 IndexPrimitivesInternal(ms, true); 00780 } 00781 00782 static bool current_wireframe; 00783 static RAS_MaterialBucket *current_bucket; 00784 static RAS_IPolyMaterial *current_polymat; 00785 static RAS_MeshSlot *current_ms; 00786 static RAS_MeshObject *current_mesh; 00787 static int current_blmat_nr; 00788 static GPUVertexAttribs current_gpu_attribs; 00789 static Image *current_image; 00790 static int CheckMaterialDM(int matnr, void *attribs) 00791 { 00792 // only draw the current material 00793 if (matnr != current_blmat_nr) 00794 return 0; 00795 GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs; 00796 if (gattribs) 00797 memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs)); 00798 return 1; 00799 } 00800 00801 /* 00802 static int CheckTexfaceDM(void *mcol, int index) 00803 { 00804 00805 // index is the original face index, retrieve the polygon 00806 RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ? 00807 current_mesh->GetPolygon(index) : NULL; 00808 if (polygon && polygon->GetMaterial() == current_bucket) { 00809 // must handle color. 00810 if (current_wireframe) 00811 return 2; 00812 if (current_ms->m_bObjectColor) { 00813 MT_Vector4& rgba = current_ms->m_RGBAcolor; 00814 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); 00815 // don't use mcol 00816 return 2; 00817 } 00818 if (!mcol) { 00819 // we have to set the color from the material 00820 unsigned char rgba[4]; 00821 current_polymat->GetMaterialRGBAColor(rgba); 00822 glColor4ubv((const GLubyte *)rgba); 00823 return 2; 00824 } 00825 return 1; 00826 } 00827 return 0; 00828 } 00829 */ 00830 00831 static int CheckTexDM(MTFace *tface, int has_mcol, int matnr) 00832 { 00833 00834 // index is the original face index, retrieve the polygon 00835 if (matnr == current_blmat_nr && 00836 (tface == NULL || tface->tpage == current_image)) { 00837 // must handle color. 00838 if (current_wireframe) 00839 return 2; 00840 if (current_ms->m_bObjectColor) { 00841 MT_Vector4& rgba = current_ms->m_RGBAcolor; 00842 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); 00843 // don't use mcol 00844 return 2; 00845 } 00846 if (!has_mcol) { 00847 // we have to set the color from the material 00848 unsigned char rgba[4]; 00849 current_polymat->GetMaterialRGBAColor(rgba); 00850 glColor4ubv((const GLubyte *)rgba); 00851 return 2; 00852 } 00853 return 1; 00854 } 00855 return 0; 00856 } 00857 00858 void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) 00859 { 00860 bool obcolor = ms.m_bObjectColor; 00861 bool wireframe = m_drawingmode <= KX_WIREFRAME; 00862 MT_Vector4& rgba = ms.m_RGBAcolor; 00863 RAS_MeshSlot::iterator it; 00864 00865 if (ms.m_pDerivedMesh) { 00866 // mesh data is in derived mesh, 00867 current_bucket = ms.m_bucket; 00868 current_polymat = current_bucket->GetPolyMaterial(); 00869 current_ms = &ms; 00870 current_mesh = ms.m_mesh; 00871 current_wireframe = wireframe; 00872 // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */ 00873 00874 // handle two-side 00875 if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL) 00876 this->SetCullFace(true); 00877 else 00878 this->SetCullFace(false); 00879 00880 if (current_polymat->GetFlag() & RAS_BLENDERGLSL) { 00881 // GetMaterialIndex return the original mface material index, 00882 // increment by 1 to match what derived mesh is doing 00883 current_blmat_nr = current_polymat->GetMaterialIndex()+1; 00884 // For GLSL we need to retrieve the GPU material attribute 00885 Material* blmat = current_polymat->GetBlenderMaterial(); 00886 Scene* blscene = current_polymat->GetBlenderScene(); 00887 if (!wireframe && blscene && blmat) 00888 GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs); 00889 else 00890 memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs)); 00891 // DM draw can mess up blending mode, restore at the end 00892 int current_blend_mode = GPU_get_material_alpha_blend(); 00893 ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM); 00894 GPU_set_material_alpha_blend(current_blend_mode); 00895 } else { 00896 //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); 00897 current_blmat_nr = current_polymat->GetMaterialIndex(); 00898 current_image = current_polymat->GetBlenderImage(); 00899 ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL); 00900 } 00901 return; 00902 } 00903 // iterate over display arrays, each containing an index + vertex array 00904 for(ms.begin(it); !ms.end(it); ms.next(it)) { 00905 RAS_TexVert *vertex; 00906 size_t i, j, numvert; 00907 00908 numvert = it.array->m_type; 00909 00910 if(it.array->m_type == RAS_DisplayArray::LINE) { 00911 // line drawing 00912 glBegin(GL_LINES); 00913 00914 for(i=0; i<it.totindex; i+=2) 00915 { 00916 vertex = &it.vertex[it.index[i]]; 00917 glVertex3fv(vertex->getXYZ()); 00918 00919 vertex = &it.vertex[it.index[i+1]]; 00920 glVertex3fv(vertex->getXYZ()); 00921 } 00922 00923 glEnd(); 00924 } 00925 else { 00926 // triangle and quad drawing 00927 if(it.array->m_type == RAS_DisplayArray::TRIANGLE) 00928 glBegin(GL_TRIANGLES); 00929 else 00930 glBegin(GL_QUADS); 00931 00932 for(i=0; i<it.totindex; i+=numvert) 00933 { 00934 if(obcolor) 00935 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); 00936 00937 for(j=0; j<numvert; j++) { 00938 vertex = &it.vertex[it.index[i+j]]; 00939 00940 if(!wireframe) { 00941 if(!obcolor) 00942 glColor4ubv((const GLubyte *)(vertex->getRGBA())); 00943 00944 glNormal3fv(vertex->getNormal()); 00945 00946 if(multi) 00947 TexCoord(*vertex); 00948 else 00949 glTexCoord2fv(vertex->getUV1()); 00950 } 00951 00952 glVertex3fv(vertex->getXYZ()); 00953 } 00954 } 00955 00956 glEnd(); 00957 } 00958 } 00959 } 00960 00961 void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat) 00962 { 00963 glMatrixMode(GL_PROJECTION); 00964 double* matrix = &mat(0,0); 00965 glLoadMatrixd(matrix); 00966 00967 m_camortho= (mat(3, 3) != 0.0f); 00968 } 00969 00970 void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat) 00971 { 00972 glMatrixMode(GL_PROJECTION); 00973 double matrix[16]; 00974 /* Get into argument. Looks a bit dodgy, but it's ok. */ 00975 mat.getValue(matrix); 00976 /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */ 00977 glLoadMatrixd(matrix); 00978 00979 m_camortho= (mat[3][3] != 0.0f); 00980 } 00981 00982 MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( 00983 float left, 00984 float right, 00985 float bottom, 00986 float top, 00987 float frustnear, 00988 float frustfar, 00989 float focallength, 00990 bool 00991 ){ 00992 MT_Matrix4x4 result; 00993 double mat[16]; 00994 00995 // correction for stereo 00996 if(Stereo()) 00997 { 00998 float near_div_focallength; 00999 float offset; 01000 01001 // if Rasterizer.setFocalLength is not called we use the camera focallength 01002 if (!m_setfocallength) 01003 // if focallength is null we use a value known to be reasonable 01004 m_focallength = (focallength == 0.f) ? m_eyeseparation * 30.0 01005 : focallength; 01006 01007 near_div_focallength = frustnear / m_focallength; 01008 offset = 0.5 * m_eyeseparation * near_div_focallength; 01009 switch(m_curreye) 01010 { 01011 case RAS_STEREO_LEFTEYE: 01012 left += offset; 01013 right += offset; 01014 break; 01015 case RAS_STEREO_RIGHTEYE: 01016 left -= offset; 01017 right -= offset; 01018 break; 01019 } 01020 // leave bottom and top untouched 01021 } 01022 01023 glMatrixMode(GL_PROJECTION); 01024 glLoadIdentity(); 01025 glFrustum(left, right, bottom, top, frustnear, frustfar); 01026 01027 glGetDoublev(GL_PROJECTION_MATRIX, mat); 01028 result.setValue(mat); 01029 01030 return result; 01031 } 01032 01033 MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix( 01034 float left, 01035 float right, 01036 float bottom, 01037 float top, 01038 float frustnear, 01039 float frustfar 01040 ){ 01041 MT_Matrix4x4 result; 01042 double mat[16]; 01043 01044 // stereo is meaning less for orthographic, disable it 01045 glMatrixMode(GL_PROJECTION); 01046 glLoadIdentity(); 01047 glOrtho(left, right, bottom, top, frustnear, frustfar); 01048 01049 glGetDoublev(GL_PROJECTION_MATRIX, mat); 01050 result.setValue(mat); 01051 01052 return result; 01053 } 01054 01055 01056 // next arguments probably contain redundant info, for later... 01057 void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, 01058 const MT_Matrix3x3 & camOrientMat3x3, 01059 const MT_Point3 & pos, 01060 bool perspective) 01061 { 01062 m_viewmatrix = mat; 01063 01064 // correction for stereo 01065 if(Stereo() && perspective) 01066 { 01067 MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention 01068 MT_Vector3 unitViewupVec(0.0, 0.0, 1.0); 01069 MT_Vector3 viewDir, viewupVec; 01070 MT_Vector3 eyeline; 01071 01072 // actual viewDir 01073 viewDir = camOrientMat3x3 * unitViewDir; // this is the moto convention, vector on right hand side 01074 // actual viewup vec 01075 viewupVec = camOrientMat3x3 * unitViewupVec; 01076 01077 // vector between eyes 01078 eyeline = viewDir.cross(viewupVec); 01079 01080 switch(m_curreye) 01081 { 01082 case RAS_STEREO_LEFTEYE: 01083 { 01084 // translate to left by half the eye distance 01085 MT_Transform transform; 01086 transform.setIdentity(); 01087 transform.translate(-(eyeline * m_eyeseparation / 2.0)); 01088 m_viewmatrix *= transform; 01089 } 01090 break; 01091 case RAS_STEREO_RIGHTEYE: 01092 { 01093 // translate to right by half the eye distance 01094 MT_Transform transform; 01095 transform.setIdentity(); 01096 transform.translate(eyeline * m_eyeseparation / 2.0); 01097 m_viewmatrix *= transform; 01098 } 01099 break; 01100 } 01101 } 01102 01103 m_viewinvmatrix = m_viewmatrix; 01104 m_viewinvmatrix.invert(); 01105 01106 // note: getValue gives back column major as needed by OpenGL 01107 MT_Scalar glviewmat[16]; 01108 m_viewmatrix.getValue(glviewmat); 01109 01110 glMatrixMode(GL_MODELVIEW); 01111 glLoadMatrixd(glviewmat); 01112 m_campos = pos; 01113 } 01114 01115 01116 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition() 01117 { 01118 return m_campos; 01119 } 01120 01121 bool RAS_OpenGLRasterizer::GetCameraOrtho() 01122 { 01123 return m_camortho; 01124 } 01125 01126 void RAS_OpenGLRasterizer::SetCullFace(bool enable) 01127 { 01128 if (enable) 01129 glEnable(GL_CULL_FACE); 01130 else 01131 glDisable(GL_CULL_FACE); 01132 } 01133 01134 void RAS_OpenGLRasterizer::SetLines(bool enable) 01135 { 01136 if (enable) 01137 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 01138 else 01139 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 01140 } 01141 01142 void RAS_OpenGLRasterizer::SetSpecularity(float specX, 01143 float specY, 01144 float specZ, 01145 float specval) 01146 { 01147 GLfloat mat_specular[] = {specX, specY, specZ, specval}; 01148 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); 01149 } 01150 01151 01152 01153 void RAS_OpenGLRasterizer::SetShinyness(float shiny) 01154 { 01155 GLfloat mat_shininess[] = { shiny }; 01156 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); 01157 } 01158 01159 01160 01161 void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse) 01162 { 01163 GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse}; 01164 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse); 01165 } 01166 01167 void RAS_OpenGLRasterizer::SetEmissive(float eX, float eY, float eZ, float e) 01168 { 01169 GLfloat mat_emit [] = {eX,eY,eZ,e}; 01170 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emit); 01171 } 01172 01173 01174 double RAS_OpenGLRasterizer::GetTime() 01175 { 01176 return m_time; 01177 } 01178 01179 void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add) 01180 { 01181 glPolygonOffset(mult, add); 01182 GLint mode = GL_POLYGON_OFFSET_FILL; 01183 if (m_drawingmode < KX_SHADED) 01184 mode = GL_POLYGON_OFFSET_LINE; 01185 if (mult != 0.0f || add != 0.0f) 01186 glEnable(mode); 01187 else 01188 glDisable(mode); 01189 } 01190 01191 void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue) 01192 { 01193 /* don't just set m_motionblur to 1, but check if it is 0 so 01194 * we don't reset a motion blur that is already enabled */ 01195 if(m_motionblur == 0) 01196 m_motionblur = 1; 01197 m_motionblurvalue = motionblurvalue; 01198 } 01199 01200 void RAS_OpenGLRasterizer::DisableMotionBlur() 01201 { 01202 m_motionblur = 0; 01203 m_motionblurvalue = -1.0; 01204 } 01205 01206 void RAS_OpenGLRasterizer::SetAlphaBlend(int alphablend) 01207 { 01208 GPU_set_material_alpha_blend(alphablend); 01209 /* 01210 if(alphablend == m_last_alphablend) 01211 return; 01212 01213 if(alphablend == GPU_BLEND_SOLID) { 01214 glDisable(GL_BLEND); 01215 glDisable(GL_ALPHA_TEST); 01216 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 01217 } 01218 else if(alphablend == GPU_BLEND_ADD) { 01219 glBlendFunc(GL_ONE, GL_ONE); 01220 glEnable(GL_BLEND); 01221 glDisable(GL_ALPHA_TEST); 01222 } 01223 else if(alphablend == GPU_BLEND_ALPHA) { 01224 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 01225 glEnable(GL_BLEND); 01226 glEnable(GL_ALPHA_TEST); 01227 glAlphaFunc(GL_GREATER, 0.0f); 01228 } 01229 else if(alphablend == GPU_BLEND_CLIP) { 01230 glDisable(GL_BLEND); 01231 glEnable(GL_ALPHA_TEST); 01232 glAlphaFunc(GL_GREATER, 0.5f); 01233 } 01234 01235 m_last_alphablend = alphablend; 01236 */ 01237 } 01238 01239 void RAS_OpenGLRasterizer::SetFrontFace(bool ccw) 01240 { 01241 if(m_last_frontface == ccw) 01242 return; 01243 01244 if(ccw) 01245 glFrontFace(GL_CCW); 01246 else 01247 glFrontFace(GL_CW); 01248 01249 m_last_frontface = ccw; 01250 } 01251 01252 void RAS_OpenGLRasterizer::SetAnisotropicFiltering(short level) 01253 { 01254 GPU_set_anisotropic((float)level); 01255 } 01256 01257 short RAS_OpenGLRasterizer::GetAnisotropicFiltering() 01258 { 01259 return (short)GPU_get_anisotropic(); 01260 }