diff options
author | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
---|---|---|
committer | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
commit | 12315f4d0e0ae993805f141f64cb8c73c5297311 (patch) | |
tree | 59b45827cd8293cfb727758989c7a74b40183974 /source/gameengine/Rasterizer/RAS_OpenGLRasterizer |
Initial revisionv2.25
Diffstat (limited to 'source/gameengine/Rasterizer/RAS_OpenGLRasterizer')
7 files changed, 1874 insertions, 0 deletions
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile new file mode 100644 index 00000000000..c03aab3422e --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile @@ -0,0 +1,47 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# +# Bounce make to subdirectories. +# + +LIBNAME = OpenGLrasterizer +DIR = $(OCGDIR)/gameengine/$(LIBNAME) + +include nan_compile.mk + +CCFLAGS += $(LEVEL_1_CPP_WARNINGS) + +CPPFLAGS += -I$(OPENGL_HEADERS) +CPPFLAGS += -I$(NAN_STRING)/include +CPPFLAGS += -I$(NAN_MOTO)/include +CPPFLAGS += -I../../../kernel/gen_system +CPPFLAGS += -I.. + diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.cpp new file mode 100644 index 00000000000..ff57e7ab102 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.cpp @@ -0,0 +1,61 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#include "RAS_CheckVertexArrays.h" + +#ifdef WIN32 +#include <windows.h> +#endif // WIN32 +#include "GL/gl.h" + +#include "STR_String.h" + + +bool RAS_SystemSupportsVertexArrays() { + + bool result = false; + + char* ext = (char*) glGetString(GL_EXTENSIONS); + STR_String extensions; + + if (ext) + extensions = STR_String(ext); + +#ifdef WIN32 + if (extensions.Find("GL_EXT_compiled_vertex_array") >= 0) + { + result=true; + } +#endif //WIN32 + + return result; + +} diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.h new file mode 100644 index 00000000000..f9edafb7d2e --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_CheckVertexArrays.h @@ -0,0 +1,37 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef __RAS_CHECKVERTEXARRAYS +#define __RAS_CHECKVERTEXARRAYS + +bool RAS_SystemSupportsVertexArrays(); + +#endif //__RAS_CHECKVERTEXARRAYS diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp new file mode 100644 index 00000000000..32b5852137b --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -0,0 +1,1226 @@ +#include "RAS_OpenGLRasterizer.h" + +#ifdef WIN32 +#include <windows.h> +#endif // WIN32 +#include "GL/gl.h" + +#include "RAS_Rect.h" +#include "RAS_TexVert.h" +#include "MT_CmMatrix4x4.h" +#include "RAS_IRenderTools.h" // rendering text + + +RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) + :RAS_IRasterizer(canvas), + m_2DCanvas(canvas), + m_fogenabled(false), + m_materialCachingInfo(0), + m_noOfScanlines(32) +{ + m_viewmatrix.Identity(); + m_stereomode = RAS_STEREO_NOSTEREO; +} + + + +RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer() +{ +} + + + +void Myinit_gl_stuff(void) +{ + float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 }; + float mat_shininess[] = { 35.0 }; +/* float one= 1.0; */ + int a, x, y; + GLubyte pat[32*32]; + const GLubyte *patc= pat; + + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); + + +#if defined(__FreeBSD) || defined(__linux__) + glDisable(GL_DITHER); /* op sgi/sun hardware && 12 bits */ +#endif + + /* no local viewer, looks ugly in ortho mode */ + /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */ + + glDepthFunc(GL_LEQUAL); + /* scaling matrices */ + glEnable(GL_NORMALIZE); + + glShadeModel(GL_FLAT); + + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glDisable(GL_LIGHTING); + glDisable(GL_LOGIC_OP); + glDisable(GL_STENCIL_TEST); + glDisable(GL_TEXTURE_1D); + glDisable(GL_TEXTURE_2D); + + glPixelTransferi(GL_MAP_COLOR, GL_FALSE); + glPixelTransferi(GL_RED_SCALE, 1); + glPixelTransferi(GL_RED_BIAS, 0); + glPixelTransferi(GL_GREEN_SCALE, 1); + glPixelTransferi(GL_GREEN_BIAS, 0); + glPixelTransferi(GL_BLUE_SCALE, 1); + glPixelTransferi(GL_BLUE_BIAS, 0); + glPixelTransferi(GL_ALPHA_SCALE, 1); + glPixelTransferi(GL_ALPHA_BIAS, 0); + + a = 0; + for(x=0; x<32; x++) + { + for(y=0; y<4; y++) + { + if( (x) & 1) pat[a++]= 0x88; + else pat[a++]= 0x22; + } + } + + glPolygonStipple(patc); +} + + + +bool RAS_OpenGLRasterizer::Init() +{ + + Myinit_gl_stuff(); + + m_redback = 0.4375; + m_greenback = 0.4375; + m_blueback = 0.4375; + m_alphaback = 0.0; + + // enable both vertexcolor AND lighting color + glEnable(GL_COLOR_MATERIAL); + + glClearColor(m_redback,m_greenback,m_blueback,m_alphaback); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glShadeModel(GL_SMOOTH); + + return true; +} + + + +void RAS_OpenGLRasterizer::SetBackColor(float red, + float green, + float blue, + float alpha) +{ + m_redback = red; + m_greenback = green; + m_blueback = blue; + m_alphaback = alpha; +} + + + +void RAS_OpenGLRasterizer::SetFogColor(float r, + float g, + float b) +{ + m_fogr = r; + m_fogg = g; + m_fogb = b; + m_fogenabled = true; +} + + + +void RAS_OpenGLRasterizer::SetFogStart(float start) +{ + m_fogstart = start; + m_fogenabled = true; +} + + + +void RAS_OpenGLRasterizer::SetFogEnd(float fogend) +{ + m_fogdist = fogend; + m_fogenabled = true; +} + + + +void RAS_OpenGLRasterizer::SetFog(float start, + float dist, + float r, + float g, + float b) +{ + m_fogstart = start; + m_fogdist = dist; + m_fogr = r; + m_fogg = g; + m_fogb = b; + m_fogenabled = true; +} + + + +void RAS_OpenGLRasterizer::DisableFog() +{ + m_fogenabled = false; +} + + + +void RAS_OpenGLRasterizer::DisplayFog() +{ + if ((m_drawingmode >= KX_SOLID) && m_fogenabled) + { + float params[5]; + glFogi(GL_FOG_MODE, GL_LINEAR); + glFogf(GL_FOG_DENSITY, 0.1f); + glFogf(GL_FOG_START, m_fogstart); + glFogf(GL_FOG_END, m_fogstart + m_fogdist); + params[0]= m_fogr; + params[1]= m_fogg; + params[2]= m_fogb; + params[3]= 0.0; + glFogfv(GL_FOG_COLOR, params); + glEnable(GL_FOG); + } + else + { + glDisable(GL_FOG); + } +} + + + +void RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat) +{ + if (mat.GetCachingInfo() != m_materialCachingInfo) + { + mat.Activate(this, m_materialCachingInfo); + } +} + + + +void RAS_OpenGLRasterizer::Exit() +{ + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glClearDepth(1.0); + glClearColor(m_redback, m_greenback, m_blueback, m_alphaback); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDepthMask (GL_TRUE); + glDepthFunc(GL_LEQUAL); + glBlendFunc(GL_ONE, GL_ZERO); + + glDisable(GL_LIGHTING); + + EndFrame(); +} + + + +bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time) +{ + m_time = time; + m_drawingmode = drawingmode; + + m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback); + m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER); + + // Blender camera routine destroys the settings + if (m_drawingmode < KX_SOLID) + { + glDisable (GL_CULL_FACE); + glDisable (GL_DEPTH_TEST); + } + else + { + glEnable(GL_DEPTH_TEST); + glEnable (GL_CULL_FACE); + } + + glShadeModel(GL_SMOOTH); + + m_2DCanvas->BeginFrame(); + + return true; +} + + + +void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode) +{ + m_drawingmode = drawingmode; + + switch (m_drawingmode) + { + case KX_BOUNDINGBOX: + { + } + case KX_WIREFRAME: + { + glDisable (GL_CULL_FACE); + break; + } + case KX_TEXTURED: + { + } + case KX_SHADED: + { + } + case KX_SOLID: + { + } + default: + { + } + } +} + + + +int RAS_OpenGLRasterizer::GetDrawingMode() +{ + return m_drawingmode; +} + + + +void RAS_OpenGLRasterizer::SetDepthMask(int depthmask) +{ + switch (depthmask) + { + case KX_DEPTHMASK_ENABLED: + { + glDepthMask(GL_TRUE); + break; + }; + case KX_DEPTHMASK_DISABLED: + { + glDepthMask(GL_FALSE); + break; + }; + default: + { + //printf("someone made a mistake, RAS_OpenGLRasterizer::SetDepthMask(int depthmask)\n"); + exit(0); + } + } +} + + + +void RAS_OpenGLRasterizer::ClearDepthBuffer() +{ + m_2DCanvas->ClearBuffer(RAS_ICanvas::DEPTH_BUFFER); +} + + +void RAS_OpenGLRasterizer::ClearCachingInfo(void) +{ + m_materialCachingInfo = 0; +} + + +void RAS_OpenGLRasterizer::EndFrame() +{ + m_2DCanvas->EndFrame(); +} + + +void RAS_OpenGLRasterizer::SetRenderArea() +{ + // only above/below stereo method needs viewport adjustment + if(m_stereomode == RAS_STEREO_ABOVEBELOW) + { + switch(m_curreye) + { + case RAS_STEREO_LEFTEYE: + // upper half of window + m_2DCanvas->GetDisplayArea().SetLeft(0); + m_2DCanvas->GetDisplayArea().SetBottom(m_2DCanvas->GetHeight() - + int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2); + + m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth())); + m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight())); + break; + case RAS_STEREO_RIGHTEYE: + // lower half of window + m_2DCanvas->GetDisplayArea().SetLeft(0); + m_2DCanvas->GetDisplayArea().SetBottom(0); + m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth())); + m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2); + break; + } + } + else + { + // every available pixel + m_2DCanvas->GetDisplayArea().SetLeft(0); + m_2DCanvas->GetDisplayArea().SetBottom(0); + m_2DCanvas->GetDisplayArea().SetRight(int(m_2DCanvas->GetWidth())); + m_2DCanvas->GetDisplayArea().SetTop(int(m_2DCanvas->GetHeight())); + } +} + + +void RAS_OpenGLRasterizer::SetStereoMode(const int stereomode) +{ + m_stereomode = stereomode; +} + + + +bool RAS_OpenGLRasterizer::Stereo() +{ + if(m_stereomode == RAS_STEREO_NOSTEREO) + return false; + else + return true; +} + + +void RAS_OpenGLRasterizer::SetEye(int eye) +{ + m_curreye = eye; + if(m_stereomode == RAS_STEREO_QUADBUFFERED) { + if(m_curreye == RAS_STEREO_LEFTEYE) + glDrawBuffer(GL_BACK_LEFT); + else + glDrawBuffer(GL_BACK_RIGHT); + } +} + + +void RAS_OpenGLRasterizer::SetEyeSeparation(float eyeseparation) +{ + m_eyeseparation = eyeseparation; +} + + +void RAS_OpenGLRasterizer::SetFocalLength(float focallength) +{ + m_focallength = focallength; +} + + +void RAS_OpenGLRasterizer::SwapBuffers() +{ + m_2DCanvas->SwapBuffers(); +} + + + +void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor + ) +{ + static const GLsizei vtxstride = sizeof(RAS_TexVert); + GLenum drawmode; + switch (mode) + { + case 0: + drawmode = GL_TRIANGLES; + break; + case 1: + drawmode = GL_LINES; + break; + case 2: + drawmode = GL_QUADS; + break; + default: + drawmode = GL_LINES; + break; + } + + const RAS_TexVert* vertexarray ; + int numindices,vt; + + for (vt=0;vt<vertexarrays.size();vt++) + { + vertexarray = &((*vertexarrays[vt]) [0]); + const KX_IndexArray & indexarray = (*indexarrays[vt]); + numindices = indexarray.size(); + + int numverts = vertexarrays[vt]->size(); + + if (!numindices) + break; + + int vindex=0; + switch (mode) + { + case 1: + { + glBegin(GL_LINES); + vindex=0; + for (int i=0;i<numindices;i+=2) + { + glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ()); + glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ()); + } + glEnd(); + } + break; + case 2: + { + glBegin(GL_QUADS); + vindex=0; + if (useObjectColor) + { + for (int i=0;i<numindices;i+=4) + { + + glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]); + + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + } + } + else + { + for (int i=0;i<numindices;i+=4) + { + char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + // This looks curiously endian unsafe to me. + // However it depends on the way the colors are packed into + // the m_rgba field of RAS_TexVert + + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + } + } + glEnd(); + break; + } + case 0: + { + glBegin(GL_TRIANGLES); + vindex=0; + if (useObjectColor) + { + for (int i=0;i<numindices;i+=3) + { + + glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]); + + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + } + } + else + { + for (int i=0;i<numindices;i+=3) + { + + char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + } + } + glEnd(); + break; + } + default: + { + } + + } // switch + } // for each vertexarray + +} + +void RAS_OpenGLRasterizer::IndexPrimitives_Ex(const vecVertexArray & vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor + ) +{ + bool recalc; + static const GLsizei vtxstride = sizeof(RAS_TexVert); + GLenum drawmode; + switch (mode) + { + case 0: + drawmode = GL_TRIANGLES; + break; + case 1: + drawmode = GL_LINES; + break; + case 2: + drawmode = GL_QUADS; + break; + default: + drawmode = GL_LINES; + break; + } + + const RAS_TexVert* vertexarray ; + int numindices,vt; + + for (vt=0;vt<vertexarrays.size();vt++) + { + vertexarray = &((*vertexarrays[vt]) [0]); + const KX_IndexArray & indexarray = (*indexarrays[vt]); + numindices = indexarray.size(); + + int numverts = vertexarrays[vt]->size(); + + if (!numindices) + break; + + int vindex=0; + switch (mode) + { + case 1: + { + glBegin(GL_LINES); + vindex=0; + for (int i=0;i<numindices;i+=2) + { + glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ()); + glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ()); + } + glEnd(); + } + break; + case 2: + { + glBegin(GL_QUADS); + vindex=0; + if (useObjectColor) + { + for (int i=0;i<numindices;i+=4) + { + MT_Point3 mv1, mv2, mv3, mv4, fnor; + /* Calc a new face normal */ + + if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL) + recalc= true; + else + recalc=false; + + if (recalc){ + mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ()); + mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ()); + mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ()); + mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ()); + + fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized(); + + glNormal3f(fnor[0], fnor[1], fnor[2]); + } + + glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]); + + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + } + } + else + { + for (int i=0;i<numindices;i+=4) + { + char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + // This looks curiously endian unsafe to me. + // However it depends on the way the colors are packed into + // the m_rgba field of RAS_TexVert + MT_Point3 mv1, mv2, mv3, mv4, fnor; + /* Calc a new face normal */ + + if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL) + recalc= true; + else + recalc=false; + + + if (recalc){ + mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ()); + mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ()); + mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ()); + mv4 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ()); + + fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))).safe_normalized(); + + glNormal3f(fnor[0], fnor[1], fnor[2]); + } + + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + } + } + glEnd(); + break; + } + case 0: + { + glBegin(GL_TRIANGLES); + vindex=0; + if (useObjectColor) + { + for (int i=0;i<numindices;i+=3) + { + MT_Point3 mv1, mv2, mv3, fnor; + /* Calc a new face normal */ + + if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL) + recalc= true; + else + recalc=false; + + if (recalc){ + mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ()); + mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ()); + mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ()); + + fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized(); + glNormal3f(fnor[0], fnor[1], fnor[2]); + } + + glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]); + + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + } + } + else + { + for (int i=0;i<numindices;i+=3) + { + MT_Point3 mv1, mv2, mv3, fnor; + /* Calc a new face normal */ + + if (vertexarray[(indexarray[vindex])].getFlag() & TV_CALCFACENORMAL) + recalc= true; + else + recalc=false; + + + if (recalc){ + mv1 = MT_Point3(vertexarray[(indexarray[vindex])].getLocalXYZ()); + mv2 = MT_Point3(vertexarray[(indexarray[vindex+1])].getLocalXYZ()); + mv3 = MT_Point3(vertexarray[(indexarray[vindex+2])].getLocalXYZ()); + + fnor = ((mv2-mv1).cross(mv3-mv2)).safe_normalized(); + glNormal3f(fnor[0], fnor[1], fnor[2]); + } + + char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + glColor4ub(cp[0], cp[1], cp[2], cp[3]); + if (!recalc) + glNormal3sv(vertexarray[(indexarray[vindex])].getNormal()); + glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1()); + glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ()); + vindex++; + } + } + glEnd(); + break; + } + default: + { + } + + } // switch + } // for each vertexarray + +} + + + +void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor + ) +{ + unsigned char* mypointer=NULL; + static const GLsizei vtxstride = sizeof(RAS_TexVert); + GLenum drawmode; + switch (mode) + { + case 0: + drawmode = GL_TRIANGLES; + break; + case 1: + drawmode = GL_LINES; + break; + case 2: + drawmode = GL_QUADS; + break; + default: + drawmode = GL_LINES; + break; + } + + const RAS_TexVert* vertexarray ; + + int numindices ; + int vt; + + if (useObjectColor) + { + glDisableClientState(GL_COLOR_ARRAY); + glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]); + } + else + { + glEnableClientState(GL_COLOR_ARRAY); + } + + for (vt=0;vt<vertexarrays.size();vt++) + { + vertexarray = &((*vertexarrays[vt]) [0]); + const KX_IndexArray & indexarray = (*indexarrays[vt]); + numindices = indexarray.size(); + + int numverts = vertexarrays[vt]->size(); + + if (!numindices) + break; + + int vindex=0; + switch (mode) + { + case 1: + { + glBegin(GL_LINES); + vindex=0; + for (int i=0;i<numindices;i+=2) + { + glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ()); + glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ()); + } + glEnd(); + } + break; + case 2: + { + vindex=0; + for (int i=0;i<numindices;i+=4) + { + float v1[3],v2[3],v3[3],v4[3]; + + char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0]; + v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1]; + v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2]; + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0]; + v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1]; + v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2]; + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0]; + v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1]; + v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2]; + vindex++; + + cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA()); + v4[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0]; + v4[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1]; + v4[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2]; + + vindex++; + + rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,v4); + ClearCachingInfo(); + } + break; + } + case 0: + { + glBegin(GL_TRIANGLES); + vindex=0; + for (int i=0;i<numindices;i+=3) + { + float v1[3],v2[3],v3[3]; + + v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0]; + v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1]; + v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2]; + vindex++; + + v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0]; + v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1]; + v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2]; + vindex++; + + v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0]; + v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1]; + v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2]; + vindex++; + + rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,NULL); + ClearCachingInfo(); + } + glEnd(); + break; + } + default: + { + } + } //switch + } //for each vertexarray +} + + + +void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat) +{ + glMatrixMode(GL_PROJECTION); + double* matrix = &mat(0,0); + glLoadMatrixd(matrix); +} + + +void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_Matrix4x4 & mat) +{ + glMatrixMode(GL_PROJECTION); + double matrix[16]; + /* Get into argument. Looks a bit dodgy, but it's ok. */ + mat.getValue(matrix); + /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */ + glLoadMatrixd(matrix); +} + +MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( + float left, + float right, + float bottom, + float top, + float frustnear, + float frustfar +){ + MT_Matrix4x4 result; + double mat[16]; + + // correction for stereo + if(m_stereomode != RAS_STEREO_NOSTEREO) + { + float near_div_focallength; + // next 2 params should be specified on command line and in Blender publisher + m_focallength = 1.5 * right; // derived from example + m_eyeseparation = 0.18 * right; // just a guess... + + near_div_focallength = frustnear / m_focallength; + switch(m_curreye) + { + case RAS_STEREO_LEFTEYE: + left += 0.5 * m_eyeseparation * near_div_focallength; + right += 0.5 * m_eyeseparation * near_div_focallength; + break; + case RAS_STEREO_RIGHTEYE: + left -= 0.5 * m_eyeseparation * near_div_focallength; + right -= 0.5 * m_eyeseparation * near_div_focallength; + break; + } + // leave bottom, top, bottom and top untouched + } + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(left, right, bottom, top, frustnear, frustfar); + glGetDoublev(GL_PROJECTION_MATRIX, mat); + result.setValue(mat); + + return result; +} + + +// next arguments probably contain redundant info, for later... +void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos, + const MT_Point3 &camLoc, const MT_Quaternion &camOrientQuat) +{ + MT_Matrix4x4 viewMat = mat; + + // correction for stereo + if(m_stereomode != RAS_STEREO_NOSTEREO) + { + MT_Matrix3x3 camOrientMat3x3(camOrientQuat); + MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention + MT_Vector3 unitViewupVec(0.0, 0.0, 1.0); + MT_Vector3 viewDir, viewupVec; + MT_Vector3 eyeline; + + // actual viewDir + viewDir = camOrientMat3x3 * unitViewDir; // this is the moto convention, vector on right hand side + // actual viewup vec + viewupVec = camOrientMat3x3 * unitViewupVec; + + // vector between eyes + eyeline = viewDir.cross(viewupVec); + + switch(m_curreye) + { + case RAS_STEREO_LEFTEYE: + { + // translate to left by half the eye distance + MT_Transform transform; + transform.setIdentity(); + transform.translate(-(eyeline * m_eyeseparation / 2.0)); + viewMat *= transform; + } + break; + case RAS_STEREO_RIGHTEYE: + { + // translate to right by half the eye distance + MT_Transform transform; + transform.setIdentity(); + transform.translate(eyeline * m_eyeseparation / 2.0); + viewMat *= transform; + } + break; + } + } + + // convert row major matrix 'viewMat' to column major for OpenGL + MT_Scalar cammat[16]; + viewMat.getValue(cammat); + MT_CmMatrix4x4 viewCmmat = cammat; + + glMatrixMode(GL_MODELVIEW); + m_viewmatrix = viewCmmat; + glLoadMatrixd(&m_viewmatrix(0,0)); + m_campos = campos; +} + + +const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition() +{ + return m_campos; +} + + + +void RAS_OpenGLRasterizer::LoadViewMatrix() +{ + glLoadMatrixd(&m_viewmatrix(0,0)); +} + + + +void RAS_OpenGLRasterizer::EnableTextures(bool enable) +{ +} + + + +void RAS_OpenGLRasterizer::SetCullFace(bool enable) +{ + if (enable) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); +} + + + +void RAS_OpenGLRasterizer::SetSpecularity(float specX, + float specY, + float specZ, + float specval) +{ + GLfloat mat_specular[] = {specX, specY, specZ, specval}; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); +} + + + +void RAS_OpenGLRasterizer::SetShinyness(float shiny) +{ + GLfloat mat_shininess[] = { shiny }; + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); +} + + + +void RAS_OpenGLRasterizer::SetDiffuse(float difX,float difY,float difZ,float diffuse) +{ + GLfloat mat_diffuse [] = {difX, difY,difZ, diffuse}; + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse); +} + +double RAS_OpenGLRasterizer::GetTime() +{ + return m_time; +} + + diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h new file mode 100644 index 00000000000..9bbb19e8aa5 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -0,0 +1,226 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef __RAS_OPENGLRASTERIZER +#define __RAS_OPENGLRASTERIZER + +#ifdef WIN32 +#pragma warning (disable:4786) +#endif + +#include "MT_CmMatrix4x4.h" +#include <vector> +using namespace std; + + +#include "RAS_IRasterizer.h" +#include "RAS_MaterialBucket.h" +#include "RAS_ICanvas.h" + +/** + * 3D rendering device context. + */ +class RAS_OpenGLRasterizer : public RAS_IRasterizer +{ + + RAS_ICanvas* m_2DCanvas; + + // fogging vars + bool m_fogenabled; + float m_fogstart; + float m_fogdist; + float m_fogr; + float m_fogg; + float m_fogb; + + float m_redback; + float m_greenback; + float m_blueback; + float m_alphaback; + + bool m_bEXT_compiled_vertex_array; + + double m_time; + MT_CmMatrix4x4 m_viewmatrix; + MT_Point3 m_campos; + + int m_stereomode; + int m_curreye; + float m_eyeseparation; + float m_focallength; + int m_noOfScanlines; + +protected: + int m_drawingmode; + /** Stores the caching information for the last material activated. */ + RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo; + +public: + double GetTime(); + RAS_OpenGLRasterizer(RAS_ICanvas* canv); + virtual ~RAS_OpenGLRasterizer(); + + + + enum + { + KX_BOUNDINGBOX = 1, + KX_WIREFRAME, + KX_SOLID, + KX_SHADED, + KX_TEXTURED + }; + + enum + { + KX_DEPTHMASK_ENABLED =1, + KX_DEPTHMASK_DISABLED, + }; + virtual void SetDepthMask(int depthmask); + + virtual void SetMaterial(const RAS_IPolyMaterial& mat); + virtual bool Init(); + virtual void Exit(); + virtual bool BeginFrame(int drawingmode, double time); + virtual void ClearDepthBuffer(); + virtual void ClearCachingInfo(void); + virtual void EndFrame(); + virtual void SetRenderArea(); + + virtual void SetStereoMode(const int stereomode); + virtual bool Stereo(); + virtual void SetEye(const int eye); + virtual void SetEyeSeparation(const float eyeseparation); + virtual void SetFocalLength(const float focallength); + + virtual void SwapBuffers(); + virtual void IndexPrimitives( + const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor + ); + + virtual void IndexPrimitives_Ex( + const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor + ); + + virtual void IndexPrimitives_3DText( + const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor + ); + + virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat); + virtual void SetProjectionMatrix(MT_Matrix4x4 & mat); + virtual void SetViewMatrix( + const MT_Matrix4x4 & mat, + const MT_Vector3& campos, + const MT_Point3 &camLoc, + const MT_Quaternion &camOrientQuat + ); + + virtual const MT_Point3& GetCameraPosition(); + virtual void LoadViewMatrix(); + + virtual void SetFog( + float start, + float dist, + float r, + float g, + float b + ); + + virtual void SetFogColor( + float r, + float g, + float b + ); + + virtual void SetFogStart(float fogstart); + virtual void SetFogEnd(float fogend); + + void DisableFog(); + virtual void DisplayFog(); + + virtual void SetBackColor( + float red, + float green, + float blue, + float alpha + ); + + virtual void SetDrawingMode(int drawingmode); + virtual int GetDrawingMode(); + + virtual void EnableTextures(bool enable); + virtual void SetCullFace(bool enable); + + virtual MT_Matrix4x4 GetFrustumMatrix( + float left, + float right, + float bottom, + float top, + float frustnear, + float frustfar + ); + + virtual void SetSpecularity( + float specX, + float specY, + float specZ, + float specval + ); + + virtual void SetShinyness(float shiny); + virtual void SetDiffuse( + float difX, + float difY, + float difZ, + float diffuse + ); + +}; + +#endif //__RAS_OPENGLRASTERIZER diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp new file mode 100644 index 00000000000..fe582a3d2ee --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp @@ -0,0 +1,215 @@ +#ifdef WIN32 + + +#include "RAS_VAOpenGLRasterizer.h" + + +#include <windows.h> +#include "GL/gl.h" + +typedef void (APIENTRY *GLLOCKARRAYSEXTPTR)(GLint first,GLsizei count); +typedef void (APIENTRY *GLUNLOCKARRAYSEXTPTR)(void); +void APIENTRY RAS_lockfunc(GLint first,GLsizei count) {}; +void APIENTRY RAS_unlockfunc() {}; +GLLOCKARRAYSEXTPTR glLockArraysEXT=RAS_lockfunc; +GLUNLOCKARRAYSEXTPTR glUnlockArraysEXT=RAS_unlockfunc; + + + + +#include "STR_String.h" +#include "RAS_TexVert.h" +#include "MT_CmMatrix4x4.h" +#include "RAS_IRenderTools.h" // rendering text + + +RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas) +:RAS_OpenGLRasterizer(canvas) +{ + int i = 0; +} + + + +RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer() +{ +} + + + +bool RAS_VAOpenGLRasterizer::Init() +{ + + bool result = RAS_OpenGLRasterizer::Init(); + + if (result) + { + // if possible, add extensions to other platforms too, if this + // rasterizer becomes messy just derive one for each platform + // (ie. KX_Win32Rasterizer, KX_LinuxRasterizer etc.) + + glUnlockArraysEXT = reinterpret_cast<GLUNLOCKARRAYSEXTPTR>(wglGetProcAddress("glUnlockArraysEXT")); + if (!glUnlockArraysEXT) + result = false; + + glLockArraysEXT = reinterpret_cast<GLLOCKARRAYSEXTPTR>(wglGetProcAddress("glLockArraysEXT")); + if (!glLockArraysEXT) + result=false; + + glEnableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + return result; +} + + + +void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode) +{ + m_drawingmode = drawingmode; + + switch (m_drawingmode) + { + case KX_BOUNDINGBOX: + { + } + case KX_WIREFRAME: + { + glDisable (GL_CULL_FACE); + break; + } + case KX_TEXTURED: + { + } + case KX_SHADED: + { + glEnableClientState(GL_COLOR_ARRAY); + } + case KX_SOLID: + { + break; + } + default: + { + } + } +} + + + +void RAS_VAOpenGLRasterizer::Exit() +{ + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisable(GL_COLOR_MATERIAL); + + RAS_OpenGLRasterizer::Exit(); +} + + + +void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor) +{ + unsigned char* mypointer=NULL; + static const GLsizei vtxstride = sizeof(RAS_TexVert); + GLenum drawmode; + switch (mode) + { + case 0: + { + drawmode = GL_TRIANGLES; + break; + } + case 2: + { + drawmode = GL_QUADS; + break; + } + case 1: //lines + { + } + default: + { + drawmode = GL_LINES; + break; + } + } + const RAS_TexVert* vertexarray; + int numindices,vt; + if (drawmode != GL_LINES) + { + if (useObjectColor) + { + glDisableClientState(GL_COLOR_ARRAY); + glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]); + } else + { + glColor4d(0,0,0,1.0); + glEnableClientState(GL_COLOR_ARRAY); + } + } + else + { + glColor3d(0,0,0); + } + // use glDrawElements to draw each vertexarray + for (vt=0;vt<vertexarrays.size();vt++) + { + vertexarray = &((*vertexarrays[vt]) [0]); + const KX_IndexArray & indexarray = (*indexarrays[vt]); + numindices = indexarray.size(); + int numverts = vertexarrays[vt]->size(); + + if (!numindices) + break; + + mypointer = (unsigned char*)(vertexarray); + glVertexPointer(3,GL_FLOAT,vtxstride,mypointer); + mypointer+= 3*sizeof(float); + glTexCoordPointer(2,GL_FLOAT,vtxstride,mypointer); + mypointer+= 2*sizeof(float); + glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,mypointer); + mypointer += sizeof(int); + glNormalPointer(GL_SHORT,vtxstride,mypointer); + glLockArraysEXT(0,numverts); + // here the actual drawing takes places + glDrawElements(drawmode,numindices,GL_UNSIGNED_INT,&(indexarray[0])); + glUnlockArraysEXT(); + } +} + + +void RAS_VAOpenGLRasterizer::EnableTextures(bool enable) +{ + if (enable) + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + else + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +bool RAS_VAOpenGLRasterizer::Stereo() +{ +/* + if(m_stereomode == RAS_STEREO_NOSTEREO) + return false; + else + return true; +*/ + return false; +} + + +#endif //WIN32 diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h new file mode 100644 index 00000000000..f2500e02dde --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h @@ -0,0 +1,62 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef __KX_VERTEXARRAYOPENGLRASTERIZER +#define __KX_VERTEXARRAYOPENGLRASTERIZER + +#include "RAS_OpenGLRasterizer.h" + +class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer +{ +public: + RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas); + virtual ~RAS_VAOpenGLRasterizer(); + + virtual bool Init(); + virtual void Exit(); + + virtual bool Stereo(); + virtual void SetDrawingMode(int drawingmode); + + virtual void IndexPrimitives( const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + int mode, + class RAS_IPolyMaterial* polymat, + class RAS_IRenderTools* rendertools, + bool useObjectColor, + const MT_Vector4& rgbacolor); + + + virtual void EnableTextures(bool enable); + +}; + +#endif //__KX_VERTEXARRAYOPENGLRASTERIZER |