Index: source/blender/makesdna/DNA_scene_types.h =================================================================== --- source/blender/makesdna/DNA_scene_types.h (revision 18000) +++ source/blender/makesdna/DNA_scene_types.h (working copy) @@ -310,6 +310,11 @@ /* cineon */ short cineonwhite, cineonblack; float cineongamma; + + /* Dome variables */ + float domesize; + short domeres, pad0; + } RenderData; /* control render convert and shading engine */ Index: source/blender/src/buttons_scene.c =================================================================== --- source/blender/src/buttons_scene.c (revision 18000) +++ source/blender/src/buttons_scene.c (working copy) @@ -1820,6 +1820,7 @@ * RAS_STEREO_ANAGLYPH 5 * RAS_STEREO_SIDEBYSIDE 6 * RAS_STEREO_VINTERLACE 7 + * RAS_STEREO_DOME 8 */ uiBlockBeginAlign(block); uiDefButS(block, ROW, 0, "No Stereo", xco, yco-=30, 88, 19, &(G.scene->r.stereomode), 7.0, 1.0, 0, 0, "Disables stereo"); @@ -1828,7 +1829,10 @@ uiDefButS(block, ROW, 0, "Anaglyph", xco-=180, yco-=21, 88, 19, &(G.scene->r.stereomode), 7.0, 5.0, 0, 0, "Enables anaglyph (Red-Blue) stereo method"); uiDefButS(block, ROW, 0, "Side by Side", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 6.0, 0, 0, "Enables side by side left and right images"); uiDefButS(block, ROW, 0, "V Interlace", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 7.0, 0, 0, "Enables interlaced vertical strips for autostereo display"); - + uiDefButS(block, ROW, 0, "Dome 180º", xco-=180, yco-=21, 88, 19, &(G.scene->r.stereomode), 7.0, 8.0, 0, 0, "Enables Dome View"); + uiDefButF(block, NUM, 0, "Size:", xco+=90, yco, 88, 19, &G.scene->r.domesize, 1.0, 10.0, 0, 0, "Size of the ENV MAP faces"); + uiDefButS(block, NUM, 0, "Res:", xco+=90, yco, 88, 19, &G.scene->r.domeres, 1.0, 5.0, 1.0, 0, "Resolution of the dome - 1 to 50"); + uiBlockEndAlign(block); uiBlockSetDirection(block, UI_TOP); Index: source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp =================================================================== --- source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp (revision 18000) +++ source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp (working copy) @@ -366,6 +366,12 @@ initMathutils(); initVideoTexture(); + //initialize Dome Settings + if(blscene->r.stereomode == RAS_IRasterizer::RAS_STEREO_DOME){ + ketsjiengine->tmpInitDome(); + ketsjiengine->InitDome(); + } + if (sceneconverter) { // convert and add scene @@ -403,7 +409,10 @@ if (render) { // render the frame - ketsjiengine->Render(); + if(blscene->r.stereomode == RAS_IRasterizer::RAS_STEREO_DOME) + RenderDome(); + else + ketsjiengine->Render(); } // test for the ESC key @@ -430,6 +439,9 @@ printf("\nBlender Game Engine Finished\n\n"); exitstring = ketsjiengine->GetExitString(); + //finalize Dome Settings + if(blscene->r.stereomode == RAS_IRasterizer::RAS_STEREO_DOME) + ketsjiengine->EndDome(); // when exiting the mainloop Index: source/gameengine/Ketsji/KX_Camera.cpp =================================================================== --- source/gameengine/Ketsji/KX_Camera.cpp (revision 18000) +++ source/gameengine/Ketsji/KX_Camera.cpp (working copy) @@ -425,7 +425,12 @@ { return m_frustum_culling; } - + +void KX_Camera::SetFrustumCulling(bool frustum) +{ + m_frustum_culling = frustum; +} + void KX_Camera::EnableViewport(bool viewport) { m_camdata.m_viewport = viewport; Index: source/gameengine/Ketsji/KX_Camera.h =================================================================== --- source/gameengine/Ketsji/KX_Camera.h (revision 18000) +++ source/gameengine/Ketsji/KX_Camera.h (working copy) @@ -220,6 +220,11 @@ * Gets this camera's culling status. */ bool GetFrustumCulling() const; + + /** + * Sets this camera's culling status. (for debug only) + */ + void SetFrustumCulling(bool frustum); /** * Sets this camera's viewport status. Index: source/gameengine/Ketsji/KX_Dome.cpp =================================================================== --- source/gameengine/Ketsji/KX_Dome.cpp (revision 0) +++ source/gameengine/Ketsji/KX_Dome.cpp (revision 0) @@ -0,0 +1,1346 @@ +/* $Id$ +----------------------------------------------------------------------------- + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser 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, or go to +http://www.gnu.org/copyleft/lesser.txt. +----------------------------------------------------------------------------- +*/ + +// implementation + +#include <PyObjectPlus.h> +#include <structmember.h> +#include <float.h> +#include <math.h> + + +#include <BIF_gl.h> + +#include "KX_PythonInit.h" +#include "DNA_scene_types.h" +#include "RAS_CameraData.h" +//#include "RAS_MeshObject.h" +#include "BLI_arithb.h" + +#include "KX_Dome.h" +#include "GL/glew.h" +#include "GL/glu.h" + +//#include "ImageBase.h" +//#include "BlendType.h" +//#include "Exception.h" +//#include "Texture.h" + +// constructor +KX_Dome::KX_Dome ( + RAS_ICanvas* canvas, + /// rasterizer + RAS_IRasterizer* rasterizer, + /// render tools + RAS_IRenderTools* rendertools, + /// engine + KX_KetsjiEngine* engine + +)://KX_Scene * scene, KX_Camera * camera) : +// ImageViewport(), + // m_render(true), + // m_scene(scene), + // m_camera(camera), +// m_owncamera(false), +// m_observer(NULL), +// m_mirror(NULL), + m_canvas(canvas), + m_rasterizer(rasterizer), + m_rendertools(rendertools), + m_engine(engine), + m_clip(100.f) +{ + // initialize background colour + setBackground(0, 0, 255, 255); + // retrieve rendering objects + // m_engine = KX_GetActiveEngine(); +// m_rasterizer = m_engine->GetRasterizer(); +// m_canvas = m_engine->GetCanvas(); +// m_rendertools = m_engine->GetRenderTools(); + cubetop.resize(1); + cubebottom.resize(1); + cubeleft.resize(2); + cuberight.resize(2); +} + +static GLenum DomeFaceTarget [6] = { + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_X +}; + +//unsigned int m_DomeFaces; +unsigned int m_DomeFacesTmp[6]; // tmp to store a single render image + +int m_DomeFacesize=512; + +// destructor +KX_Dome::~KX_Dome (void) +{ +// if (m_owncamera) +// m_camera->Release(); +/* + for (int i=0;i<nfacestop;i++){ + for (int j=0;j<3;j++){ + for (int k=0;k<3;k++){ + printf("cubetop[%1d].verts[%1d][%1d]: %2.4f\n", i, j, k, cubetop[i].verts[j][k]); +// cout << cubetop[i].verts[j][k] << std::endl; + } + } + } + */ +} + + +// set background color/ +void KX_Dome::setBackground (int red, int green, int blue, int alpha) +{ + m_background[0] = (red < 0) ? 0.f : (red > 255) ? 1.f : float(red)/255.f; + m_background[1] = (green < 0) ? 0.f : (green > 255) ? 1.f : float(green)/255.f; + m_background[2] = (blue < 0) ? 0.f : (blue > 255) ? 1.f : float(blue)/255.f; + m_background[3] = (alpha < 0) ? 0.f : (alpha > 255) ? 1.f : float(alpha)/255.f; +} + +/* my code ::: */ + +void KX_Dome::Dome_CubeCreate(int cubeRes){ + int i,j; + + //creating faces for the env mapcube 180º Dome + // Top Face - just a triangle + cubetop[0].verts[0][0] = -sqrt(2.0) / 2.0; + cubetop[0].verts[0][1] = 0.0; + cubetop[0].verts[0][2] = 0.5; + cubetop[0].u[0] = 0.0; + cubetop[0].v[0] = 1.0; + + cubetop[0].verts[1][0] = 0.0; + cubetop[0].verts[1][1] = sqrt(2.0) / 2.0; + cubetop[0].verts[1][2] = 0.5; + cubetop[0].u[1] = 0.0; + cubetop[0].v[1] = 0.0; + + cubetop[0].verts[2][0] = sqrt(2.0) / 2.0; + cubetop[0].verts[2][1] = 0.0; + cubetop[0].verts[2][2] = 0.5; + cubetop[0].u[2] = 1.0; + cubetop[0].v[2] = 0.0; + + nfacestop = 1; + + /* Bottom face - just a triangle */ + cubebottom[0].verts[0][0] = -sqrt(2.0) / 2.0; + cubebottom[0].verts[0][1] = 0; + cubebottom[0].verts[0][2] = -0.5; + cubebottom[0].u[0] = 1; + cubebottom[0].v[0] = 0; + + cubebottom[0].verts[1][0] = sqrt(2.0) / 2.0; + cubebottom[0].verts[1][1] = 0; + cubebottom[0].verts[1][2] = -0.5; + cubebottom[0].u[1] = 0; + cubebottom[0].v[1] = 1; + + cubebottom[0].verts[2][0] = 0; + cubebottom[0].verts[2][1] = sqrt(2.0) / 2.0; + cubebottom[0].verts[2][2] = -0.5; + cubebottom[0].u[2] = 0; + cubebottom[0].v[2] = 0; + + nfacesbottom = 1; + + /* Left face - two triangles */ + + cubeleft[0].verts[0][0] = -sqrt(2.0) / 2.0; + cubeleft[0].verts[0][1] = 0; + cubeleft[0].verts[0][2] = -0.5; + cubeleft[0].u[0] = 0; + cubeleft[0].v[0] = 0; + + cubeleft[0].verts[1][0] = 0; + cubeleft[0].verts[1][1] = sqrt(2.0) / 2.0; + cubeleft[0].verts[1][2] = -0.5; + cubeleft[0].u[1] = 1; + cubeleft[0].v[1] = 0; + + cubeleft[0].verts[2][0] = -sqrt(2.0) / 2.0; + cubeleft[0].verts[2][1] = 0; + cubeleft[0].verts[2][2] = 0.5; + cubeleft[0].u[2] = 0; + cubeleft[0].v[2] = 1; + + cubeleft[1].verts[0][0] = -sqrt(2.0) / 2.0; + cubeleft[1].verts[0][1] = 0; + cubeleft[1].verts[0][2] = 0.5; + cubeleft[1].u[0] = 0; + cubeleft[1].v[0] = 1; + + cubeleft[1].verts[1][0] = 0; + cubeleft[1].verts[1][1] = sqrt(2.0) / 2.0; + cubeleft[1].verts[1][2] = -0.5; + cubeleft[1].u[1] = 1; + cubeleft[1].v[1] = 0; + + cubeleft[1].verts[2][0] = 0; + cubeleft[1].verts[2][1] = sqrt(2.0) / 2.0; + cubeleft[1].verts[2][2] = 0.5; + cubeleft[1].u[2] = 1; + cubeleft[1].v[2] = 1; + + nfacesleft = 2; + + /* Right face - two triangles */ + cuberight[0].verts[0][0] = 0; + cuberight[0].verts[0][1] = sqrt(2.0) / 2.0; + cuberight[0].verts[0][2] = -0.5; + cuberight[0].u[0] = 0; + cuberight[0].v[0] = 0; + + cuberight[0].verts[1][0] = sqrt(2.0) / 2.0; + cuberight[0].verts[1][1] = 0; + cuberight[0].verts[1][2] = -0.5; + cuberight[0].u[1] = 1; + cuberight[0].v[1] = 0; + + cuberight[0].verts[2][0] = sqrt(2.0) / 2.0; + cuberight[0].verts[2][1] = 0; + cuberight[0].verts[2][2] = 0.5; + cuberight[0].u[2] = 1; + cuberight[0].v[2] = 1; + + cuberight[1].verts[0][0] = 0; + cuberight[1].verts[0][1] = sqrt(2.0) / 2.0; + cuberight[1].verts[0][2] = -0.5; + cuberight[1].u[0] = 0; + cuberight[1].v[0] = 0; + + cuberight[1].verts[1][0] = sqrt(2.0) / 2.0; + cuberight[1].verts[1][1] = 0; + cuberight[1].verts[1][2] = 0.5; + cuberight[1].u[1] = 1; + cuberight[1].v[1] = 1; + + cuberight[1].verts[2][0] = 0; + cuberight[1].verts[2][1] = sqrt(2.0) / 2.0; + cuberight[1].verts[2][2] = 0.5; + cuberight[1].u[2] = 0; + cuberight[1].v[2] = 1; + + nfacesright = 2; + + //Refine a triangular mesh by bisecting each edge forms 3 new triangles for each existing triangle on each iteration + //Could be made more efficient for drawing if the triangles were ordered in a fan or strip! + +// cubeRes = 3; + for(i=0;i<cubeRes;i++){ + cubetop.resize(4*nfacestop); + Dome_CubeSplitFace(cubetop,&nfacestop); + cubebottom.resize(4*nfacesbottom); + Dome_CubeSplitFace(cubebottom,&nfacesbottom); + cubeleft.resize(4*nfacesleft); + Dome_CubeSplitFace(cubeleft,&nfacesleft); + cuberight.resize(4*nfacesright); + Dome_CubeSplitFace(cuberight,&nfacesright); + } + + // Turn into a hemisphere + for(j=0;j<3;j++){ + for(i=0;i<nfacestop;i++) + cubetop[i].verts[j].normalize(); + for(i=0;i<nfacesbottom;i++) + cubebottom[i].verts[j].normalize(); + for(i=0;i<nfacesleft;i++) + cubeleft[i].verts[j].normalize(); + for(i=0;i<nfacesright;i++) + cuberight[i].verts[j].normalize(); + } + + //flatten onto xz plane + for(j=0;j<3;j++){ + for(i=0;i<nfacestop;i++) + Dome_CubeFlatten(cubetop[i].verts[j]); + for(i=0;i<nfacesbottom;i++) + Dome_CubeFlatten(cubebottom[i].verts[j]); + for(i=0;i<nfacesleft;i++) + Dome_CubeFlatten(cubeleft[i].verts[j]); + for(i=0;i<nfacesright;i++) + Dome_CubeFlatten(cuberight[i].verts[j]); + } +} + +void KX_Dome::Dome_CubeSplitFace(vector <DomeFace>& face, int *nfaces) +{ + int i; + int n1, n2; + + n1 = n2 = *nfaces; + + for(i=0;i<n1;i++){ + + face[n2].verts[0] = (face[i].verts[0] + face[i].verts[1]) /2; + face[n2].verts[1] = face[i].verts[1]; + face[n2].verts[2] = (face[i].verts[1] + face[i].verts[2]) /2; + face[n2].u[0] = (face[i].u[0] + face[i].u[1]) /2; + face[n2].u[1] = face[i].u[1]; + face[n2].u[2] = (face[i].u[1] + face[i].u[2]) /2; + face[n2].v[0] = (face[i].v[0] + face[i].v[1]) /2; + face[n2].v[1] = face[i].v[1]; + face[n2].v[2] = (face[i].v[1] + face[i].v[2]) /2; + + face[n2+1].verts[0] = (face[i].verts[1] + face[i].verts[2]) /2; + face[n2+1].verts[1] = face[i].verts[2]; + face[n2+1].verts[2] = (face[i].verts[2] + face[i].verts[0]) /2; + face[n2+1].u[0] = (face[i].u[1] + face[i].u[2]) /2; + face[n2+1].u[1] = face[i].u[2]; + face[n2+1].u[2] = (face[i].u[2] + face[i].u[0]) /2; + face[n2+1].v[0] = (face[i].v[1] + face[i].v[2]) /2; + face[n2+1].v[1] = face[i].v[2]; + face[n2+1].v[2] = (face[i].v[2] + face[i].v[0]) /2; + + face[n2+2].verts[0] = (face[i].verts[0] + face[i].verts[1]) /2; + face[n2+2].verts[1] = (face[i].verts[1] + face[i].verts[2]) /2; + face[n2+2].verts[2] = (face[i].verts[2] + face[i].verts[0]) /2; + face[n2+2].u[0] = (face[i].u[0] + face[i].u[1]) /2; + face[n2+2].u[1] = (face[i].u[1] + face[i].u[2]) /2; + face[n2+2].u[2] = (face[i].u[2] + face[i].u[0]) /2; + face[n2+2].v[0] = (face[i].v[0] + face[i].v[1]) /2; + face[n2+2].v[1] = (face[i].v[1] + face[i].v[2]) /2; + face[n2+2].v[2] = (face[i].v[2] + face[i].v[0]) /2; + + //face[i].verts[0] = face[i].verts[0] ; + face[i].verts[1] = (face[i].verts[0] + face[i].verts[1]) /2; + face[i].verts[2] = (face[i].verts[0] + face[i].verts[2]) /2; + //face[i].u[0] = face[i].u[0]; + face[i].u[1] = (face[i].u[0] + face[i].u[1]) /2; + face[i].u[2] = (face[i].u[0] + face[i].u[2]) /2; + //face[i].v[0] = face[i].v[0] ; + face[i].v[1] = (face[i].v[0] + face[i].v[1]) /2; + face[i].v[2] = (face[i].v[0] + face[i].v[2]) /2; + + n2 += 3; // number of faces + } + *nfaces = n2; +} + +void KX_Dome::Dome_CubeFlatten(MT_Vector3 & verts){ + double phi, r; + + r = atan2(sqrt(verts[0]*verts[0] + verts[2]*verts[2]), verts[1]); + r /= (MT_PI / 2); + printf("R= %2.4f\n", r); + + phi = atan2(verts[2], verts[0]); + printf("Phi= %2.4f\n", phi); + + verts[0] = r * cos(phi); + verts[1] = 0; // zed, I probably will need to change it to work with BGE axis + verts[2] = r * sin(phi); +} + +void DrawDomeVert(float theta, float phi) +{ + float r = 1.0f; + float x, y, z, nx, ny, nz; + float dtor = 3.1416/180.0; + float ztrans = 1.0; + + nx = sin(dtor * theta) * cos(dtor * phi); + ny = sin(dtor * phi); + nz = cos(dtor * theta) * cos(dtor * phi); + glNormal3f(nx, ny, nz); + + x = r * sin(dtor * theta) * cos(dtor * phi); + y = r * sin(dtor * phi); + z = -ztrans + r * cos(dtor * theta) * cos(dtor * phi); + glVertex4f(x, y, z, 1.0); +} + +void DrawDomeSphere(float del) +{ + float phi, phi2, theta; + + glColor4f(1.0, 1.0, 1.0, 1.0); + // glBegin(GL_TRIANGLE_STRIP); + for (phi = -90.0f; phi < 90.0f; phi += del) { + glBegin(GL_TRIANGLE_STRIP); + + phi2 = phi + del; + + for (theta = -90.0f; theta <= 90.0f; theta += del) { + DrawDomeVert(theta, phi); + DrawDomeVert(theta, phi2); + } + glEnd(); + } +// glEnd(); +} +/* +void KX_Dome::Dome_CubeDraw(unsigned int viewport[4], int m_DomeFaces) +{ + //Skybox => 4 images + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Making the viewport always square + + int can_width = viewport[2]; + int can_height = viewport[3]; + + float ortho_width, ortho_height = 1.0; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + glBegin(GL_TRIANGLES); + glColor3f(0.0f ,0.0f, 1.0f); + glVertex3f( 0.0f, 0.5f, 4.0f); + glColor3f(0.0f ,0.5f, 0.0f); + glVertex3f(-0.5f,-0.5f, 4.0f); + glColor3f(1.0f ,0.0f, 0.0f); + glVertex3f( 0.5f,-0.5f, 4.0f); + glEnd(); + + glEnable(GL_TEXTURE_2D); + +// DomeFacesTmp[0] -> LEFT + glBindTexture(GL_TEXTURE_2D, m_DomeFaces); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.05f, 0.3f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.65f,0.3f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.65f,-0.3f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.05f,-0.3f, 3.0f); + glEnd(); + +// DomeFacesTmp[1] -> RIGHT + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+1); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.65f, 0.3f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(0.05f,0.3f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(0.05f,-0.3f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f( 0.65f,-0.3f, 3.0f); + glEnd(); + +// DomeFacesTmp[2] -> TOP + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+2); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.05f, 0.95f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.65f,0.95f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.65f,0.35f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.05f,0.35f, 3.0f); + glEnd(); + +// DomeFacesTmp[3] -> BOTTOM + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+3); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.05f, -0.35f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.65f,-0.35f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.65f,-0.95f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.05f,-0.95f, 3.0f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); +} +*/ + +void KX_Dome::Dome_CubeDraw(unsigned int viewport[4], int m_DomeFaces) +{ + //correct =>Skybox + int i,j; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Making the viewport always square + + int can_width = viewport[2]; + int can_height = viewport[3]; + + float ortho_width, ortho_height = 1.0; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0.0,-1.0,0.0, 0.0,0.0,0.0, 0.0,0.0,1.0); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); +// glPolygonMode(GL_FRONT, GL_LINE); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + glEnable(GL_TEXTURE_2D); + glColor3f(1.0,1.0,1.0); + + glBindTexture(GL_TEXTURE_2D, m_DomeFaces); + // top triangle + glBegin(GL_TRIANGLES); +// glColor3f(0.0f, 0.0f, 1.0f); + for (i=0;i<nfacestop;i++) { + for (j=0;j<3;j++) { + glTexCoord2f(cubetop[i].u[j],cubetop[i].v[j]); + glVertex3f((GLfloat)cubetop[i].verts[j][0],(GLfloat)cubetop[i].verts[j][1],(GLfloat)cubetop[i].verts[j][2]); + } + } + glEnd(); + + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+1); + // bottom triangle + glBegin(GL_TRIANGLES); +// glColor3f(1.0f, 1.0f, 0.0f); + for (i=0;i<nfacesbottom;i++) { + for (j=0;j<3;j++) { + glTexCoord2f(cubebottom[i].u[j],cubebottom[i].v[j]); + glVertex3f((GLfloat)cubebottom[i].verts[j][0],(GLfloat)cubebottom[i].verts[j][1],(GLfloat)cubebottom[i].verts[j][2]); + } + } + glEnd(); + + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+2); + // left triangle + glBegin(GL_TRIANGLES); +// glColor3f(0.0f, 1.0f, 0.0f); + for (i=0;i<nfacesleft;i++) { + for (j=0;j<3;j++) { + glTexCoord2f(cubeleft[i].u[j],cubeleft[i].v[j]); + glVertex3f((GLfloat)cubeleft[i].verts[j][0],(GLfloat)cubeleft[i].verts[j][1],(GLfloat)cubeleft[i].verts[j][2]); + } + } + glEnd(); + + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+3); + // right triangle + glBegin(GL_TRIANGLES); +// glColor3f(1.0f, 0.0f, 0.0f); + for (i=0;i<nfacesright;i++) { + for (j=0;j<3;j++) { + glTexCoord2f(cuberight[i].u[j],cuberight[i].v[j]); + glVertex3f((GLfloat)cuberight[i].verts[j][0],(GLfloat)cuberight[i].verts[j][1],(GLfloat)cuberight[i].verts[j][2]); + } + } + glEnd(); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); +} +void KX_Dome::RenderDome() +{ + m_engine->Render(); + +/* + KX_Scene* firstscene = *m_scenes.begin(); + const RAS_FrameSettings &framesettings = firstscene->GetFramingType(); + + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); + + // hiding mouse cursor each frame + // (came back when going out of focus and then back in again) + if (m_hideCursor) + m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); + + // clear the entire game screen with the border color + // only once per frame + m_canvas->BeginDraw(); + if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) { + m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight()); + if (m_overrideFrameColor) + { + // Do not use the framing bar color set in the Blender scenes + m_canvas->ClearColor( + m_overrideFrameColorR, + m_overrideFrameColorG, + m_overrideFrameColorB, + 1.0 + ); + } + else + { + // Use the framing bar color set in the Blender scenes + m_canvas->ClearColor( + framesettings.BarRed(), + framesettings.BarGreen(), + framesettings.BarBlue(), + 1.0 + ); + } + // clear the -whole- viewport + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); + } + + m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_LEFTEYE); + + // BeginFrame() sets the actual drawing area. You can use a part of the window + if (!BeginFrame()) + return; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + KX_Camera* cam = scene->GetActiveCamera(); + // pass the scene's worldsettings to the rasterizer + SetWorldSettings(scene->GetWorldInfo()); + + // shadow buffers + RenderShadowBuffers(scene); + + // Avoid drawing the scene with the active camera twice when it's viewport is enabled + if(cam && !cam->GetViewport()) + { + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + // dome checking + if(m_rasterizer->GetStereoMode()==RAS_IRasterizer::RAS_STEREO_DOME) + RenderDomeFrame(scene,cam); + else + RenderFrame(scene, cam); + } + + list<class KX_Camera*>* cameras = scene->GetCameras(); + + // Draw the scene once for each camera with an enabled viewport + list<KX_Camera*>::iterator it = cameras->begin(); + while(it != cameras->end()) + { + if((*it)->GetViewport()) + { + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + if(m_rasterizer->GetStereoMode()==RAS_IRasterizer::RAS_STEREO_DOME) + RenderDomeFrame(scene, (*it)); + else + RenderFrame(scene, (*it)); + } + + it++; + } + } + + // only one place that checks for stereo + if(m_rasterizer->Stereo()) + { + m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_RIGHTEYE); + + if (!BeginFrame()) + return; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + KX_Camera* cam = scene->GetActiveCamera(); + + // pass the scene's worldsettings to the rasterizer + SetWorldSettings(scene->GetWorldInfo()); + + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + //pass the scene, for picking and raycasting (shadows) + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + //RenderFrame(scene); + RenderFrame(scene, cam); + } + } // if(m_rasterizer->Stereo()) + + EndFrame(); +*/ +} +/* +void KX_Dome::Dome_CubeDraw(unsigned int viewport[4], int m_DomeFaces) +{ +//tmp, cubemap + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // + + int can_width = viewport[2]; + int can_height = viewport[3]; + + float ortho_width, ortho_height; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + //Start to Draw + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + glDisable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_CUBE_MAP, m_DomeFaces); + // Commands to Enable EnvMap + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glEnable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glEnable(GL_NORMALIZE); + + DrawDomeSphere(9.0); + + glDisable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_DEPTH_TEST); +} +*/ +/* +// capture image from viewport +void KX_Dome::calcImage (unsigned int texId) +{ + if (m_rasterizer->GetDrawingMode() != RAS_IRasterizer::KX_TEXTURED || // no need for texture + m_camera->GetViewport() || // camera must be inactive + m_camera == m_scene->GetActiveCamera()) + { + // no need to compute texture in non texture rendering + m_avail = false; + return; + } + // render the scene from the camera + Render(); + // get image from viewport + ImageViewport::calcImage(texId); + // restore OpenGL state + m_canvas->EndFrame(); +} +*/ +/* +void ImageRender::Render() +{ + RAS_FrameFrustum frustrum; + + if (!m_render) + return; + + if (m_mirror) + { + // mirror mode, compute camera frustrum, position and orientation + // convert mirror position and normal in world space + const MT_Matrix3x3 & mirrorObjWorldOri = m_mirror->GetSGNode()->GetWorldOrientation(); + const MT_Point3 & mirrorObjWorldPos = m_mirror->GetSGNode()->GetWorldPosition(); + const MT_Vector3 & mirrorObjWorldScale = m_mirror->GetSGNode()->GetWorldScaling(); + MT_Point3 mirrorWorldPos = + mirrorObjWorldPos + mirrorObjWorldScale * (mirrorObjWorldOri * m_mirrorPos); + MT_Vector3 mirrorWorldZ = mirrorObjWorldOri * m_mirrorZ; + // get observer world position + const MT_Point3 & observerWorldPos = m_observer->GetSGNode()->GetWorldPosition(); + // get plane D term = mirrorPos . normal + MT_Scalar mirrorPlaneDTerm = mirrorWorldPos.dot(mirrorWorldZ); + // compute distance of observer to mirror = D - observerPos . normal + MT_Scalar observerDistance = mirrorPlaneDTerm - observerWorldPos.dot(mirrorWorldZ); + // if distance < 0.01 => observer is on wrong side of mirror, don't render + if (observerDistance < 0.01f) + return; + // set camera world position = observerPos + normal * 2 * distance + MT_Point3 cameraWorldPos = observerWorldPos + (MT_Scalar(2.0)*observerDistance)*mirrorWorldZ; + m_camera->GetSGNode()->SetLocalPosition(cameraWorldPos); + // set camera orientation: z=normal, y=mirror_up in world space, x= y x z + MT_Vector3 mirrorWorldY = mirrorObjWorldOri * m_mirrorY; + MT_Vector3 mirrorWorldX = mirrorObjWorldOri * m_mirrorX; + MT_Matrix3x3 cameraWorldOri( + mirrorWorldX[0], mirrorWorldY[0], mirrorWorldZ[0], + mirrorWorldX[1], mirrorWorldY[1], mirrorWorldZ[1], + mirrorWorldX[2], mirrorWorldY[2], mirrorWorldZ[2]); + m_camera->GetSGNode()->SetLocalOrientation(cameraWorldOri); + m_camera->GetSGNode()->UpdateWorldData(0.0); + // compute camera frustrum: + // get position of mirror relative to camera: offset = mirrorPos-cameraPos + MT_Vector3 mirrorOffset = mirrorWorldPos - cameraWorldPos; + // convert to camera orientation + mirrorOffset = mirrorOffset * cameraWorldOri; + // scale mirror size to world scale: + // get closest local axis for mirror Y and X axis and scale height and width by local axis scale + MT_Scalar x, y; + x = fabs(m_mirrorY[0]); + y = fabs(m_mirrorY[1]); + float height = (x > y) ? + ((x > fabs(m_mirrorY[2])) ? mirrorObjWorldScale[0] : mirrorObjWorldScale[2]): + ((y > fabs(m_mirrorY[2])) ? mirrorObjWorldScale[1] : mirrorObjWorldScale[2]); + x = fabs(m_mirrorX[0]); + y = fabs(m_mirrorX[1]); + float width = (x > y) ? + ((x > fabs(m_mirrorX[2])) ? mirrorObjWorldScale[0] : mirrorObjWorldScale[2]): + ((y > fabs(m_mirrorX[2])) ? mirrorObjWorldScale[1] : mirrorObjWorldScale[2]); + width *= m_mirrorHalfWidth; + height *= m_mirrorHalfHeight; + // left = offsetx-width + // right = offsetx+width + // top = offsety+height + // bottom = offsety-height + // near = -offsetz + // far = near+100 + frustrum.x1 = mirrorOffset[0]-width; + frustrum.x2 = mirrorOffset[0]+width; + frustrum.y1 = mirrorOffset[1]-height; + frustrum.y2 = mirrorOffset[1]+height; + frustrum.camnear = -mirrorOffset[2]; + frustrum.camfar = -mirrorOffset[2]+m_clip; + } + const float ortho = 100.0; + const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); + + // The screen area that ImageViewport will copy is also the rendering zone + m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0]-1, m_position[1]+m_capSize[1]-1); + m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]); + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); + m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,m_engine->GetClockTime()); + m_rendertools->BeginFrame(m_rasterizer); + m_engine->SetWorldSettings(m_scene->GetWorldInfo()); + m_rendertools->SetAuxilaryClientInfo(m_scene); + m_rasterizer->DisplayFog(); + // matrix calculation, don't apply any of the stereo mode + m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO); + if (m_mirror) + { + // frustrum was computed above + // get frustrum matrix and set projection matrix + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + + m_camera->SetProjectionMatrix(projmat); + } else if (m_camera->hasValidProjectionMatrix()) + { + m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix()); + } else + { + float lens = m_camera->GetLens(); + bool orthographic = !m_camera->GetCameraData()->m_perspective; + float nearfrust = m_camera->GetCameraNear(); + float farfrust = m_camera->GetCameraFar(); + float aspect_ratio = 1.0f; + Scene *blenderScene = m_scene->GetBlenderScene(); + + if (orthographic) { + lens *= ortho; + nearfrust = (nearfrust + 1.0)*ortho; + farfrust *= ortho; + } + // compute the aspect ratio from frame blender scene settings so that render to texture + // works the same in Blender and in Blender player + if (blenderScene->r.ysch != 0) + aspect_ratio = float(blenderScene->r.xsch) / float(blenderScene->r.ysch); + + RAS_FramingManager::ComputeDefaultFrustum( + nearfrust, + farfrust, + lens, + aspect_ratio, + frustrum); + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + + m_camera->SetProjectionMatrix(projmat); + } + + MT_Transform camtrans(m_camera->GetWorldToCamera()); + if (!m_camera->GetCameraData()->m_perspective) + camtrans.getOrigin()[2] *= ortho; + MT_Matrix4x4 viewmat(camtrans); + + m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), + m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + m_camera->SetModelviewMatrix(viewmat); + // restore the stereo mode now that the matrix is computed + m_rasterizer->SetStereoMode(stereomode); + + // do not update the mesh, we don't want to do it more than once per frame + //m_scene->UpdateMeshTransformations(); + + m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera); + + m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); +} +*/ +/* +// cast Image pointer to ImageRender +inline ImageRender * getImageRender (PyImage * self) +{ return static_cast<ImageRender*>(self->m_image); } +*/ + +// python methods + +// Blender Scene type +//BlendType<KX_Scene> sceneType ("KX_Scene"); +// Blender Camera type +//BlendType<KX_Camera> cameraType ("KX_Camera"); + +/* +// object initialization +static int ImageRender_init (PyObject * pySelf, PyObject * args, PyObject * kwds) +{ + // parameters - scene object + PyObject * scene; + // camera object + PyObject * camera; + // parameter keywords + static char *kwlist[] = {"sceneObj", "cameraObj", NULL}; + // get parameters + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &scene, &camera)) + return -1; + try + { + // get scene pointer + KX_Scene * scenePtr (NULL); + if (scene != NULL) scenePtr = sceneType.checkType(scene); + // throw exception if scene is not available + if (scenePtr == NULL) THRWEXCP(SceneInvalid, S_OK); + + // get camera pointer + KX_Camera * cameraPtr (NULL); + if (camera != NULL) cameraPtr = cameraType.checkType(camera); + // throw exception if camera is not available + if (cameraPtr == NULL) THRWEXCP(CameraInvalid, S_OK); + + // get pointer to image structure + PyImage * self = reinterpret_cast<PyImage*>(pySelf); + // create source object + if (self->m_image != NULL) delete self->m_image; + self->m_image = new ImageRender(scenePtr, cameraPtr); + } + catch (Exception & exp) + { + exp.report(); + return -1; + } + // initialization succeded + return 0; +} +*/ +/* +// get background color +PyObject * getBackground (PyImage * self, void * closure) +{ + return Py_BuildValue("[BBBB]", + getImageRender(self)->getBackground(0), + getImageRender(self)->getBackground(1), + getImageRender(self)->getBackground(2), + getImageRender(self)->getBackground(3)); +} +*/ +/* +// set color +static int setBackground (PyImage * self, PyObject * value, void * closure) +{ + // check validity of parameter + if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 4 + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1)) + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2)) + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 3))) + { + PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 4 integer between 0 and 255"); + return -1; + } + // set background color + getImageRender(self)->setBackground((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), + (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))), + (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2))), + (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 3)))); + // success + return 0; +} +*/ +/* +// methods structure +static PyMethodDef imageRenderMethods[] = +{ // methods from ImageBase class + {"refresh", (PyCFunction)Image_refresh, METH_NOARGS, "Refresh image - invalidate its current content"}, + {NULL} +}; +// attributes structure +static PyGetSetDef imageRenderGetSets[] = +{ + {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL}, + // attribute from ImageViewport + {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL}, + {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL}, + {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL}, + // attributes from ImageBase class + {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, + {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, + {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL}, + {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL}, + {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL}, + {NULL} +}; +*/ + +/* +// object initialization +static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds) +{ + // parameters - scene object + PyObject * scene; + // reference object for mirror + PyObject * observer; + // object holding the mirror + PyObject * mirror; + // material of the mirror + short materialID = 0; + // parameter keywords + static char *kwlist[] = {"scene", "observer", "mirror", "material", NULL}; + // get parameters + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|h", kwlist, &scene, &observer, &mirror, &materialID)) + return -1; + try + { + // get scene pointer + KX_Scene * scenePtr (NULL); + if (scene != NULL && PyObject_TypeCheck(scene, &KX_Scene::Type)) + scenePtr = static_cast<KX_Scene*>(scene); + else + THRWEXCP(SceneInvalid, S_OK); + + // get observer pointer + KX_GameObject * observerPtr (NULL); + if (observer != NULL && PyObject_TypeCheck(observer, &KX_GameObject::Type)) + observerPtr = static_cast<KX_GameObject*>(observer); + else if (observer != NULL && PyObject_TypeCheck(observer, &KX_Camera::Type)) + observerPtr = static_cast<KX_Camera*>(observer); + else + THRWEXCP(ObserverInvalid, S_OK); + + // get mirror pointer + KX_GameObject * mirrorPtr (NULL); + if (mirror != NULL && PyObject_TypeCheck(mirror, &KX_GameObject::Type)) + mirrorPtr = static_cast<KX_GameObject*>(mirror); + else + THRWEXCP(MirrorInvalid, S_OK); + + // locate the material in the mirror + RAS_IPolyMaterial * material = getMaterial(mirror, materialID); + if (material == NULL) + THRWEXCP(MaterialNotAvail, S_OK); + + // get pointer to image structure + PyImage * self = reinterpret_cast<PyImage*>(pySelf); + + // create source object + if (self->m_image != NULL) + { + delete self->m_image; + self->m_image = NULL; + } + self->m_image = new ImageRender(scenePtr, observerPtr, mirrorPtr, material); + } + catch (Exception & exp) + { + exp.report(); + return -1; + } + // initialization succeded + return 0; +} +*/ +/** +// get background color +PyObject * getClip (PyImage * self, void * closure) +{ + return PyFloat_FromDouble(getImageRender(self)->getClip()); +} +*/ +/* +// set clip +static int setClip (PyImage * self, PyObject * value, void * closure) +{ + // check validity of parameter + double clip; + if (value == NULL || !PyFloat_Check(value) || (clip = PyFloat_AsDouble(value)) < 0.01 || clip > 5000.0) + { + PyErr_SetString(PyExc_TypeError, "The value must be an float between 0.01 and 5000"); + return -1; + } + // set background color + getImageRender(self)->setClip(float(clip)); + // success + return 0; +} +*/ +/* +// attributes structure +static PyGetSetDef imageMirrorGetSets[] = +{ + {(char*)"clip", (getter)getClip, (setter)setClip, (char*)"clipping distance", NULL}, + // attribute from ImageRender + {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL}, + // attribute from ImageViewport + {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL}, + {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL}, + {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL}, + // attributes from ImageBase class + {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, + {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, + {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL}, + {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL}, + {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL}, + {NULL} +}; +*/ +/* +// constructor +ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat) : + ImageViewport(), + m_render(false), + m_scene(scene), + m_observer(observer), + m_mirror(mirror), + m_clip(100.f) +{ + // this constructor is used for automatic planar mirror + // create a camera, take all data by default, in any case we will recompute the frustrum on each frame + RAS_CameraData camdata; + vector<RAS_TexVert*> mirrorVerts; + vector<RAS_TexVert*>::iterator it; + float mirrorArea = 0.f; + float mirrorNormal[3] = {0.f, 0.f, 0.f}; + float mirrorUp[3]; + float dist, vec[3], axis[3]; + float zaxis[3] = {0.f, 0.f, 1.f}; + float yaxis[3] = {0.f, 1.f, 0.f}; + float mirrorMat[3][3]; + float left, right, top, bottom, back; + + m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata); + m_camera->SetName("__mirror__cam__"); + // don't add the camera to the scene object list, it doesn't need to be accessible + m_owncamera = true; + // retrieve rendering objects + m_engine = KX_GetActiveEngine(); + m_rasterizer = m_engine->GetRasterizer(); + m_canvas = m_engine->GetCanvas(); + m_rendertools = m_engine->GetRenderTools(); + // locate the vertex assigned to mat and do following calculation in mesh coordinates + for (int meshIndex = 0; meshIndex < mirror->GetMeshCount(); meshIndex++) + { + RAS_MeshObject* mesh = mirror->GetMesh(meshIndex); + int numPolygons = mesh->NumPolygons(); + for (int polygonIndex=0; polygonIndex < numPolygons; polygonIndex++) + { + RAS_Polygon* polygon = mesh->GetPolygon(polygonIndex); + if (polygon->GetMaterial()->GetPolyMaterial() == mat) + { + RAS_TexVert *v1, *v2, *v3, *v4; + float normal[3]; + float area; + // this polygon is part of the mirror, + v1 = polygon->GetVertex(0); + v2 = polygon->GetVertex(1); + v3 = polygon->GetVertex(2); + mirrorVerts.push_back(v1); + mirrorVerts.push_back(v2); + mirrorVerts.push_back(v3); + if (polygon->VertexCount() == 4) + { + v4 = polygon->GetVertex(3); + mirrorVerts.push_back(v4); + area = CalcNormFloat4((float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), (float*)v4->getXYZ(), normal); + } else + { + area = CalcNormFloat((float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), normal); + } + area = fabs(area); + mirrorArea += area; + VecMulf(normal, area); + VecAddf(mirrorNormal, mirrorNormal, normal); + } + } + } + if (mirrorVerts.size() == 0 || mirrorArea < FLT_EPSILON) + { + // no vertex or zero size mirror + THRWEXCP(MirrorSizeInvalid, S_OK); + } + // compute average normal of mirror faces + VecMulf(mirrorNormal, 1.0f/mirrorArea); + if (Normalize(mirrorNormal) == 0.f) + { + // no normal + THRWEXCP(MirrorNormalInvalid, S_OK); + } + // the mirror plane has an equation of the type ax+by+cz = d where (a,b,c) is the normal vector + // if the mirror is more vertical then horizontal, the Z axis is the up direction. + // otherwise the Y axis is the up direction. + // If the mirror is not perfectly vertical(horizontal), the Z(Y) axis projection on the mirror + // plan by the normal will be the up direction. + if (fabs(mirrorNormal[2]) > fabs(mirrorNormal[1]) && + fabs(mirrorNormal[2]) > fabs(mirrorNormal[0])) + { + // the mirror is more horizontal than vertical + VecCopyf(axis, yaxis); + } + else + { + // the mirror is more vertical than horizontal + VecCopyf(axis, zaxis); + } + dist = Inpf(mirrorNormal, axis); + if (fabs(dist) < FLT_EPSILON) + { + // the mirror is already fully aligned with up axis + VecCopyf(mirrorUp, axis); + } + else + { + // projection of axis to mirror plane through normal + VecCopyf(vec, mirrorNormal); + VecMulf(vec, dist); + VecSubf(mirrorUp, axis, vec); + if (Normalize(mirrorUp) == 0.f) + { + // should not happen + THRWEXCP(MirrorHorizontal, S_OK); + return; + } + } + // compute rotation matrix between local coord and mirror coord + // to match camera orientation, we select mirror z = -normal, y = up, x = y x z + VecCopyf(mirrorMat[2], mirrorNormal); + VecMulf(mirrorMat[2], -1.0f); + VecCopyf(mirrorMat[1], mirrorUp); + Crossf(mirrorMat[0], mirrorMat[1], mirrorMat[2]); + // transpose to make it a orientation matrix from local space to mirror space + Mat3Transp(mirrorMat); + // transform all vertex to plane coordinates and determine mirror position + left = FLT_MAX; + right = -FLT_MAX; + bottom = FLT_MAX; + top = -FLT_MAX; + back = -FLT_MAX; // most backward vertex (=highest Z coord in mirror space) + for (it = mirrorVerts.begin(); it != mirrorVerts.end(); it++) + { + VecCopyf(vec, (float*)(*it)->getXYZ()); + Mat3MulVecfl(mirrorMat, vec); + if (vec[0] < left) + left = vec[0]; + if (vec[0] > right) + right = vec[0]; + if (vec[1] < bottom) + bottom = vec[1]; + if (vec[1] > top) + top = vec[1]; + if (vec[2] > back) + back = vec[2]; + } + // now store this information in the object for later rendering + m_mirrorHalfWidth = (right-left)*0.5f; + m_mirrorHalfHeight = (top-bottom)*0.5f; + if (m_mirrorHalfWidth < 0.01f || m_mirrorHalfHeight < 0.01f) + { + // mirror too small + THRWEXCP(MirrorTooSmall, S_OK); + } + // mirror position in mirror coord + vec[0] = (left+right)*0.5f; + vec[1] = (top+bottom)*0.5f; + vec[2] = back; + // convert it in local space: transpose again the matrix to get back to mirror to local transform + Mat3Transp(mirrorMat); + Mat3MulVecfl(mirrorMat, vec); + // mirror position in local space + m_mirrorPos.setValue(vec[0], vec[1], vec[2]); + // mirror normal vector (pointed towards the back of the mirror) in local space + m_mirrorZ.setValue(-mirrorNormal[0], -mirrorNormal[1], -mirrorNormal[2]); + m_mirrorY.setValue(mirrorUp[0], mirrorUp[1], mirrorUp[2]); + m_mirrorX = m_mirrorY.cross(m_mirrorZ); + m_render = true; + + setBackground(0, 0, 255, 255); +} + +*/ + + Index: source/gameengine/Ketsji/KX_Dome.h =================================================================== --- source/gameengine/Ketsji/KX_Dome.h (revision 0) +++ source/gameengine/Ketsji/KX_Dome.h (revision 0) @@ -0,0 +1,145 @@ +/* $Id: KX_Dome.h +----------------------------------------------------------------------------- + + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser 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, or go to +http://www.gnu.org/copyleft/lesser.txt. +----------------------------------------------------------------------------- +*/ + +#if !defined KX_DOME_H +#define KX_DOME_H + + +//#include "Common.h" + +#include "KX_Scene.h" +#include "KX_Camera.h" +#include "DNA_screen_types.h" +#include "RAS_ICanvas.h" +#include "RAS_IRasterizer.h" +#include "RAS_IRenderTools.h" +#include "KX_KetsjiEngine.h" + +//#include "ImageViewport.h" +//#include "GL/glew.h" +#include <BIF_gl.h> +#include <vector> + +/// class for render 3d scene +class KX_Dome +{ +public: + /// constructor + KX_Dome ( + RAS_ICanvas* m_canvas, + /// rasterizer + RAS_IRasterizer* m_rasterizer, + /// render tools + RAS_IRenderTools* m_rendertools, + /// engine + KX_KetsjiEngine* m_engine + ); +// KX_Scene * scene, KX_Camera * camera); +// ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat); + + /// destructor + virtual ~KX_Dome (void); + + typedef struct { + double u[3], v[3]; + MT_Vector3 verts[3]; //three verts + } DomeFace; + + vector <DomeFace> cubetop, cubebottom, cubefront, cuberight, cubeleft; + + int nfacestop, nfacesbottom, nfacesleft, nfacesright; + double aperture; + + //old + void DrawDomeVert(float theta, float phi); + void DrawDomeSphere(float del); + + //from initTexture + void setBackground (int red, int green, int blue, int alpha); + + void RenderDome(void); + + // Paul Bourke functions + void Dome_CubeCreate(int cubeRes); + void Dome_CubeSplitFace(vector <DomeFace>& face, int *nfaces); + void Dome_CubeFlatten(MT_Vector3& verts); + void Dome_CubeDraw(unsigned int viewport[4], int m_DomeFaces); + + /// get background color +// int getBackground (int idx) { return (idx < 0 || idx > 3) ? 0 : int(m_background[idx]*255.f); } + /// set background color +// void setBackground (int red, int green, int blue, int alpha); + + /// clipping distance +// float getClip (void) { return m_clip; } + /// set whole buffer use +// void setClip (float clip) { m_clip = clip; } + +protected: + /// true if ready to render +// bool m_render; + /// rendered scene + KX_Scene * m_scene; + /// camera for render + KX_Camera * m_camera; + /// do we own the camera? + // bool m_owncamera; // ???? + /// for mirror operation + + float m_clip; // clipping distance + /// canvas + RAS_ICanvas* m_canvas; + /// rasterizer + RAS_IRasterizer* m_rasterizer; + /// render tools + RAS_IRenderTools* m_rendertools; + /// engine + KX_KetsjiEngine* m_engine; + + /// background colour + float m_background[4]; + + + /// render 3d scene to image +// virtual void calcImage (unsigned int texId); + +// void Render(); +// void SetupRenderFrame(KX_Scene *scene, KX_Camera* cam); +// void RenderFrame(KX_Scene* scene, KX_Camera* cam); +// void SetBackGround(KX_WorldInfo* wi); +// void SetWorldSettings(KX_WorldInfo* wi); +}; + +/* my function here. I don't want to use a class unless I need it */ + +//void DomeDraw(unsigned int viewport[4], int m_DomeFaces); + +/* functions from Paul Bourke */ + +//void Dome_CubeSplitFace(KX_Dome::DomeFace* face, int *nfaces); + +//void Dome_CubeDraw(void); + +//KX_Dome::DomeFace* cubetop, cubebottom, cubefront, cuberight, cubeleft; +//int nfacestop, nfacesbottom, nfacesleft, nfacesright; +//double aperture; + +#endif + Index: source/gameengine/Ketsji/KX_GameObject.cpp =================================================================== --- source/gameengine/Ketsji/KX_GameObject.cpp (revision 18000) +++ source/gameengine/Ketsji/KX_GameObject.cpp (working copy) @@ -884,7 +884,28 @@ } } +void KX_GameObject::NodeSetWorldOrientation(const MT_Matrix3x3& rot){ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return; + + if (m_pPhysicsController1 && !GetSGNode()->GetSGParent()) + { + // see note above + m_pPhysicsController1->setOrientation(rot); + } + +// SG_Node* parent = m_pSGNode->GetSGParent(); +// if (parent != NULL){ + //set worldposition of the parent instead +// parent->SetWorldOrientation(rot); +// GetSGNode()->SetWorldOrientation(rot); +// } +// else + GetSGNode()->SetWorldOrientation(rot); +} + void KX_GameObject::NodeUpdateGS(double time,bool bInitiator) { if (GetSGNode()) Index: source/gameengine/Ketsji/KX_GameObject.h =================================================================== --- source/gameengine/Ketsji/KX_GameObject.h (revision 18000) +++ source/gameengine/Ketsji/KX_GameObject.h (working copy) @@ -365,6 +365,8 @@ // adapt local position so that world position is set to desired position void NodeSetWorldPosition(const MT_Point3& trans); + void NodeSetWorldOrientation(const MT_Matrix3x3& rot ); + void NodeUpdateGS( double time, Index: source/gameengine/Ketsji/KX_KetsjiEngine.cpp =================================================================== --- source/gameengine/Ketsji/KX_KetsjiEngine.cpp (revision 18000) +++ source/gameengine/Ketsji/KX_KetsjiEngine.cpp (working copy) @@ -74,6 +74,11 @@ #include "RAS_FramingManager.h" #include "stdio.h" +#include "KX_Dome.h" + +#include "GL/glew.h" +#include "GL/glu.h" + // If define: little test for Nzc: guarded drawing. If the canvas is // not valid, skip rendering this frame. //#define NZC_GUARDED_OUTPUT @@ -97,8 +102,40 @@ double KX_KetsjiEngine::m_suspendedtime = 0.0; double KX_KetsjiEngine::m_suspendeddelta = 0.0; double KX_KetsjiEngine::m_average_framerate = 0.0; +/* +static const enum KX_KetsjiEngine::DomeFaceTarget { + GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT +}; +*/ +static GLenum DomeFaceTarget [6] = { + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_X +}; +/* +static GLenum DomeFaceTarget [6] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT +}; +*/ +unsigned int DomeFaces[4]; +unsigned int DomeFacesTmp[6]; // tmp to store a single render image +int DomeFaceSize=512; + /** * Constructor of the Ketsji Engine */ @@ -165,7 +202,9 @@ for (int i = tc_first; i < tc_numCategories; i++) m_logger->AddCategory((KX_TimeCategory)i); - + + //Initialize the dome +// m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this); } @@ -176,6 +215,7 @@ KX_KetsjiEngine::~KX_KetsjiEngine() { delete m_logger; + delete m_dome; } @@ -253,8 +293,12 @@ m_sceneconverter = sceneconverter; } +void KX_KetsjiEngine::InitDome() +{ + m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this); + m_dome->Dome_CubeCreate(4); +} - /** * Ketsji Init(), Initializes datastructures and converts data from * Blender into Ketsji native (realtime) format also sets up the @@ -610,11 +654,822 @@ return doRender; } +void KX_KetsjiEngine::tmpInitDome() +{ +// KX_Dome my_dome = KX_Dome(scene,cam); +// KX_Dome *kx_dome = &my_dome; +// m_dome = new KX_Dome(); + //create 6 images + glGenTextures(4, (GLuint*)&DomeFaces); + + for (int i=0;i<4;i++){ + //create tmp texture +// glGenTextures(1, (GLuint*)&DomeFaces[i]); + glBindTexture(GL_TEXTURE_2D, DomeFaces[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, DomeFaceSize, DomeFaceSize, 0, GL_RGBA, + GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + +// glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); +// glGenTextures(1, (GLuint*)&DomeFaces); +// glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); + for (int i=0;i<6;i++){ + glTexImage2D(DomeFaceTarget[i], 0, GL_RGBA, DomeFaceSize, DomeFaceSize, 0, GL_RGBA, + GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP); + } -void KX_KetsjiEngine::Render() + for (int i=0;i<6;i++){ + //create tmp texture + glGenTextures(1, (GLuint*)&DomeFacesTmp[i]); + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, DomeFaceSize, DomeFaceSize, 0, GL_RGBA, + GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } + + printf("\nInitializing Dome\n\n"); + return; +} +void KX_KetsjiEngine::EndDome(){ +// delete m_dome; + //delete the six envmap images created + glDeleteTextures(6, (GLuint*)&DomeFaces); + glDeleteTextures(6, (GLuint*)&DomeFacesTmp); + + printf("\nEnding Dome\n\n"); + return; +} +/* +void DomeDraw(GLuint viewport[4], KX_Dome* dome) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Making the viewport always square + + int can_width = viewport[2]; + int can_height = viewport[3]; + + float ortho_width, ortho_height; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + //Start to Draw + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + glDisable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); + // Commands to Enable EnvMap + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glEnable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glEnable(GL_NORMALIZE); + + dome->DrawDomeSphere(9.0); + + + glDisable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_DEPTH_TEST); +} +*/ +void DomeDrawTmp2(GLuint viewport[4]) +{ + //6 faces tmp + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + /* Making the viewport always square */ + + int can_width = viewport[2]; + int can_height = viewport[3]; + + float ortho_width, ortho_height = 1.0; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + glBegin(GL_TRIANGLES); + glColor3f(0.0f ,0.0f, 1.0f); + glVertex3f( 0.0f, 0.5f, 4.0f); + glColor3f(0.0f ,0.5f, 0.0f); + glVertex3f(-0.5f,-0.5f, 4.0f); + glColor3f(1.0f ,0.0f, 0.0f); + glVertex3f( 0.5f,-0.5f, 4.0f); + glEnd(); + + glEnable(GL_TEXTURE_2D); +// DomeFacesTmp[0] -> GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[0]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.35f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.95f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.95f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.35f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[1] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[1]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.35f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.95f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.95f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.35f,-0.8f, 3.0f); + glEnd(); + +// DomeFacesTmp[2] -> GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[2]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.3f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.3f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.3f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(0.3f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[3] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[3]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.3f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.3f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.3f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(0.3f,-0.8f, 3.0f); + glEnd(); + +// DomeFacesTmp[4] -> GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[4]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.95f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f( 0.35f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f( 0.35f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f( 0.95f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[5] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[5]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.95f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(0.35f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(0.35f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f( 0.95f,-0.8f, 3.0f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); +} +void KX_KetsjiEngine::DomeRotateCamera(KX_Camera* cam, int i){ + + MT_Matrix3x3 locRot [6] = { + MT_Matrix3x3( 0.0, 1.0, 0.0, // 90º - Left + -1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0,-1.0, 0.0, // 90º - Right + 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0, 0.0, 1.0, // 90º - Bottom + 0.0,-1.0, 0.0, + 1.0, 0.0, 0.0), + MT_Matrix3x3( 0.0, 0.0,-1.0, // 90º - Top + 0.0,-1.0, 0.0, + -1.0, 0.0, 0.0), + MT_Matrix3x3( 1.0, 0.0, 0.0, // 0º - Front + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3(-1.0, 0.0, 0.0, // 180º - Back + 0.0,-1.0, 0.0, + 0.0, 0.0, 1.0) + }; + + MT_Quaternion cam_ori = cam->GetCameraOrientation(); + MT_Matrix3x3 cam_node_ori = cam->GetSGNode()->GetLocalOrientation(); + MT_Matrix3x3 gloOri = cam->NodeGetWorldOrientation().inverse(); + +// cam->NodeSetWorldOrientation(locRot[i]*cam_node_ori); + + MT_Matrix4x4 cam_mat = cam->GetModelviewMatrix(); + + MT_Vector3 vu = MT_Vector3 (cam_mat[1][0], cam_mat[1][1], cam_mat[1][2]); // view up vector + MT_Vector3 vd = MT_Vector3 (cam_mat[2][0], cam_mat[2][1], cam_mat[2][2]); // view direction + MT_Vector3 vp = MT_Vector3 (cam_mat[3][0], cam_mat[3][1], cam_mat[3][2]); // view position + + cam_mat[3][0] += 10.0; + +// cam->SetModelviewMatrix(cam_mat); + +// m_rasterizer->SetViewMatrix(cam_mat); + +// m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix()); +// cam->NodeSetLocalOrientation(locRot[i]*cam_node_ori); +// cam->GetSGNode()->RelativeRotate(locRot[i],true); +// cam->NodeUpdateGS(0,true); +// MT_Matrix4x4 cam_MM = cam->GetModelviewMatrix(); +// cam_MM *= locRot_4[i]; +// cam->SetModelviewMatrix(cam_MM); +// printf("Rotating Camera !!!!!!\n"); + +} +void KX_KetsjiEngine::DomeRotateView(KX_Camera* cam, int i, MT_Matrix4x4 cam_mat){ +//Mix MatrixMethod +//changing camera +// MT_Matrix4x4 cam_mat = cam->GetModelviewMatrix(); + cam_mat = cam->GetModelviewMatrix(); + + + MT_Vector3 vu = MT_Vector3 (cam_mat[1][0], cam_mat[1][1], cam_mat[1][2]); // view up vector + MT_Vector3 vd = MT_Vector3 (cam_mat[2][0], cam_mat[2][1], cam_mat[2][2]); // view direction + MT_Vector3 vp = MT_Vector3 (cam_mat[3][0], cam_mat[3][1], cam_mat[3][2]); // view position + + vp = cam->NodeGetWorldPosition(); + +// cam->SetModelviewMatrix(cam_mat); + + MT_Vector3 vr; // view right vector + MT_Vector3 vl; // view left vector + + MT_Vector3 vright; + MT_Vector3 vleft; + + vd.normalize(); + vu.normalize(); + + vr = MT_cross(vu, vd); + vr.normalize(); + + vl = MT_cross(vd, vu); + vl.normalize(); + + vright = vr - vd; + vleft = vl - vd; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.0,1.0,cam->GetCameraNear(),cam->GetCameraFar()); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + MT_Matrix3x3 m_lookAt; + switch (i){ + case 0: //top + m_lookAt = MT_Matrix3x3(vp[0],vp[1],vp[2],(vp[0]+vu[0]),(vp[1]+vu[1]),(vp[2]+vu[2]),-vright[0],-vright[1],-vright[2]); + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vu[0]),(vp[1]+vu[1]),(vp[2]+vu[2]),-vright[0],-vright[1],-vright[2]); + break; + case 1: //bottom + m_lookAt = MT_Matrix3x3(vp[0],vp[1],vp[2],(vp[0]-vu[0]),(vp[1]-vu[1]),(vp[2]-vu[2]),-vleft[0],-vleft[1],-vleft[2]); + gluLookAt(vp[0],vp[1],vp[2],(vp[0]-vu[0]),(vp[1]-vu[1]),(vp[2]-vu[2]),-vleft[0],-vleft[1],-vleft[2]); + break; + case 2: // left + m_lookAt = MT_Matrix3x3(vp[0],vp[1],vp[2],(vp[0] +vleft[0]),(vp[1] +vleft[1]),(vp[2]+vleft[2]),vu[0], vu[1], vu[2]); + gluLookAt(vp[0],vp[1],vp[2],(vp[0] +vleft[0]),(vp[1] +vleft[1]),(vp[2]+vleft[2]),vu[0], vu[1], vu[2]); + break; + case 3: // right + m_lookAt = MT_Matrix3x3(vp[0],vp[1],vp[2],(vp[0]+vright[0]),(vp[1]+vright[1]),(vp[2]+vright[2]),vu[0],vu[1],vu[2]); + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vright[0]),(vp[1]+vright[1]),(vp[2]+vright[2]),vu[0],vu[1],vu[2]); + break; + default: + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vd[0]),(vp[1]+vd[1]),(vp[2]+vd[2]),vu[0],vu[1],vu[2]); + break; + }; + + // implementing a manual gluLookAt() + MT_Vector3 m_vd = m_lookAt[1]; + MT_Vector3 m_vu = m_lookAt[2]; + + MT_Vector3 f = m_vd - vp; + MT_Vector3 s = f * m_vu; + MT_Vector3 u = s * f; + + MT_Matrix4x4 n_cam_mat = MT_Matrix4x4(s[0], s[1], s[2], 0.0, + u[0], u[1], u[2], 0.0, + -f[0],-f[1],-f[2], 0.0, + 0.0, 0.0, 0.0, 0.0); + n_cam_mat = cam_mat * n_cam_mat; + +// glMatrixMode(GL_MODELVIEW); +// glLoadIdentity(); +// glMultMatrixfv(n_cam_mat); +// +// cam->SetModelviewMatrix(n_cam_mat); +// m_rasterizer->SetViewMatrix(n_cam_mat, cam->NodeGetWorldPosition(), cam->GetCameraLocation(), cam->GetCameraOrientation()); + +} +/* +void DomeRotateView(KX_Camera* cam, int i){ +//Mix MatrixMethod + MT_Matrix4x4 cam_mat = cam->GetModelviewMatrix(); + + MT_Vector3 vu = MT_Vector3 (cam_mat[1][0], cam_mat[1][1], cam_mat[1][2]); // view up vector + MT_Vector3 vd = MT_Vector3 (cam_mat[2][0], cam_mat[2][1], cam_mat[2][2]); // view direction + MT_Vector3 vp = MT_Vector3 (cam_mat[3][0], cam_mat[3][1], cam_mat[3][2]); // view position + MT_Vector3 aup = MT_Vector3 (0.0,0.0,1.0); + + vp = cam->NodeGetWorldPosition(); + +// cam->SetModelviewMatrix(cam_mat); + + MT_Vector3 vr; // view right vector + MT_Vector3 vl; // view left vector + + MT_Vector3 vright; + MT_Vector3 vleft; + + vd.normalize(); + vu.normalize(); + + vr = MT_cross(vu, vd); + vr.normalize(); + + vl = MT_cross(vd, vu); + vl.normalize(); + + vright = vr - vd; + vleft = vl - vd; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.0,1.0,cam->GetCameraNear(),cam->GetCameraFar()); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + switch (i){ + case 0: //top + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vu[0]),(vp[1]+vu[1]),(vp[2]+vu[2]),-vright[0],-vright[1],-vright[2]); + break; + case 1: //bottom + gluLookAt(vp[0],vp[1],vp[2],(vp[0]-vu[0]),(vp[1]-vu[1]),(vp[2]-vu[2]),-vleft[0],-vleft[1],-vleft[2]); + break; + case 2: // left + gluLookAt(vp[0],vp[1],vp[2],(vp[0] +vleft[0]),(vp[1] +vleft[1]),(vp[2]+vleft[2]),vu[0], vu[1], vu[2]); + break; + case 3: // right + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vright[0]),(vp[1]+vright[1]),(vp[2]+vright[2]),vu[0],vu[1],vu[2]); + break; + default: + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vd[0]),(vp[1]+vd[1]),(vp[2]+vd[2]),vu[0],vu[1],vu[2]); + break; + }; +} +*/ +void DomeRotateViewPaul(KX_Camera* cam, int i){ +//PaulBourke +// SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), +// m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + + MT_Matrix3x3 camOrientMat3x3(cam->GetCameraOrientation()); + +// MT_Matrix3x3 camOrientMat3x3(cam->NodeGetWorldOrientation()); + +// MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention + 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 viewcrossleftVec, viewcrossrightVec; + MT_Vector3 viewleftVec, viewrightVec; + MT_Vector3 viewPos = cam->NodeGetWorldPosition(); + + // actual viewDir + viewDir = camOrientMat3x3 * unitViewDir; // this is the moto convention, vector on right hand side + // actual viewup vec + viewupVec = camOrientMat3x3 * unitViewupVec; + + // vector left to the camera + viewcrossleftVec = viewupVec.cross(viewDir); + + // vector right to the camera + viewcrossrightVec = viewDir.cross(viewupVec); + + //I don't think I really need a safe_normalized here (a regular normalized should work) + viewDir.safe_normalized(); + viewupVec.safe_normalized(); + viewcrossrightVec.safe_normalized(); + viewcrossleftVec.safe_normalized(); + + viewrightVec = viewcrossrightVec + viewDir; + viewleftVec = viewcrossleftVec + viewDir; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.0,1.0,cam->GetCameraNear(),cam->GetCameraFar()); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + switch (i){ + case 0: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0] +viewleftVec[0]),(viewPos[1] +viewleftVec[1]),(viewPos[2]+viewleftVec[2]),viewupVec[0], viewupVec[1], viewupVec[2]); + break; + case 1: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0]+viewrightVec[0]),(viewPos[1]+viewrightVec[1]),(viewPos[2]+viewrightVec[2]),viewupVec[0],viewupVec[1],viewupVec[2]); + break; + case 2: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0]+viewupVec[0]),(viewPos[1]+viewupVec[1]),(viewPos[2]+viewupVec[2]),-viewrightVec[0],-viewrightVec[1],-viewrightVec[2]); + break; + case 3: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0]-viewupVec[0]),(viewPos[1]-viewupVec[1]),(viewPos[2]-viewupVec[2]),-viewleftVec[0],-viewleftVec[1],-viewleftVec[2]); + break; + case 4: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0]-viewupVec[0]),(viewPos[1]-viewupVec[1]),(viewPos[2]-viewupVec[2]),-viewleftVec[0],-viewleftVec[1],-viewleftVec[2]); + break; + case 5: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0] +viewDir[0]),(viewPos[1] +viewDir[1]),(viewPos[2]+viewDir[2]),viewupVec[0], viewupVec[1], viewupVec[2]); + break; + }; + + +// MT_Scalar glviewmat[16]; +// m_viewmatrix.getValue(glviewmat); + +// glMatrixMode(GL_MODELVIEW); +// glLoadMatrixd(glviewmat); +} +void DomeRotateViewOld(KX_Camera* cam, int i){ + + MT_Matrix4x4 cam_mat = cam->GetModelviewMatrix(); + + MT_Vector3 vu = MT_Vector3 (cam_mat[1][0], cam_mat[1][1], cam_mat[1][2]); // view up vector + MT_Vector3 vd = MT_Vector3 (cam_mat[2][0], cam_mat[2][1], cam_mat[2][2]); // view direction + MT_Vector3 vp = MT_Vector3 (cam_mat[3][0], cam_mat[3][1], cam_mat[3][2]); // view position + +// cam_mat[3][0] += 10.0; + +// cam->SetModelviewMatrix(cam_mat); + + MT_Vector3 vr; // view right vector + MT_Vector3 vl; // view left vector + + MT_Vector3 vright; + MT_Vector3 vleft; + + /* vp = view position */ + MT_Point3 pos = cam->NodeGetWorldPosition(); + MT_Point3 ori = MT_Point3 (0.0, 0.0, 0.0); +// vp = pos - ori; +// vp = cam->GetCameraLocation() +// vp = cam->NodeGetWorldPosition(); + + /* vu - view up vector */ +// MT_Matrix3x3 worldori = cam->NodeGetWorldOrientation(); +// vu = cam->PyGetAxisVect(0.0,0.0,1.0); +// vu = worldori * (pos - ori); + + /* vd - view direction */ +// vd = pos - ori; + + vd.safe_normalized(); + vu.safe_normalized(); + + vr = MT_cross(vd, vu); + vr.safe_normalized(); + + vl = MT_cross(vu, vd); + vl.safe_normalized(); + + vright = vr + vd; + vleft = vl + vd; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.0,1.0,cam->GetCameraNear(),cam->GetCameraFar()); + +// GLdouble vp_x = (GLdouble *)vp.x; + + MT_Matrix3x3 locRot [6] = { + MT_Matrix3x3( 0.0, 1.0, 0.0, // 90º - Left + -1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0,-1.0, 0.0, // 90º - Right + 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0, 0.0, 1.0, // 90º - Bottom + 0.0,-1.0, 0.0, + 1.0, 0.0, 0.0), + MT_Matrix3x3( 0.0, 0.0,-1.0, // 90º - Top + 0.0,-1.0, 0.0, + -1.0, 0.0, 0.0), + MT_Matrix3x3( 1.0, 0.0, 0.0, // 0º - Front + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3(-1.0, 0.0, 0.0, // 180º - Back + 0.0,-1.0, 0.0, + 0.0, 0.0, 1.0) + }; + GLfloat directions[] = { + 0.0, 0.0, -1.0, + 0.0, 0.0, 1.0, + 0.0, -1.0, 0.0, + 0.0, 1.0, 0.0, + -1.0, 0.0, 0.0, + 1.0, 0.0, 0.0 + }; + GLfloat ups[] = { + 0.0, -1.0, 0.0, + 0.0, -1.0, 0.0, + 0.0, 0.0, -1.0, + 0.0, 0.0, 1.0, + 0.0, -1.0, 0.0, + 0.0, -1.0, 0.0 + };/* + GLfloat ups[] = { + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0, + 0.0, 0.0, -1.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0 + };*/ + //hand-rotating the camera +// gluLookAt(locRot[i][0][0],locRot[i][0][1],locRot[i][0][2],locRot[i][1][0],locRot[i][1][1],locRot[i][1][2],locRot[i][2][0],locRot[i][2][1],locRot[i][2][2]); + + GLfloat *direction = directions; + GLfloat *up = ups; + + //counter + direction += 3*i; + up += 3*i; + + gluLookAt(0.0, 0.0, 0.0, direction[0], direction[1], direction[2], + up[0], up[1], up[2]); + + float vp_x = vp[0]; +/* + switch (i){ + case 0: +// gluLookAt(locRot[0][0],locRot[0][1],locRot[0][3],locRot[0][4],locRot[0][5],locRot[0][6],locRot[0][7],locRot[0][8]); + gluLookAt(vp[0],vp[1],vp[2],(vp[0] +vleft[0]),(vp[1] +vleft[1]),(vp[2]+vleft[2]),vu[0], vu[1], vu[2]); + break; + case 1: + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vright[0]),(vp[1]+vright[1]),(vp[2]+vright[2]),vu[0],vu[1],vu[2]); + break; + case 2: + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vu[0]),(vp[1]+vu[1]),(vp[2]+vu[2]),-vright[0],-vright[1],-vright[2]); + break; + case 3: + gluLookAt(vp[0],vp[1],vp[2],(vp[0]-vu[0]),(vp[1]-vu[1]),(vp[2]-vu[2]),-vleft[0],-vleft[1],-vleft[2]); + break; + };*/ +} +void DomeBindImages(GLuint viewport[4], int i){ + + // Storing the cubemap image +// glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); +// glCopyTexImage2D(DomeFaceTarget[i], 0, GL_RGBA8, 0, 0, DomeFaceSize, DomeFaceSize, 0); + + //storing the plane image (for tests) + glBindTexture(GL_TEXTURE_2D, DomeFaces[i]); +// glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, viewport[2], viewport[3], 0); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, DomeFaceSize, DomeFaceSize, 0); +} +void KX_KetsjiEngine::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam) +{ + //routine to render the dome + const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); + GLuint viewport[4]={0}; + glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); + unsigned int m_viewport[4] = {viewport[0], viewport[1], viewport[2], viewport[3]}; + + //tmp disabling culling + cam->SetFrustumCulling(false); +// KX_Dome my_dome = KX_Dome(scene,cam); +// KX_Dome *kx_dome = &my_dome; + + //the initial orientation of the camera + MT_Matrix4x4 cam_mat = cam->GetModelviewMatrix(); +// cam->SetModelviewMatrix(cam_mat); + MT_Matrix4x4 cam_mat_b = cam->GetModelviewMatrix(); + + DomePreRender(scene,cam); + for (int i=0;i<4;i++){ + DomeRotateView(cam, i, cam_mat); +// DomeRotateCamera(cam, i); + DomeRenderRoutine(scene, cam); + DomeBindImages(viewport, i); + } +// cam->SetModelviewMatrix(cam_mat); + DomePostRender(scene,cam,stereomode); + m_canvas->EndFrame(); +// m_dome->Dome_CubeCreate(1); // in Dome.cpp + m_dome->Dome_CubeDraw(m_viewport,DomeFaces[0]); + //DomeDraw(m_viewport, DomeFaces); +} +void KX_KetsjiEngine::DomePreRender(KX_Scene* m_scene, KX_Camera* m_camera) +{ + // The final one + RAS_FrameFrustum frustrum; +// const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); + + //Set the viewport to be of the size of the Dome face + m_canvas->SetViewPort(0,0, DomeFaceSize, DomeFaceSize); + m_canvas->ClearColor(m_overrideFrameColorR,m_overrideFrameColorB,m_overrideFrameColorB,1.0); + + m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,GetClockTime()); + m_rendertools->BeginFrame(m_rasterizer); + SetWorldSettings(m_scene->GetWorldInfo()); + m_rendertools->SetAuxilaryClientInfo(m_scene); + m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO); + + m_rasterizer->DisplayFog(); + + if (m_camera->hasValidProjectionMatrix()) + { + m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix()); + } else + { + float lens = m_camera->GetLens(); + bool orthographic = !m_camera->GetCameraData()->m_perspective; + float nearfrust = m_camera->GetCameraNear(); + float farfrust = m_camera->GetCameraFar(); + float aspect_ratio = 1.0f; + + + RAS_FramingManager::ComputeDefaultFrustum( + nearfrust, + farfrust, + lens, + aspect_ratio, + frustrum); + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + + m_camera->SetProjectionMatrix(projmat); + } + + MT_Transform camtrans(m_camera->GetWorldToCamera()); + MT_Matrix4x4 viewmat(camtrans); + + m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), + m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + m_camera->SetModelviewMatrix(viewmat); + + m_scene->UpdateMeshTransformations(); +} +void KX_KetsjiEngine::DomeRenderRoutine(KX_Scene* m_scene, KX_Camera* m_camera) +{ + MT_Transform camtrans(m_camera->GetWorldToCamera()); + m_canvas->ClearColor(m_overrideFrameColorR,m_overrideFrameColorB,m_overrideFrameColorB,1.0); + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); + + m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera); + m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); +} +void KX_KetsjiEngine::DomePostRender(KX_Scene* m_scene, KX_Camera* m_camera, RAS_IRasterizer::StereoMode stereomode) +{ + m_rasterizer->SetStereoMode(stereomode); + //restore glViewport(); + //restore glScissor(); +// m_canvas->SetViewport(viewport[0], viewport[1], viewport[2], viewport[3]); +} +void KX_KetsjiEngine::DomeImageRender(KX_Scene* m_scene, KX_Camera* m_camera) +{ + RAS_FrameFrustum frustrum; + const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); + + // The screen area that ImageViewport will copy is also the rendering zone +// m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0]-1, m_position[1]+m_capSize[1]-1); + // m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]); + m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight()); + m_canvas->ClearColor(m_overrideFrameColorR,m_overrideFrameColorB,m_overrideFrameColorB,1.0); + + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); +// m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,m_engine->GetClockTime()); + m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,GetClockTime()); + m_rendertools->BeginFrame(m_rasterizer); +// m_engine->SetWorldSettings(m_scene->GetWorldInfo()); + SetWorldSettings(m_scene->GetWorldInfo()); + m_rendertools->SetAuxilaryClientInfo(m_scene); + m_rasterizer->DisplayFog(); + // matrix calculation, don't apply any of the stereo mode + m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO); + + if (m_camera->hasValidProjectionMatrix()) + { + m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix()); + } else + { + float lens = m_camera->GetLens(); + bool orthographic = !m_camera->GetCameraData()->m_perspective; + float nearfrust = m_camera->GetCameraNear(); + float farfrust = m_camera->GetCameraFar(); + float aspect_ratio = 1.0f; +// Scene *blenderScene = m_scene->GetBlenderScene(); + + // compute the aspect ratio from frame blender scene settings so that render to texture + // works the same in Blender and in Blender player + // if (blenderScene->r.ysch != 0) + // aspect_ratio = float(blenderScene->r.xsch) / float(blenderScene->r.ysch); + + RAS_FramingManager::ComputeDefaultFrustum( + nearfrust, + farfrust, + lens, + aspect_ratio, + frustrum); + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + + m_camera->SetProjectionMatrix(projmat); + } + + MT_Transform camtrans(m_camera->GetWorldToCamera()); +// if (!m_camera->GetCameraData()->m_perspective) +// camtrans.getOrigin()[2] *= ortho; + MT_Matrix4x4 viewmat(camtrans); + + m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), + m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + m_camera->SetModelviewMatrix(viewmat); + // restore the stereo mode now that the matrix is computed + m_rasterizer->SetStereoMode(stereomode); + + // do not update the mesh, we don't want to do it more than once per frame + //m_scene->UpdateMeshTransformations(); + + m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera); + + m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); +} +void KX_KetsjiEngine::DomeOriginalRender() +{ KX_Scene* firstscene = *m_scenes.begin(); const RAS_FrameSettings &framesettings = firstscene->GetFramingType(); @@ -737,9 +1592,567 @@ EndFrame(); } +void KX_KetsjiEngine::oldDomeRender(KX_Scene* scene, KX_Camera* cam) +{ + //old file + /* + Render (call Render) + copy (Bind); + rotate; + Render (call Render) + copy (Bind); + Render (call Render) + copy (Bind); + Draw + */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + bool override_camera; + RAS_Rect viewport, area; + float left, right, bottom, top, nearfrust, farfrust, focallength; + const float ortho = 100.0; +// KX_Camera* cam = scene->GetActiveCamera(); + + if (!cam) + return; + GetSceneViewport(scene, cam, area, viewport); + + // store the computed viewport in the scene + scene->SetSceneViewport(viewport); + + // set the viewport for this frame and scene + m_canvas->SetViewPort(viewport.GetLeft(), viewport.GetBottom(), + viewport.GetRight(), viewport.GetTop()); + + // see KX_BlenderMaterial::Activate + //m_rasterizer->SetAmbient(); + m_rasterizer->DisplayFog(); + + override_camera = m_overrideCam && (scene->GetName() == m_overrideSceneName); + override_camera = override_camera && (cam->GetName() == "__default__cam__"); + + if (override_camera && m_overrideCamUseOrtho) { + MT_CmMatrix4x4 projmat = m_overrideCamProjMat; + m_rasterizer->SetProjectionMatrix(projmat); + } else if (cam->hasValidProjectionMatrix() && !cam->GetViewport() ) + { + m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix()); + } else + { + RAS_FrameFrustum frustum; + float lens = cam->GetLens(); + nearfrust = cam->GetCameraNear(); + farfrust = cam->GetCameraFar(); + focallength = cam->GetFocalLength(); + + if(override_camera) { + nearfrust = m_overrideCamNear; + farfrust = m_overrideCamFar; + } + + RAS_FramingManager::ComputeFrustum( + scene->GetFramingType(), + area, + viewport, + lens, + nearfrust, + farfrust, + frustum + ); + + left = frustum.x1 * m_cameraZoom; + right = frustum.x2 * m_cameraZoom; + bottom = frustum.y1 * m_cameraZoom; + top = frustum.y2 * m_cameraZoom; + nearfrust = frustum.camnear; + farfrust = frustum.camfar; + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + left, right, bottom, top, nearfrust, farfrust, focallength); + + cam->SetProjectionMatrix(projmat); + + } + + MT_Transform camtrans(cam->GetWorldToCamera()); + if (!cam->GetCameraData()->m_perspective) + camtrans.getOrigin()[2] *= ortho; + MT_Matrix4x4 viewmat(camtrans); + + scene->UpdateMeshTransformations(); + + MT_Quaternion cam_ori = cam->GetCameraOrientation(); + MT_Matrix3x3 cam_node_ori = cam->GetSGNode()->GetLocalOrientation(); + MT_Matrix3x3 gloOri = cam->NodeGetWorldOrientation().inverse(); +// MT_Matrix3x3 gloOri = cam->NodeGetWorldOrientation(); + + + MT_Matrix3x3 locRot [6] = { + MT_Matrix3x3( 1.0, 0.0, 0.0, // 0º - Front + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3(-1.0, 0.0, 0.0, // 180º - Back + 0.0,-1.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0, 1.0, 0.0, // 90º - Left + -1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0,-1.0, 0.0, // 90º - Right + 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0, 0.0,-1.0, // 90º - Top + 0.0, 1.0, 0.0, + 1.0, 0.0, 0.0), + MT_Matrix3x3( 0.0, 0.0, 1.0, // 90º - Bottom + 0.0, 1.0, 0.0, + -1.0, 0.0, 0.0) + }; + + glEnable(GL_TEXTURE_2D); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + for (int i = 0;i<6;i++){ + + // cam->NodeSetLocalOrientation(locRot*gloOri); + + // cam->NodeSetLocalOrientation(locRot[i]*cam->GetSGNode()->GetLocalOrientation()); + cam->NodeSetLocalOrientation(locRot[i]*cam_node_ori); + // scene->UpdateMeshTransformations(); + + //// RenderDomeCamera(scene, cam, viewmat, camtrans, rotn180); + +/* Code from the top */ + + GetSceneViewport(scene, cam, area, viewport); + + // store the computed viewport in the scene + scene->SetSceneViewport(viewport); + + // set the viewport for this frame and scene + m_canvas->SetViewPort(viewport.GetLeft(), viewport.GetBottom(), + viewport.GetRight(), viewport.GetTop()); + + RAS_FrameFrustum frustum; + float lens = cam->GetLens(); + nearfrust = cam->GetCameraNear(); + farfrust = cam->GetCameraFar(); + focallength = cam->GetFocalLength(); + + if(override_camera) { + nearfrust = m_overrideCamNear; + farfrust = m_overrideCamFar; + } + + RAS_FramingManager::ComputeFrustum( + scene->GetFramingType(), + area, + viewport, + lens, + nearfrust, + farfrust, + frustum + ); + + left = frustum.x1 * m_cameraZoom; + right = frustum.x2 * m_cameraZoom; + bottom = frustum.y1 * m_cameraZoom; + top = frustum.y2 * m_cameraZoom; + nearfrust = frustum.camnear; + farfrust = frustum.camfar; + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + left, right, bottom, top, nearfrust, farfrust, focallength); + + cam->SetProjectionMatrix(projmat); + +/* end: Code from the top */ + + MT_Transform camtrans_b(cam->GetWorldToCamera()); + MT_Matrix4x4 viewmat_b(camtrans_b); + + m_rasterizer->SetViewMatrix(viewmat_b, cam->NodeGetWorldPosition(), + cam->GetCameraLocation(), cam->GetCameraOrientation()); + + // camtrans = cam->GetWorldToCamera(); + // viewmat = camtrans; + + cam->SetModelviewMatrix(viewmat_b); + + + scene->CalculateVisibleMeshes(m_rasterizer,cam); + + scene->UpdateMeshTransformations(); + + glReadBuffer(GL_BACK); + glDrawBuffer(GL_BACK); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); + glFinish(); + + + // save the images +// glActiveTexture(DomeFacesTmp[i]); + +// drawTestTriangle(viewport, i); // test to make each texture different + + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[i]); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, viewport.GetWidth(), viewport.GetHeight(), 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* + unsigned char *pixels; + + // Allocate memory for the pixel data // + if (! (pixels = (unsigned char *)malloc(viewport.GetWidth() * viewport.GetHeight() * 3))) { + fprintf(stderr, "not enough memory for pixel data\n"); + exit(1); + } + + // Read the framebuffer content and create a texture using the image data + // (glCopyTexImage2D does NOT work for this purpose!) // + glReadPixels(viewport.GetLeft(), viewport.GetBottom(), viewport.GetWidth(), viewport.GetHeight(), GL_RGB, + GL_UNSIGNED_BYTE, pixels); +*/ + + } + /* Copy Color Buffer to EnvMap */ +// glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); +// for (int i=0;i<6;i++){ +// glCopyTexImage2D(DomeFaceTarget[i], 0, GL_RGBA8, 0, 0, viewport.GetWidth(), viewport.GetHeight(), 0); +// glCopyTexImage2D(DomeFaceTarget[i], 0, GL_RGBA8, 0, 0, DomeFaceSize, DomeFaceSize, 0); + +/* + unsigned char *pixels; + + // Allocate memory for the pixel data // + if (! (pixels = (unsigned char *)malloc(viewport.GetWidth() * viewport.GetHeight() * 3))) { + fprintf(stderr, "not enough memory for pixel data\n"); + exit(1); + } + + // Read the framebuffer content and create a texture using the image data + // (glCopyTexImage2D does NOT work for this purpose!) // + glReadPixels(viewport.GetLeft(), viewport.GetBottom(), viewport.GetWidth(), viewport.GetHeight(), GL_RGB, + GL_UNSIGNED_BYTE, pixels); + + glTexImage2D(DomeFaceTarget[i], 0, GL_RGB, viewport.GetWidth(), viewport.GetHeight(), 0, GL_RGB, + GL_UNSIGNED_BYTE, pixels); + +*/ +// } + + /* TMP my test */ + /* +//XXX +*/ +// for (int i=0;i<6;i++){ +// glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[i]); +// glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, viewport.GetWidth(), viewport.GetHeight(), 0); +// } +//XXX + + /* Drawing the Sphere on top of the screen */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + /* Making the viewport always square */ + + int can_width = viewport.GetWidth(); + int can_height = viewport.GetHeight(); + + float ortho_width, ortho_height; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + +// glEnable(GL_TEXTURE_CUBE_MAP_EXT); +// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); +/* + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); +*/ + glDisable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_CUBE_MAP); + glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces[0]); +// glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); // original cubemap call + +// DrawDomeSphere(9.0); + + glBegin(GL_TRIANGLES); + glColor3f(0.0f ,0.0f, 1.0f); + glVertex3f( 0.0f, 0.5f, 4.0f); + glColor3f(0.0f ,0.5f, 0.0f); + glVertex3f(-0.5f,-0.5f, 4.0f); + glColor3f(1.0f ,0.0f, 0.0f); + glVertex3f( 0.5f,-0.5f, 4.0f); + glEnd(); + + glDisable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_TEXTURE_2D); +// glBindTexture(GL_TEXTURE_2D, DomeFaces); +// glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[0]); +// glBindTexture(GL_TEXTURE_2D, 7); + +// DomeFacesTmp[0] -> GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[0]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.35f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.95f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.95f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.35f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[1] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[1]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.35f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.95f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.95f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.35f,-0.8f, 3.0f); + glEnd(); + +// DomeFacesTmp[2] -> GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[2]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.3f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.3f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.3f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(0.3f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[3] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[3]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.3f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.3f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.3f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(0.3f,-0.8f, 3.0f); + glEnd(); + +// DomeFacesTmp[4] -> GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[4]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.95f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f( 0.35f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f( 0.35f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f( 0.95f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[5] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[5]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.95f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(0.35f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(0.35f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f( 0.95f,-0.8f, 3.0f); + glEnd(); + +/* + glBegin(GL_QUADS); + glTexCoord2f(1.0,1.0); + glColor3f(0.0f ,0.0f, 1.0f); + glVertex3f( 0.8f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glColor3f(0.0f ,0.5f, 0.0f); + glVertex3f(-0.8f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glColor3f(1.0f ,0.0f, 0.0f); + glVertex3f(-0.8f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glColor3f(0.5f ,0.5f, 0.0f); + glVertex3f(0.8f,-0.8f, 3.0f); + glEnd(); +*/ + + glEnable(GL_DEPTH_TEST); + + PostRenderFrame(); + + printf("\nRendering Dome\n"); +} + +void KX_KetsjiEngine::Render() +{ + KX_Scene* firstscene = *m_scenes.begin(); + const RAS_FrameSettings &framesettings = firstscene->GetFramingType(); + + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); + + // hiding mouse cursor each frame + // (came back when going out of focus and then back in again) + if (m_hideCursor) + m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); + + // clear the entire game screen with the border color + // only once per frame + m_canvas->BeginDraw(); + if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) { + m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight()); + if (m_overrideFrameColor) + { + // Do not use the framing bar color set in the Blender scenes + m_canvas->ClearColor( + m_overrideFrameColorR, + m_overrideFrameColorG, + m_overrideFrameColorB, + 1.0 + ); + } + else + { + // Use the framing bar color set in the Blender scenes + m_canvas->ClearColor( + framesettings.BarRed(), + framesettings.BarGreen(), + framesettings.BarBlue(), + 1.0 + ); + } + // clear the -whole- viewport + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); + } + + m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_LEFTEYE); + + // BeginFrame() sets the actual drawing area. You can use a part of the window + if (!BeginFrame()) + return; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + KX_Camera* cam = scene->GetActiveCamera(); + // pass the scene's worldsettings to the rasterizer + SetWorldSettings(scene->GetWorldInfo()); + + // shadow buffers + RenderShadowBuffers(scene); + + // Avoid drawing the scene with the active camera twice when it's viewport is enabled + if(cam && !cam->GetViewport()) + { + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + // dome checking + if(m_rasterizer->GetStereoMode()==RAS_IRasterizer::RAS_STEREO_DOME) + RenderDomeFrame(scene,cam); + else + RenderFrame(scene, cam); + } + + list<class KX_Camera*>* cameras = scene->GetCameras(); + + // Draw the scene once for each camera with an enabled viewport + list<KX_Camera*>::iterator it = cameras->begin(); + while(it != cameras->end()) + { + if((*it)->GetViewport()) + { + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + if(m_rasterizer->GetStereoMode()==RAS_IRasterizer::RAS_STEREO_DOME) + RenderDomeFrame(scene, (*it)); + else + RenderFrame(scene, (*it)); + } + + it++; + } + } + + // only one place that checks for stereo + if(m_rasterizer->Stereo()) + { + m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_RIGHTEYE); + + if (!BeginFrame()) + return; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + KX_Camera* cam = scene->GetActiveCamera(); + + // pass the scene's worldsettings to the rasterizer + SetWorldSettings(scene->GetWorldInfo()); + + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + //pass the scene, for picking and raycasting (shadows) + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + //RenderFrame(scene); + RenderFrame(scene, cam); + } + } // if(m_rasterizer->Stereo()) + + EndFrame(); +} + + + void KX_KetsjiEngine::RequestExit(int exitrequestmode) { m_exitcode = exitrequestmode; Index: source/gameengine/Ketsji/KX_KetsjiEngine.h =================================================================== --- source/gameengine/Ketsji/KX_KetsjiEngine.h (revision 18000) +++ source/gameengine/Ketsji/KX_KetsjiEngine.h (working copy) @@ -37,6 +37,7 @@ #include "KX_Scene.h" #include "KX_Python.h" #include "KX_WorldInfo.h" +#include "RAS_IRasterizer.h" #include <vector> #include <set> @@ -74,6 +75,7 @@ PyObject* m_pythondictionary; class SCA_IInputDevice* m_keyboarddevice; class SCA_IInputDevice* m_mousedevice; + class KX_Dome* m_dome; // dome stereo mode /** Lists of scenes scheduled to be removed at the end of the frame. */ std::set<STR_String> m_removingScenes; @@ -208,6 +210,31 @@ RAS_ICanvas* GetCanvas(){return m_canvas;}; RAS_IRenderTools* GetRenderTools(){return m_rendertools;}; + /// Dome functions + void InitDome(); //recycled :) + void tmpInitDome(); + void EndDome(); + + void RenderDomeFrame(KX_Scene* scene, KX_Camera* cam); + + void DomePreRender(KX_Scene* m_scene, KX_Camera* m_cam); + void DomeRenderRoutine(KX_Scene* m_scene, KX_Camera* m_cam); + void DomePostRender(KX_Scene* m_scene, KX_Camera* m_cam, RAS_IRasterizer::StereoMode stereomode); + + void DomeRotateView(KX_Camera* cam, int i, MT_Matrix4x4 cam_mat); + + + //to be deleted:: + void oldDomeRender(KX_Scene* scene, KX_Camera* cam); + void DomeOriginalRender(); + void DomeImageRender(KX_Scene* m_scene, KX_Camera* m_cam); + void RenderDomeCamera(KX_Scene* scene, KX_Camera* cam, MT_Matrix4x4 viewmat, MT_Transform camtrans, MT_Vector3 camrot); + void DomeRotateCamera(KX_Camera* cam, int i); +// void DrawDomeVert(float theta, float phi); +// void DrawDomeSphere(float del); +// static const enum DomeFaceTarget; + + ///returns true if an update happened to indicate -> Render bool NextFrame(); void Render(); Index: source/gameengine/Rasterizer/RAS_IRasterizer.h =================================================================== --- source/gameengine/Rasterizer/RAS_IRasterizer.h (revision 18000) +++ source/gameengine/Rasterizer/RAS_IRasterizer.h (working copy) @@ -113,6 +113,7 @@ RAS_STEREO_ANAGLYPH, RAS_STEREO_SIDEBYSIDE, RAS_STEREO_VINTERLACE, + RAS_STEREO_DOME, RAS_STEREO_MAXSTEREO }; Index: source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp =================================================================== --- source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp (revision 18000) +++ source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp (working copy) @@ -419,7 +419,7 @@ bool RAS_OpenGLRasterizer::Stereo() { - if(m_stereomode == RAS_STEREO_NOSTEREO) + if(m_stereomode == RAS_STEREO_NOSTEREO || m_stereomode == RAS_STEREO_DOME) return false; else return true;
Index: source/blender/makesdna/DNA_scene_types.h =================================================================== --- source/blender/makesdna/DNA_scene_types.h (revision 18000) +++ source/blender/makesdna/DNA_scene_types.h (working copy) @@ -310,6 +310,11 @@ /* cineon */ short cineonwhite, cineonblack; float cineongamma; + + /* Dome variables */ + float domesize; + short domeres, pad0; + } RenderData; /* control render convert and shading engine */ Index: source/blender/src/buttons_scene.c =================================================================== --- source/blender/src/buttons_scene.c (revision 18000) +++ source/blender/src/buttons_scene.c (working copy) @@ -1820,6 +1820,7 @@ * RAS_STEREO_ANAGLYPH 5 * RAS_STEREO_SIDEBYSIDE 6 * RAS_STEREO_VINTERLACE 7 + * RAS_STEREO_DOME 8 */ uiBlockBeginAlign(block); uiDefButS(block, ROW, 0, "No Stereo", xco, yco-=30, 88, 19, &(G.scene->r.stereomode), 7.0, 1.0, 0, 0, "Disables stereo"); @@ -1828,7 +1829,10 @@ uiDefButS(block, ROW, 0, "Anaglyph", xco-=180, yco-=21, 88, 19, &(G.scene->r.stereomode), 7.0, 5.0, 0, 0, "Enables anaglyph (Red-Blue) stereo method"); uiDefButS(block, ROW, 0, "Side by Side", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 6.0, 0, 0, "Enables side by side left and right images"); uiDefButS(block, ROW, 0, "V Interlace", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 7.0, 0, 0, "Enables interlaced vertical strips for autostereo display"); - + uiDefButS(block, ROW, 0, "Dome 180º", xco-=180, yco-=21, 88, 19, &(G.scene->r.stereomode), 7.0, 8.0, 0, 0, "Enables Dome View"); + uiDefButF(block, NUM, 0, "Size:", xco+=90, yco, 88, 19, &G.scene->r.domesize, 1.0, 10.0, 0, 0, "Size of the ENV MAP faces"); + uiDefButS(block, NUM, 0, "Res:", xco+=90, yco, 88, 19, &G.scene->r.domeres, 1.0, 5.0, 1.0, 0, "Resolution of the dome - 1 to 50"); + uiBlockEndAlign(block); uiBlockSetDirection(block, UI_TOP); Index: source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp =================================================================== --- source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp (revision 18000) +++ source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp (working copy) @@ -366,6 +366,12 @@ initMathutils(); initVideoTexture(); + //initialize Dome Settings + if(blscene->r.stereomode == RAS_IRasterizer::RAS_STEREO_DOME){ + ketsjiengine->tmpInitDome(); + ketsjiengine->InitDome(); + } + if (sceneconverter) { // convert and add scene @@ -403,7 +409,10 @@ if (render) { // render the frame - ketsjiengine->Render(); + if(blscene->r.stereomode == RAS_IRasterizer::RAS_STEREO_DOME) + RenderDome(); + else + ketsjiengine->Render(); } // test for the ESC key @@ -430,6 +439,9 @@ printf("\nBlender Game Engine Finished\n\n"); exitstring = ketsjiengine->GetExitString(); + //finalize Dome Settings + if(blscene->r.stereomode == RAS_IRasterizer::RAS_STEREO_DOME) + ketsjiengine->EndDome(); // when exiting the mainloop Index: source/gameengine/Ketsji/KX_Camera.cpp =================================================================== --- source/gameengine/Ketsji/KX_Camera.cpp (revision 18000) +++ source/gameengine/Ketsji/KX_Camera.cpp (working copy) @@ -425,7 +425,12 @@ { return m_frustum_culling; } - + +void KX_Camera::SetFrustumCulling(bool frustum) +{ + m_frustum_culling = frustum; +} + void KX_Camera::EnableViewport(bool viewport) { m_camdata.m_viewport = viewport; Index: source/gameengine/Ketsji/KX_Camera.h =================================================================== --- source/gameengine/Ketsji/KX_Camera.h (revision 18000) +++ source/gameengine/Ketsji/KX_Camera.h (working copy) @@ -220,6 +220,11 @@ * Gets this camera's culling status. */ bool GetFrustumCulling() const; + + /** + * Sets this camera's culling status. (for debug only) + */ + void SetFrustumCulling(bool frustum); /** * Sets this camera's viewport status. Index: source/gameengine/Ketsji/KX_Dome.cpp =================================================================== --- source/gameengine/Ketsji/KX_Dome.cpp (revision 0) +++ source/gameengine/Ketsji/KX_Dome.cpp (revision 0) @@ -0,0 +1,1346 @@ +/* $Id$ +----------------------------------------------------------------------------- + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser 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, or go to +http://www.gnu.org/copyleft/lesser.txt. +----------------------------------------------------------------------------- +*/ + +// implementation + +#include <PyObjectPlus.h> +#include <structmember.h> +#include <float.h> +#include <math.h> + + +#include <BIF_gl.h> + +#include "KX_PythonInit.h" +#include "DNA_scene_types.h" +#include "RAS_CameraData.h" +//#include "RAS_MeshObject.h" +#include "BLI_arithb.h" + +#include "KX_Dome.h" +#include "GL/glew.h" +#include "GL/glu.h" + +//#include "ImageBase.h" +//#include "BlendType.h" +//#include "Exception.h" +//#include "Texture.h" + +// constructor +KX_Dome::KX_Dome ( + RAS_ICanvas* canvas, + /// rasterizer + RAS_IRasterizer* rasterizer, + /// render tools + RAS_IRenderTools* rendertools, + /// engine + KX_KetsjiEngine* engine + +)://KX_Scene * scene, KX_Camera * camera) : +// ImageViewport(), + // m_render(true), + // m_scene(scene), + // m_camera(camera), +// m_owncamera(false), +// m_observer(NULL), +// m_mirror(NULL), + m_canvas(canvas), + m_rasterizer(rasterizer), + m_rendertools(rendertools), + m_engine(engine), + m_clip(100.f) +{ + // initialize background colour + setBackground(0, 0, 255, 255); + // retrieve rendering objects + // m_engine = KX_GetActiveEngine(); +// m_rasterizer = m_engine->GetRasterizer(); +// m_canvas = m_engine->GetCanvas(); +// m_rendertools = m_engine->GetRenderTools(); + cubetop.resize(1); + cubebottom.resize(1); + cubeleft.resize(2); + cuberight.resize(2); +} + +static GLenum DomeFaceTarget [6] = { + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_X +}; + +//unsigned int m_DomeFaces; +unsigned int m_DomeFacesTmp[6]; // tmp to store a single render image + +int m_DomeFacesize=512; + +// destructor +KX_Dome::~KX_Dome (void) +{ +// if (m_owncamera) +// m_camera->Release(); +/* + for (int i=0;i<nfacestop;i++){ + for (int j=0;j<3;j++){ + for (int k=0;k<3;k++){ + printf("cubetop[%1d].verts[%1d][%1d]: %2.4f\n", i, j, k, cubetop[i].verts[j][k]); +// cout << cubetop[i].verts[j][k] << std::endl; + } + } + } + */ +} + + +// set background color/ +void KX_Dome::setBackground (int red, int green, int blue, int alpha) +{ + m_background[0] = (red < 0) ? 0.f : (red > 255) ? 1.f : float(red)/255.f; + m_background[1] = (green < 0) ? 0.f : (green > 255) ? 1.f : float(green)/255.f; + m_background[2] = (blue < 0) ? 0.f : (blue > 255) ? 1.f : float(blue)/255.f; + m_background[3] = (alpha < 0) ? 0.f : (alpha > 255) ? 1.f : float(alpha)/255.f; +} + +/* my code ::: */ + +void KX_Dome::Dome_CubeCreate(int cubeRes){ + int i,j; + + //creating faces for the env mapcube 180º Dome + // Top Face - just a triangle + cubetop[0].verts[0][0] = -sqrt(2.0) / 2.0; + cubetop[0].verts[0][1] = 0.0; + cubetop[0].verts[0][2] = 0.5; + cubetop[0].u[0] = 0.0; + cubetop[0].v[0] = 1.0; + + cubetop[0].verts[1][0] = 0.0; + cubetop[0].verts[1][1] = sqrt(2.0) / 2.0; + cubetop[0].verts[1][2] = 0.5; + cubetop[0].u[1] = 0.0; + cubetop[0].v[1] = 0.0; + + cubetop[0].verts[2][0] = sqrt(2.0) / 2.0; + cubetop[0].verts[2][1] = 0.0; + cubetop[0].verts[2][2] = 0.5; + cubetop[0].u[2] = 1.0; + cubetop[0].v[2] = 0.0; + + nfacestop = 1; + + /* Bottom face - just a triangle */ + cubebottom[0].verts[0][0] = -sqrt(2.0) / 2.0; + cubebottom[0].verts[0][1] = 0; + cubebottom[0].verts[0][2] = -0.5; + cubebottom[0].u[0] = 1; + cubebottom[0].v[0] = 0; + + cubebottom[0].verts[1][0] = sqrt(2.0) / 2.0; + cubebottom[0].verts[1][1] = 0; + cubebottom[0].verts[1][2] = -0.5; + cubebottom[0].u[1] = 0; + cubebottom[0].v[1] = 1; + + cubebottom[0].verts[2][0] = 0; + cubebottom[0].verts[2][1] = sqrt(2.0) / 2.0; + cubebottom[0].verts[2][2] = -0.5; + cubebottom[0].u[2] = 0; + cubebottom[0].v[2] = 0; + + nfacesbottom = 1; + + /* Left face - two triangles */ + + cubeleft[0].verts[0][0] = -sqrt(2.0) / 2.0; + cubeleft[0].verts[0][1] = 0; + cubeleft[0].verts[0][2] = -0.5; + cubeleft[0].u[0] = 0; + cubeleft[0].v[0] = 0; + + cubeleft[0].verts[1][0] = 0; + cubeleft[0].verts[1][1] = sqrt(2.0) / 2.0; + cubeleft[0].verts[1][2] = -0.5; + cubeleft[0].u[1] = 1; + cubeleft[0].v[1] = 0; + + cubeleft[0].verts[2][0] = -sqrt(2.0) / 2.0; + cubeleft[0].verts[2][1] = 0; + cubeleft[0].verts[2][2] = 0.5; + cubeleft[0].u[2] = 0; + cubeleft[0].v[2] = 1; + + cubeleft[1].verts[0][0] = -sqrt(2.0) / 2.0; + cubeleft[1].verts[0][1] = 0; + cubeleft[1].verts[0][2] = 0.5; + cubeleft[1].u[0] = 0; + cubeleft[1].v[0] = 1; + + cubeleft[1].verts[1][0] = 0; + cubeleft[1].verts[1][1] = sqrt(2.0) / 2.0; + cubeleft[1].verts[1][2] = -0.5; + cubeleft[1].u[1] = 1; + cubeleft[1].v[1] = 0; + + cubeleft[1].verts[2][0] = 0; + cubeleft[1].verts[2][1] = sqrt(2.0) / 2.0; + cubeleft[1].verts[2][2] = 0.5; + cubeleft[1].u[2] = 1; + cubeleft[1].v[2] = 1; + + nfacesleft = 2; + + /* Right face - two triangles */ + cuberight[0].verts[0][0] = 0; + cuberight[0].verts[0][1] = sqrt(2.0) / 2.0; + cuberight[0].verts[0][2] = -0.5; + cuberight[0].u[0] = 0; + cuberight[0].v[0] = 0; + + cuberight[0].verts[1][0] = sqrt(2.0) / 2.0; + cuberight[0].verts[1][1] = 0; + cuberight[0].verts[1][2] = -0.5; + cuberight[0].u[1] = 1; + cuberight[0].v[1] = 0; + + cuberight[0].verts[2][0] = sqrt(2.0) / 2.0; + cuberight[0].verts[2][1] = 0; + cuberight[0].verts[2][2] = 0.5; + cuberight[0].u[2] = 1; + cuberight[0].v[2] = 1; + + cuberight[1].verts[0][0] = 0; + cuberight[1].verts[0][1] = sqrt(2.0) / 2.0; + cuberight[1].verts[0][2] = -0.5; + cuberight[1].u[0] = 0; + cuberight[1].v[0] = 0; + + cuberight[1].verts[1][0] = sqrt(2.0) / 2.0; + cuberight[1].verts[1][1] = 0; + cuberight[1].verts[1][2] = 0.5; + cuberight[1].u[1] = 1; + cuberight[1].v[1] = 1; + + cuberight[1].verts[2][0] = 0; + cuberight[1].verts[2][1] = sqrt(2.0) / 2.0; + cuberight[1].verts[2][2] = 0.5; + cuberight[1].u[2] = 0; + cuberight[1].v[2] = 1; + + nfacesright = 2; + + //Refine a triangular mesh by bisecting each edge forms 3 new triangles for each existing triangle on each iteration + //Could be made more efficient for drawing if the triangles were ordered in a fan or strip! + +// cubeRes = 3; + for(i=0;i<cubeRes;i++){ + cubetop.resize(4*nfacestop); + Dome_CubeSplitFace(cubetop,&nfacestop); + cubebottom.resize(4*nfacesbottom); + Dome_CubeSplitFace(cubebottom,&nfacesbottom); + cubeleft.resize(4*nfacesleft); + Dome_CubeSplitFace(cubeleft,&nfacesleft); + cuberight.resize(4*nfacesright); + Dome_CubeSplitFace(cuberight,&nfacesright); + } + + // Turn into a hemisphere + for(j=0;j<3;j++){ + for(i=0;i<nfacestop;i++) + cubetop[i].verts[j].normalize(); + for(i=0;i<nfacesbottom;i++) + cubebottom[i].verts[j].normalize(); + for(i=0;i<nfacesleft;i++) + cubeleft[i].verts[j].normalize(); + for(i=0;i<nfacesright;i++) + cuberight[i].verts[j].normalize(); + } + + //flatten onto xz plane + for(j=0;j<3;j++){ + for(i=0;i<nfacestop;i++) + Dome_CubeFlatten(cubetop[i].verts[j]); + for(i=0;i<nfacesbottom;i++) + Dome_CubeFlatten(cubebottom[i].verts[j]); + for(i=0;i<nfacesleft;i++) + Dome_CubeFlatten(cubeleft[i].verts[j]); + for(i=0;i<nfacesright;i++) + Dome_CubeFlatten(cuberight[i].verts[j]); + } +} + +void KX_Dome::Dome_CubeSplitFace(vector <DomeFace>& face, int *nfaces) +{ + int i; + int n1, n2; + + n1 = n2 = *nfaces; + + for(i=0;i<n1;i++){ + + face[n2].verts[0] = (face[i].verts[0] + face[i].verts[1]) /2; + face[n2].verts[1] = face[i].verts[1]; + face[n2].verts[2] = (face[i].verts[1] + face[i].verts[2]) /2; + face[n2].u[0] = (face[i].u[0] + face[i].u[1]) /2; + face[n2].u[1] = face[i].u[1]; + face[n2].u[2] = (face[i].u[1] + face[i].u[2]) /2; + face[n2].v[0] = (face[i].v[0] + face[i].v[1]) /2; + face[n2].v[1] = face[i].v[1]; + face[n2].v[2] = (face[i].v[1] + face[i].v[2]) /2; + + face[n2+1].verts[0] = (face[i].verts[1] + face[i].verts[2]) /2; + face[n2+1].verts[1] = face[i].verts[2]; + face[n2+1].verts[2] = (face[i].verts[2] + face[i].verts[0]) /2; + face[n2+1].u[0] = (face[i].u[1] + face[i].u[2]) /2; + face[n2+1].u[1] = face[i].u[2]; + face[n2+1].u[2] = (face[i].u[2] + face[i].u[0]) /2; + face[n2+1].v[0] = (face[i].v[1] + face[i].v[2]) /2; + face[n2+1].v[1] = face[i].v[2]; + face[n2+1].v[2] = (face[i].v[2] + face[i].v[0]) /2; + + face[n2+2].verts[0] = (face[i].verts[0] + face[i].verts[1]) /2; + face[n2+2].verts[1] = (face[i].verts[1] + face[i].verts[2]) /2; + face[n2+2].verts[2] = (face[i].verts[2] + face[i].verts[0]) /2; + face[n2+2].u[0] = (face[i].u[0] + face[i].u[1]) /2; + face[n2+2].u[1] = (face[i].u[1] + face[i].u[2]) /2; + face[n2+2].u[2] = (face[i].u[2] + face[i].u[0]) /2; + face[n2+2].v[0] = (face[i].v[0] + face[i].v[1]) /2; + face[n2+2].v[1] = (face[i].v[1] + face[i].v[2]) /2; + face[n2+2].v[2] = (face[i].v[2] + face[i].v[0]) /2; + + //face[i].verts[0] = face[i].verts[0] ; + face[i].verts[1] = (face[i].verts[0] + face[i].verts[1]) /2; + face[i].verts[2] = (face[i].verts[0] + face[i].verts[2]) /2; + //face[i].u[0] = face[i].u[0]; + face[i].u[1] = (face[i].u[0] + face[i].u[1]) /2; + face[i].u[2] = (face[i].u[0] + face[i].u[2]) /2; + //face[i].v[0] = face[i].v[0] ; + face[i].v[1] = (face[i].v[0] + face[i].v[1]) /2; + face[i].v[2] = (face[i].v[0] + face[i].v[2]) /2; + + n2 += 3; // number of faces + } + *nfaces = n2; +} + +void KX_Dome::Dome_CubeFlatten(MT_Vector3 & verts){ + double phi, r; + + r = atan2(sqrt(verts[0]*verts[0] + verts[2]*verts[2]), verts[1]); + r /= (MT_PI / 2); + printf("R= %2.4f\n", r); + + phi = atan2(verts[2], verts[0]); + printf("Phi= %2.4f\n", phi); + + verts[0] = r * cos(phi); + verts[1] = 0; // zed, I probably will need to change it to work with BGE axis + verts[2] = r * sin(phi); +} + +void DrawDomeVert(float theta, float phi) +{ + float r = 1.0f; + float x, y, z, nx, ny, nz; + float dtor = 3.1416/180.0; + float ztrans = 1.0; + + nx = sin(dtor * theta) * cos(dtor * phi); + ny = sin(dtor * phi); + nz = cos(dtor * theta) * cos(dtor * phi); + glNormal3f(nx, ny, nz); + + x = r * sin(dtor * theta) * cos(dtor * phi); + y = r * sin(dtor * phi); + z = -ztrans + r * cos(dtor * theta) * cos(dtor * phi); + glVertex4f(x, y, z, 1.0); +} + +void DrawDomeSphere(float del) +{ + float phi, phi2, theta; + + glColor4f(1.0, 1.0, 1.0, 1.0); + // glBegin(GL_TRIANGLE_STRIP); + for (phi = -90.0f; phi < 90.0f; phi += del) { + glBegin(GL_TRIANGLE_STRIP); + + phi2 = phi + del; + + for (theta = -90.0f; theta <= 90.0f; theta += del) { + DrawDomeVert(theta, phi); + DrawDomeVert(theta, phi2); + } + glEnd(); + } +// glEnd(); +} +/* +void KX_Dome::Dome_CubeDraw(unsigned int viewport[4], int m_DomeFaces) +{ + //Skybox => 4 images + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Making the viewport always square + + int can_width = viewport[2]; + int can_height = viewport[3]; + + float ortho_width, ortho_height = 1.0; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + glBegin(GL_TRIANGLES); + glColor3f(0.0f ,0.0f, 1.0f); + glVertex3f( 0.0f, 0.5f, 4.0f); + glColor3f(0.0f ,0.5f, 0.0f); + glVertex3f(-0.5f,-0.5f, 4.0f); + glColor3f(1.0f ,0.0f, 0.0f); + glVertex3f( 0.5f,-0.5f, 4.0f); + glEnd(); + + glEnable(GL_TEXTURE_2D); + +// DomeFacesTmp[0] -> LEFT + glBindTexture(GL_TEXTURE_2D, m_DomeFaces); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.05f, 0.3f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.65f,0.3f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.65f,-0.3f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.05f,-0.3f, 3.0f); + glEnd(); + +// DomeFacesTmp[1] -> RIGHT + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+1); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.65f, 0.3f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(0.05f,0.3f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(0.05f,-0.3f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f( 0.65f,-0.3f, 3.0f); + glEnd(); + +// DomeFacesTmp[2] -> TOP + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+2); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.05f, 0.95f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.65f,0.95f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.65f,0.35f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.05f,0.35f, 3.0f); + glEnd(); + +// DomeFacesTmp[3] -> BOTTOM + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+3); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.05f, -0.35f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.65f,-0.35f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.65f,-0.95f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.05f,-0.95f, 3.0f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); +} +*/ + +void KX_Dome::Dome_CubeDraw(unsigned int viewport[4], int m_DomeFaces) +{ + //correct =>Skybox + int i,j; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Making the viewport always square + + int can_width = viewport[2]; + int can_height = viewport[3]; + + float ortho_width, ortho_height = 1.0; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0.0,-1.0,0.0, 0.0,0.0,0.0, 0.0,0.0,1.0); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); +// glPolygonMode(GL_FRONT, GL_LINE); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + glEnable(GL_TEXTURE_2D); + glColor3f(1.0,1.0,1.0); + + glBindTexture(GL_TEXTURE_2D, m_DomeFaces); + // top triangle + glBegin(GL_TRIANGLES); +// glColor3f(0.0f, 0.0f, 1.0f); + for (i=0;i<nfacestop;i++) { + for (j=0;j<3;j++) { + glTexCoord2f(cubetop[i].u[j],cubetop[i].v[j]); + glVertex3f((GLfloat)cubetop[i].verts[j][0],(GLfloat)cubetop[i].verts[j][1],(GLfloat)cubetop[i].verts[j][2]); + } + } + glEnd(); + + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+1); + // bottom triangle + glBegin(GL_TRIANGLES); +// glColor3f(1.0f, 1.0f, 0.0f); + for (i=0;i<nfacesbottom;i++) { + for (j=0;j<3;j++) { + glTexCoord2f(cubebottom[i].u[j],cubebottom[i].v[j]); + glVertex3f((GLfloat)cubebottom[i].verts[j][0],(GLfloat)cubebottom[i].verts[j][1],(GLfloat)cubebottom[i].verts[j][2]); + } + } + glEnd(); + + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+2); + // left triangle + glBegin(GL_TRIANGLES); +// glColor3f(0.0f, 1.0f, 0.0f); + for (i=0;i<nfacesleft;i++) { + for (j=0;j<3;j++) { + glTexCoord2f(cubeleft[i].u[j],cubeleft[i].v[j]); + glVertex3f((GLfloat)cubeleft[i].verts[j][0],(GLfloat)cubeleft[i].verts[j][1],(GLfloat)cubeleft[i].verts[j][2]); + } + } + glEnd(); + + glBindTexture(GL_TEXTURE_2D, m_DomeFaces+3); + // right triangle + glBegin(GL_TRIANGLES); +// glColor3f(1.0f, 0.0f, 0.0f); + for (i=0;i<nfacesright;i++) { + for (j=0;j<3;j++) { + glTexCoord2f(cuberight[i].u[j],cuberight[i].v[j]); + glVertex3f((GLfloat)cuberight[i].verts[j][0],(GLfloat)cuberight[i].verts[j][1],(GLfloat)cuberight[i].verts[j][2]); + } + } + glEnd(); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); +} +void KX_Dome::RenderDome() +{ + m_engine->Render(); + +/* + KX_Scene* firstscene = *m_scenes.begin(); + const RAS_FrameSettings &framesettings = firstscene->GetFramingType(); + + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); + + // hiding mouse cursor each frame + // (came back when going out of focus and then back in again) + if (m_hideCursor) + m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); + + // clear the entire game screen with the border color + // only once per frame + m_canvas->BeginDraw(); + if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) { + m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight()); + if (m_overrideFrameColor) + { + // Do not use the framing bar color set in the Blender scenes + m_canvas->ClearColor( + m_overrideFrameColorR, + m_overrideFrameColorG, + m_overrideFrameColorB, + 1.0 + ); + } + else + { + // Use the framing bar color set in the Blender scenes + m_canvas->ClearColor( + framesettings.BarRed(), + framesettings.BarGreen(), + framesettings.BarBlue(), + 1.0 + ); + } + // clear the -whole- viewport + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); + } + + m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_LEFTEYE); + + // BeginFrame() sets the actual drawing area. You can use a part of the window + if (!BeginFrame()) + return; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + KX_Camera* cam = scene->GetActiveCamera(); + // pass the scene's worldsettings to the rasterizer + SetWorldSettings(scene->GetWorldInfo()); + + // shadow buffers + RenderShadowBuffers(scene); + + // Avoid drawing the scene with the active camera twice when it's viewport is enabled + if(cam && !cam->GetViewport()) + { + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + // dome checking + if(m_rasterizer->GetStereoMode()==RAS_IRasterizer::RAS_STEREO_DOME) + RenderDomeFrame(scene,cam); + else + RenderFrame(scene, cam); + } + + list<class KX_Camera*>* cameras = scene->GetCameras(); + + // Draw the scene once for each camera with an enabled viewport + list<KX_Camera*>::iterator it = cameras->begin(); + while(it != cameras->end()) + { + if((*it)->GetViewport()) + { + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + if(m_rasterizer->GetStereoMode()==RAS_IRasterizer::RAS_STEREO_DOME) + RenderDomeFrame(scene, (*it)); + else + RenderFrame(scene, (*it)); + } + + it++; + } + } + + // only one place that checks for stereo + if(m_rasterizer->Stereo()) + { + m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_RIGHTEYE); + + if (!BeginFrame()) + return; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + KX_Camera* cam = scene->GetActiveCamera(); + + // pass the scene's worldsettings to the rasterizer + SetWorldSettings(scene->GetWorldInfo()); + + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + //pass the scene, for picking and raycasting (shadows) + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + //RenderFrame(scene); + RenderFrame(scene, cam); + } + } // if(m_rasterizer->Stereo()) + + EndFrame(); +*/ +} +/* +void KX_Dome::Dome_CubeDraw(unsigned int viewport[4], int m_DomeFaces) +{ +//tmp, cubemap + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // + + int can_width = viewport[2]; + int can_height = viewport[3]; + + float ortho_width, ortho_height; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + //Start to Draw + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + glDisable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_CUBE_MAP, m_DomeFaces); + // Commands to Enable EnvMap + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glEnable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glEnable(GL_NORMALIZE); + + DrawDomeSphere(9.0); + + glDisable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_DEPTH_TEST); +} +*/ +/* +// capture image from viewport +void KX_Dome::calcImage (unsigned int texId) +{ + if (m_rasterizer->GetDrawingMode() != RAS_IRasterizer::KX_TEXTURED || // no need for texture + m_camera->GetViewport() || // camera must be inactive + m_camera == m_scene->GetActiveCamera()) + { + // no need to compute texture in non texture rendering + m_avail = false; + return; + } + // render the scene from the camera + Render(); + // get image from viewport + ImageViewport::calcImage(texId); + // restore OpenGL state + m_canvas->EndFrame(); +} +*/ +/* +void ImageRender::Render() +{ + RAS_FrameFrustum frustrum; + + if (!m_render) + return; + + if (m_mirror) + { + // mirror mode, compute camera frustrum, position and orientation + // convert mirror position and normal in world space + const MT_Matrix3x3 & mirrorObjWorldOri = m_mirror->GetSGNode()->GetWorldOrientation(); + const MT_Point3 & mirrorObjWorldPos = m_mirror->GetSGNode()->GetWorldPosition(); + const MT_Vector3 & mirrorObjWorldScale = m_mirror->GetSGNode()->GetWorldScaling(); + MT_Point3 mirrorWorldPos = + mirrorObjWorldPos + mirrorObjWorldScale * (mirrorObjWorldOri * m_mirrorPos); + MT_Vector3 mirrorWorldZ = mirrorObjWorldOri * m_mirrorZ; + // get observer world position + const MT_Point3 & observerWorldPos = m_observer->GetSGNode()->GetWorldPosition(); + // get plane D term = mirrorPos . normal + MT_Scalar mirrorPlaneDTerm = mirrorWorldPos.dot(mirrorWorldZ); + // compute distance of observer to mirror = D - observerPos . normal + MT_Scalar observerDistance = mirrorPlaneDTerm - observerWorldPos.dot(mirrorWorldZ); + // if distance < 0.01 => observer is on wrong side of mirror, don't render + if (observerDistance < 0.01f) + return; + // set camera world position = observerPos + normal * 2 * distance + MT_Point3 cameraWorldPos = observerWorldPos + (MT_Scalar(2.0)*observerDistance)*mirrorWorldZ; + m_camera->GetSGNode()->SetLocalPosition(cameraWorldPos); + // set camera orientation: z=normal, y=mirror_up in world space, x= y x z + MT_Vector3 mirrorWorldY = mirrorObjWorldOri * m_mirrorY; + MT_Vector3 mirrorWorldX = mirrorObjWorldOri * m_mirrorX; + MT_Matrix3x3 cameraWorldOri( + mirrorWorldX[0], mirrorWorldY[0], mirrorWorldZ[0], + mirrorWorldX[1], mirrorWorldY[1], mirrorWorldZ[1], + mirrorWorldX[2], mirrorWorldY[2], mirrorWorldZ[2]); + m_camera->GetSGNode()->SetLocalOrientation(cameraWorldOri); + m_camera->GetSGNode()->UpdateWorldData(0.0); + // compute camera frustrum: + // get position of mirror relative to camera: offset = mirrorPos-cameraPos + MT_Vector3 mirrorOffset = mirrorWorldPos - cameraWorldPos; + // convert to camera orientation + mirrorOffset = mirrorOffset * cameraWorldOri; + // scale mirror size to world scale: + // get closest local axis for mirror Y and X axis and scale height and width by local axis scale + MT_Scalar x, y; + x = fabs(m_mirrorY[0]); + y = fabs(m_mirrorY[1]); + float height = (x > y) ? + ((x > fabs(m_mirrorY[2])) ? mirrorObjWorldScale[0] : mirrorObjWorldScale[2]): + ((y > fabs(m_mirrorY[2])) ? mirrorObjWorldScale[1] : mirrorObjWorldScale[2]); + x = fabs(m_mirrorX[0]); + y = fabs(m_mirrorX[1]); + float width = (x > y) ? + ((x > fabs(m_mirrorX[2])) ? mirrorObjWorldScale[0] : mirrorObjWorldScale[2]): + ((y > fabs(m_mirrorX[2])) ? mirrorObjWorldScale[1] : mirrorObjWorldScale[2]); + width *= m_mirrorHalfWidth; + height *= m_mirrorHalfHeight; + // left = offsetx-width + // right = offsetx+width + // top = offsety+height + // bottom = offsety-height + // near = -offsetz + // far = near+100 + frustrum.x1 = mirrorOffset[0]-width; + frustrum.x2 = mirrorOffset[0]+width; + frustrum.y1 = mirrorOffset[1]-height; + frustrum.y2 = mirrorOffset[1]+height; + frustrum.camnear = -mirrorOffset[2]; + frustrum.camfar = -mirrorOffset[2]+m_clip; + } + const float ortho = 100.0; + const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); + + // The screen area that ImageViewport will copy is also the rendering zone + m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0]-1, m_position[1]+m_capSize[1]-1); + m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]); + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); + m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,m_engine->GetClockTime()); + m_rendertools->BeginFrame(m_rasterizer); + m_engine->SetWorldSettings(m_scene->GetWorldInfo()); + m_rendertools->SetAuxilaryClientInfo(m_scene); + m_rasterizer->DisplayFog(); + // matrix calculation, don't apply any of the stereo mode + m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO); + if (m_mirror) + { + // frustrum was computed above + // get frustrum matrix and set projection matrix + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + + m_camera->SetProjectionMatrix(projmat); + } else if (m_camera->hasValidProjectionMatrix()) + { + m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix()); + } else + { + float lens = m_camera->GetLens(); + bool orthographic = !m_camera->GetCameraData()->m_perspective; + float nearfrust = m_camera->GetCameraNear(); + float farfrust = m_camera->GetCameraFar(); + float aspect_ratio = 1.0f; + Scene *blenderScene = m_scene->GetBlenderScene(); + + if (orthographic) { + lens *= ortho; + nearfrust = (nearfrust + 1.0)*ortho; + farfrust *= ortho; + } + // compute the aspect ratio from frame blender scene settings so that render to texture + // works the same in Blender and in Blender player + if (blenderScene->r.ysch != 0) + aspect_ratio = float(blenderScene->r.xsch) / float(blenderScene->r.ysch); + + RAS_FramingManager::ComputeDefaultFrustum( + nearfrust, + farfrust, + lens, + aspect_ratio, + frustrum); + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + + m_camera->SetProjectionMatrix(projmat); + } + + MT_Transform camtrans(m_camera->GetWorldToCamera()); + if (!m_camera->GetCameraData()->m_perspective) + camtrans.getOrigin()[2] *= ortho; + MT_Matrix4x4 viewmat(camtrans); + + m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), + m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + m_camera->SetModelviewMatrix(viewmat); + // restore the stereo mode now that the matrix is computed + m_rasterizer->SetStereoMode(stereomode); + + // do not update the mesh, we don't want to do it more than once per frame + //m_scene->UpdateMeshTransformations(); + + m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera); + + m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); +} +*/ +/* +// cast Image pointer to ImageRender +inline ImageRender * getImageRender (PyImage * self) +{ return static_cast<ImageRender*>(self->m_image); } +*/ + +// python methods + +// Blender Scene type +//BlendType<KX_Scene> sceneType ("KX_Scene"); +// Blender Camera type +//BlendType<KX_Camera> cameraType ("KX_Camera"); + +/* +// object initialization +static int ImageRender_init (PyObject * pySelf, PyObject * args, PyObject * kwds) +{ + // parameters - scene object + PyObject * scene; + // camera object + PyObject * camera; + // parameter keywords + static char *kwlist[] = {"sceneObj", "cameraObj", NULL}; + // get parameters + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &scene, &camera)) + return -1; + try + { + // get scene pointer + KX_Scene * scenePtr (NULL); + if (scene != NULL) scenePtr = sceneType.checkType(scene); + // throw exception if scene is not available + if (scenePtr == NULL) THRWEXCP(SceneInvalid, S_OK); + + // get camera pointer + KX_Camera * cameraPtr (NULL); + if (camera != NULL) cameraPtr = cameraType.checkType(camera); + // throw exception if camera is not available + if (cameraPtr == NULL) THRWEXCP(CameraInvalid, S_OK); + + // get pointer to image structure + PyImage * self = reinterpret_cast<PyImage*>(pySelf); + // create source object + if (self->m_image != NULL) delete self->m_image; + self->m_image = new ImageRender(scenePtr, cameraPtr); + } + catch (Exception & exp) + { + exp.report(); + return -1; + } + // initialization succeded + return 0; +} +*/ +/* +// get background color +PyObject * getBackground (PyImage * self, void * closure) +{ + return Py_BuildValue("[BBBB]", + getImageRender(self)->getBackground(0), + getImageRender(self)->getBackground(1), + getImageRender(self)->getBackground(2), + getImageRender(self)->getBackground(3)); +} +*/ +/* +// set color +static int setBackground (PyImage * self, PyObject * value, void * closure) +{ + // check validity of parameter + if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 4 + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1)) + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2)) + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 3))) + { + PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 4 integer between 0 and 255"); + return -1; + } + // set background color + getImageRender(self)->setBackground((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), + (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))), + (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2))), + (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 3)))); + // success + return 0; +} +*/ +/* +// methods structure +static PyMethodDef imageRenderMethods[] = +{ // methods from ImageBase class + {"refresh", (PyCFunction)Image_refresh, METH_NOARGS, "Refresh image - invalidate its current content"}, + {NULL} +}; +// attributes structure +static PyGetSetDef imageRenderGetSets[] = +{ + {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL}, + // attribute from ImageViewport + {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL}, + {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL}, + {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL}, + // attributes from ImageBase class + {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, + {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, + {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL}, + {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL}, + {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL}, + {NULL} +}; +*/ + +/* +// object initialization +static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds) +{ + // parameters - scene object + PyObject * scene; + // reference object for mirror + PyObject * observer; + // object holding the mirror + PyObject * mirror; + // material of the mirror + short materialID = 0; + // parameter keywords + static char *kwlist[] = {"scene", "observer", "mirror", "material", NULL}; + // get parameters + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|h", kwlist, &scene, &observer, &mirror, &materialID)) + return -1; + try + { + // get scene pointer + KX_Scene * scenePtr (NULL); + if (scene != NULL && PyObject_TypeCheck(scene, &KX_Scene::Type)) + scenePtr = static_cast<KX_Scene*>(scene); + else + THRWEXCP(SceneInvalid, S_OK); + + // get observer pointer + KX_GameObject * observerPtr (NULL); + if (observer != NULL && PyObject_TypeCheck(observer, &KX_GameObject::Type)) + observerPtr = static_cast<KX_GameObject*>(observer); + else if (observer != NULL && PyObject_TypeCheck(observer, &KX_Camera::Type)) + observerPtr = static_cast<KX_Camera*>(observer); + else + THRWEXCP(ObserverInvalid, S_OK); + + // get mirror pointer + KX_GameObject * mirrorPtr (NULL); + if (mirror != NULL && PyObject_TypeCheck(mirror, &KX_GameObject::Type)) + mirrorPtr = static_cast<KX_GameObject*>(mirror); + else + THRWEXCP(MirrorInvalid, S_OK); + + // locate the material in the mirror + RAS_IPolyMaterial * material = getMaterial(mirror, materialID); + if (material == NULL) + THRWEXCP(MaterialNotAvail, S_OK); + + // get pointer to image structure + PyImage * self = reinterpret_cast<PyImage*>(pySelf); + + // create source object + if (self->m_image != NULL) + { + delete self->m_image; + self->m_image = NULL; + } + self->m_image = new ImageRender(scenePtr, observerPtr, mirrorPtr, material); + } + catch (Exception & exp) + { + exp.report(); + return -1; + } + // initialization succeded + return 0; +} +*/ +/** +// get background color +PyObject * getClip (PyImage * self, void * closure) +{ + return PyFloat_FromDouble(getImageRender(self)->getClip()); +} +*/ +/* +// set clip +static int setClip (PyImage * self, PyObject * value, void * closure) +{ + // check validity of parameter + double clip; + if (value == NULL || !PyFloat_Check(value) || (clip = PyFloat_AsDouble(value)) < 0.01 || clip > 5000.0) + { + PyErr_SetString(PyExc_TypeError, "The value must be an float between 0.01 and 5000"); + return -1; + } + // set background color + getImageRender(self)->setClip(float(clip)); + // success + return 0; +} +*/ +/* +// attributes structure +static PyGetSetDef imageMirrorGetSets[] = +{ + {(char*)"clip", (getter)getClip, (setter)setClip, (char*)"clipping distance", NULL}, + // attribute from ImageRender + {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL}, + // attribute from ImageViewport + {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL}, + {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL}, + {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL}, + // attributes from ImageBase class + {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, + {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, + {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL}, + {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL}, + {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL}, + {NULL} +}; +*/ +/* +// constructor +ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat) : + ImageViewport(), + m_render(false), + m_scene(scene), + m_observer(observer), + m_mirror(mirror), + m_clip(100.f) +{ + // this constructor is used for automatic planar mirror + // create a camera, take all data by default, in any case we will recompute the frustrum on each frame + RAS_CameraData camdata; + vector<RAS_TexVert*> mirrorVerts; + vector<RAS_TexVert*>::iterator it; + float mirrorArea = 0.f; + float mirrorNormal[3] = {0.f, 0.f, 0.f}; + float mirrorUp[3]; + float dist, vec[3], axis[3]; + float zaxis[3] = {0.f, 0.f, 1.f}; + float yaxis[3] = {0.f, 1.f, 0.f}; + float mirrorMat[3][3]; + float left, right, top, bottom, back; + + m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata); + m_camera->SetName("__mirror__cam__"); + // don't add the camera to the scene object list, it doesn't need to be accessible + m_owncamera = true; + // retrieve rendering objects + m_engine = KX_GetActiveEngine(); + m_rasterizer = m_engine->GetRasterizer(); + m_canvas = m_engine->GetCanvas(); + m_rendertools = m_engine->GetRenderTools(); + // locate the vertex assigned to mat and do following calculation in mesh coordinates + for (int meshIndex = 0; meshIndex < mirror->GetMeshCount(); meshIndex++) + { + RAS_MeshObject* mesh = mirror->GetMesh(meshIndex); + int numPolygons = mesh->NumPolygons(); + for (int polygonIndex=0; polygonIndex < numPolygons; polygonIndex++) + { + RAS_Polygon* polygon = mesh->GetPolygon(polygonIndex); + if (polygon->GetMaterial()->GetPolyMaterial() == mat) + { + RAS_TexVert *v1, *v2, *v3, *v4; + float normal[3]; + float area; + // this polygon is part of the mirror, + v1 = polygon->GetVertex(0); + v2 = polygon->GetVertex(1); + v3 = polygon->GetVertex(2); + mirrorVerts.push_back(v1); + mirrorVerts.push_back(v2); + mirrorVerts.push_back(v3); + if (polygon->VertexCount() == 4) + { + v4 = polygon->GetVertex(3); + mirrorVerts.push_back(v4); + area = CalcNormFloat4((float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), (float*)v4->getXYZ(), normal); + } else + { + area = CalcNormFloat((float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), normal); + } + area = fabs(area); + mirrorArea += area; + VecMulf(normal, area); + VecAddf(mirrorNormal, mirrorNormal, normal); + } + } + } + if (mirrorVerts.size() == 0 || mirrorArea < FLT_EPSILON) + { + // no vertex or zero size mirror + THRWEXCP(MirrorSizeInvalid, S_OK); + } + // compute average normal of mirror faces + VecMulf(mirrorNormal, 1.0f/mirrorArea); + if (Normalize(mirrorNormal) == 0.f) + { + // no normal + THRWEXCP(MirrorNormalInvalid, S_OK); + } + // the mirror plane has an equation of the type ax+by+cz = d where (a,b,c) is the normal vector + // if the mirror is more vertical then horizontal, the Z axis is the up direction. + // otherwise the Y axis is the up direction. + // If the mirror is not perfectly vertical(horizontal), the Z(Y) axis projection on the mirror + // plan by the normal will be the up direction. + if (fabs(mirrorNormal[2]) > fabs(mirrorNormal[1]) && + fabs(mirrorNormal[2]) > fabs(mirrorNormal[0])) + { + // the mirror is more horizontal than vertical + VecCopyf(axis, yaxis); + } + else + { + // the mirror is more vertical than horizontal + VecCopyf(axis, zaxis); + } + dist = Inpf(mirrorNormal, axis); + if (fabs(dist) < FLT_EPSILON) + { + // the mirror is already fully aligned with up axis + VecCopyf(mirrorUp, axis); + } + else + { + // projection of axis to mirror plane through normal + VecCopyf(vec, mirrorNormal); + VecMulf(vec, dist); + VecSubf(mirrorUp, axis, vec); + if (Normalize(mirrorUp) == 0.f) + { + // should not happen + THRWEXCP(MirrorHorizontal, S_OK); + return; + } + } + // compute rotation matrix between local coord and mirror coord + // to match camera orientation, we select mirror z = -normal, y = up, x = y x z + VecCopyf(mirrorMat[2], mirrorNormal); + VecMulf(mirrorMat[2], -1.0f); + VecCopyf(mirrorMat[1], mirrorUp); + Crossf(mirrorMat[0], mirrorMat[1], mirrorMat[2]); + // transpose to make it a orientation matrix from local space to mirror space + Mat3Transp(mirrorMat); + // transform all vertex to plane coordinates and determine mirror position + left = FLT_MAX; + right = -FLT_MAX; + bottom = FLT_MAX; + top = -FLT_MAX; + back = -FLT_MAX; // most backward vertex (=highest Z coord in mirror space) + for (it = mirrorVerts.begin(); it != mirrorVerts.end(); it++) + { + VecCopyf(vec, (float*)(*it)->getXYZ()); + Mat3MulVecfl(mirrorMat, vec); + if (vec[0] < left) + left = vec[0]; + if (vec[0] > right) + right = vec[0]; + if (vec[1] < bottom) + bottom = vec[1]; + if (vec[1] > top) + top = vec[1]; + if (vec[2] > back) + back = vec[2]; + } + // now store this information in the object for later rendering + m_mirrorHalfWidth = (right-left)*0.5f; + m_mirrorHalfHeight = (top-bottom)*0.5f; + if (m_mirrorHalfWidth < 0.01f || m_mirrorHalfHeight < 0.01f) + { + // mirror too small + THRWEXCP(MirrorTooSmall, S_OK); + } + // mirror position in mirror coord + vec[0] = (left+right)*0.5f; + vec[1] = (top+bottom)*0.5f; + vec[2] = back; + // convert it in local space: transpose again the matrix to get back to mirror to local transform + Mat3Transp(mirrorMat); + Mat3MulVecfl(mirrorMat, vec); + // mirror position in local space + m_mirrorPos.setValue(vec[0], vec[1], vec[2]); + // mirror normal vector (pointed towards the back of the mirror) in local space + m_mirrorZ.setValue(-mirrorNormal[0], -mirrorNormal[1], -mirrorNormal[2]); + m_mirrorY.setValue(mirrorUp[0], mirrorUp[1], mirrorUp[2]); + m_mirrorX = m_mirrorY.cross(m_mirrorZ); + m_render = true; + + setBackground(0, 0, 255, 255); +} + +*/ + + Index: source/gameengine/Ketsji/KX_Dome.h =================================================================== --- source/gameengine/Ketsji/KX_Dome.h (revision 0) +++ source/gameengine/Ketsji/KX_Dome.h (revision 0) @@ -0,0 +1,145 @@ +/* $Id: KX_Dome.h +----------------------------------------------------------------------------- + + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser 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, or go to +http://www.gnu.org/copyleft/lesser.txt. +----------------------------------------------------------------------------- +*/ + +#if !defined KX_DOME_H +#define KX_DOME_H + + +//#include "Common.h" + +#include "KX_Scene.h" +#include "KX_Camera.h" +#include "DNA_screen_types.h" +#include "RAS_ICanvas.h" +#include "RAS_IRasterizer.h" +#include "RAS_IRenderTools.h" +#include "KX_KetsjiEngine.h" + +//#include "ImageViewport.h" +//#include "GL/glew.h" +#include <BIF_gl.h> +#include <vector> + +/// class for render 3d scene +class KX_Dome +{ +public: + /// constructor + KX_Dome ( + RAS_ICanvas* m_canvas, + /// rasterizer + RAS_IRasterizer* m_rasterizer, + /// render tools + RAS_IRenderTools* m_rendertools, + /// engine + KX_KetsjiEngine* m_engine + ); +// KX_Scene * scene, KX_Camera * camera); +// ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat); + + /// destructor + virtual ~KX_Dome (void); + + typedef struct { + double u[3], v[3]; + MT_Vector3 verts[3]; //three verts + } DomeFace; + + vector <DomeFace> cubetop, cubebottom, cubefront, cuberight, cubeleft; + + int nfacestop, nfacesbottom, nfacesleft, nfacesright; + double aperture; + + //old + void DrawDomeVert(float theta, float phi); + void DrawDomeSphere(float del); + + //from initTexture + void setBackground (int red, int green, int blue, int alpha); + + void RenderDome(void); + + // Paul Bourke functions + void Dome_CubeCreate(int cubeRes); + void Dome_CubeSplitFace(vector <DomeFace>& face, int *nfaces); + void Dome_CubeFlatten(MT_Vector3& verts); + void Dome_CubeDraw(unsigned int viewport[4], int m_DomeFaces); + + /// get background color +// int getBackground (int idx) { return (idx < 0 || idx > 3) ? 0 : int(m_background[idx]*255.f); } + /// set background color +// void setBackground (int red, int green, int blue, int alpha); + + /// clipping distance +// float getClip (void) { return m_clip; } + /// set whole buffer use +// void setClip (float clip) { m_clip = clip; } + +protected: + /// true if ready to render +// bool m_render; + /// rendered scene + KX_Scene * m_scene; + /// camera for render + KX_Camera * m_camera; + /// do we own the camera? + // bool m_owncamera; // ???? + /// for mirror operation + + float m_clip; // clipping distance + /// canvas + RAS_ICanvas* m_canvas; + /// rasterizer + RAS_IRasterizer* m_rasterizer; + /// render tools + RAS_IRenderTools* m_rendertools; + /// engine + KX_KetsjiEngine* m_engine; + + /// background colour + float m_background[4]; + + + /// render 3d scene to image +// virtual void calcImage (unsigned int texId); + +// void Render(); +// void SetupRenderFrame(KX_Scene *scene, KX_Camera* cam); +// void RenderFrame(KX_Scene* scene, KX_Camera* cam); +// void SetBackGround(KX_WorldInfo* wi); +// void SetWorldSettings(KX_WorldInfo* wi); +}; + +/* my function here. I don't want to use a class unless I need it */ + +//void DomeDraw(unsigned int viewport[4], int m_DomeFaces); + +/* functions from Paul Bourke */ + +//void Dome_CubeSplitFace(KX_Dome::DomeFace* face, int *nfaces); + +//void Dome_CubeDraw(void); + +//KX_Dome::DomeFace* cubetop, cubebottom, cubefront, cuberight, cubeleft; +//int nfacestop, nfacesbottom, nfacesleft, nfacesright; +//double aperture; + +#endif + Index: source/gameengine/Ketsji/KX_GameObject.cpp =================================================================== --- source/gameengine/Ketsji/KX_GameObject.cpp (revision 18000) +++ source/gameengine/Ketsji/KX_GameObject.cpp (working copy) @@ -884,7 +884,28 @@ } } +void KX_GameObject::NodeSetWorldOrientation(const MT_Matrix3x3& rot){ + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return; + + if (m_pPhysicsController1 && !GetSGNode()->GetSGParent()) + { + // see note above + m_pPhysicsController1->setOrientation(rot); + } + +// SG_Node* parent = m_pSGNode->GetSGParent(); +// if (parent != NULL){ + //set worldposition of the parent instead +// parent->SetWorldOrientation(rot); +// GetSGNode()->SetWorldOrientation(rot); +// } +// else + GetSGNode()->SetWorldOrientation(rot); +} + void KX_GameObject::NodeUpdateGS(double time,bool bInitiator) { if (GetSGNode()) Index: source/gameengine/Ketsji/KX_GameObject.h =================================================================== --- source/gameengine/Ketsji/KX_GameObject.h (revision 18000) +++ source/gameengine/Ketsji/KX_GameObject.h (working copy) @@ -365,6 +365,8 @@ // adapt local position so that world position is set to desired position void NodeSetWorldPosition(const MT_Point3& trans); + void NodeSetWorldOrientation(const MT_Matrix3x3& rot ); + void NodeUpdateGS( double time, Index: source/gameengine/Ketsji/KX_KetsjiEngine.cpp =================================================================== --- source/gameengine/Ketsji/KX_KetsjiEngine.cpp (revision 18000) +++ source/gameengine/Ketsji/KX_KetsjiEngine.cpp (working copy) @@ -74,6 +74,11 @@ #include "RAS_FramingManager.h" #include "stdio.h" +#include "KX_Dome.h" + +#include "GL/glew.h" +#include "GL/glu.h" + // If define: little test for Nzc: guarded drawing. If the canvas is // not valid, skip rendering this frame. //#define NZC_GUARDED_OUTPUT @@ -97,8 +102,40 @@ double KX_KetsjiEngine::m_suspendedtime = 0.0; double KX_KetsjiEngine::m_suspendeddelta = 0.0; double KX_KetsjiEngine::m_average_framerate = 0.0; +/* +static const enum KX_KetsjiEngine::DomeFaceTarget { + GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT +}; +*/ +static GLenum DomeFaceTarget [6] = { + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_X +}; +/* +static GLenum DomeFaceTarget [6] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT +}; +*/ +unsigned int DomeFaces[4]; +unsigned int DomeFacesTmp[6]; // tmp to store a single render image +int DomeFaceSize=512; + /** * Constructor of the Ketsji Engine */ @@ -165,7 +202,9 @@ for (int i = tc_first; i < tc_numCategories; i++) m_logger->AddCategory((KX_TimeCategory)i); - + + //Initialize the dome +// m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this); } @@ -176,6 +215,7 @@ KX_KetsjiEngine::~KX_KetsjiEngine() { delete m_logger; + delete m_dome; } @@ -253,8 +293,12 @@ m_sceneconverter = sceneconverter; } +void KX_KetsjiEngine::InitDome() +{ + m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this); + m_dome->Dome_CubeCreate(4); +} - /** * Ketsji Init(), Initializes datastructures and converts data from * Blender into Ketsji native (realtime) format also sets up the @@ -610,11 +654,822 @@ return doRender; } +void KX_KetsjiEngine::tmpInitDome() +{ +// KX_Dome my_dome = KX_Dome(scene,cam); +// KX_Dome *kx_dome = &my_dome; +// m_dome = new KX_Dome(); + //create 6 images + glGenTextures(4, (GLuint*)&DomeFaces); + + for (int i=0;i<4;i++){ + //create tmp texture +// glGenTextures(1, (GLuint*)&DomeFaces[i]); + glBindTexture(GL_TEXTURE_2D, DomeFaces[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, DomeFaceSize, DomeFaceSize, 0, GL_RGBA, + GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + +// glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); +// glGenTextures(1, (GLuint*)&DomeFaces); +// glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); + for (int i=0;i<6;i++){ + glTexImage2D(DomeFaceTarget[i], 0, GL_RGBA, DomeFaceSize, DomeFaceSize, 0, GL_RGBA, + GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP); + } -void KX_KetsjiEngine::Render() + for (int i=0;i<6;i++){ + //create tmp texture + glGenTextures(1, (GLuint*)&DomeFacesTmp[i]); + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, DomeFaceSize, DomeFaceSize, 0, GL_RGBA, + GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } + + printf("\nInitializing Dome\n\n"); + return; +} +void KX_KetsjiEngine::EndDome(){ +// delete m_dome; + //delete the six envmap images created + glDeleteTextures(6, (GLuint*)&DomeFaces); + glDeleteTextures(6, (GLuint*)&DomeFacesTmp); + + printf("\nEnding Dome\n\n"); + return; +} +/* +void DomeDraw(GLuint viewport[4], KX_Dome* dome) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Making the viewport always square + + int can_width = viewport[2]; + int can_height = viewport[3]; + + float ortho_width, ortho_height; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + //Start to Draw + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + glDisable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); + // Commands to Enable EnvMap + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + glEnable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glEnable(GL_NORMALIZE); + + dome->DrawDomeSphere(9.0); + + + glDisable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_DEPTH_TEST); +} +*/ +void DomeDrawTmp2(GLuint viewport[4]) +{ + //6 faces tmp + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + /* Making the viewport always square */ + + int can_width = viewport[2]; + int can_height = viewport[3]; + + float ortho_width, ortho_height = 1.0; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + + glBegin(GL_TRIANGLES); + glColor3f(0.0f ,0.0f, 1.0f); + glVertex3f( 0.0f, 0.5f, 4.0f); + glColor3f(0.0f ,0.5f, 0.0f); + glVertex3f(-0.5f,-0.5f, 4.0f); + glColor3f(1.0f ,0.0f, 0.0f); + glVertex3f( 0.5f,-0.5f, 4.0f); + glEnd(); + + glEnable(GL_TEXTURE_2D); +// DomeFacesTmp[0] -> GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[0]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.35f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.95f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.95f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.35f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[1] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[1]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.35f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.95f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.95f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.35f,-0.8f, 3.0f); + glEnd(); + +// DomeFacesTmp[2] -> GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[2]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.3f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.3f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.3f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(0.3f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[3] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[3]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.3f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.3f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.3f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(0.3f,-0.8f, 3.0f); + glEnd(); + +// DomeFacesTmp[4] -> GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[4]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.95f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f( 0.35f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f( 0.35f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f( 0.95f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[5] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[5]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.95f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(0.35f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(0.35f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f( 0.95f,-0.8f, 3.0f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); +} +void KX_KetsjiEngine::DomeRotateCamera(KX_Camera* cam, int i){ + + MT_Matrix3x3 locRot [6] = { + MT_Matrix3x3( 0.0, 1.0, 0.0, // 90º - Left + -1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0,-1.0, 0.0, // 90º - Right + 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0, 0.0, 1.0, // 90º - Bottom + 0.0,-1.0, 0.0, + 1.0, 0.0, 0.0), + MT_Matrix3x3( 0.0, 0.0,-1.0, // 90º - Top + 0.0,-1.0, 0.0, + -1.0, 0.0, 0.0), + MT_Matrix3x3( 1.0, 0.0, 0.0, // 0º - Front + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3(-1.0, 0.0, 0.0, // 180º - Back + 0.0,-1.0, 0.0, + 0.0, 0.0, 1.0) + }; + + MT_Quaternion cam_ori = cam->GetCameraOrientation(); + MT_Matrix3x3 cam_node_ori = cam->GetSGNode()->GetLocalOrientation(); + MT_Matrix3x3 gloOri = cam->NodeGetWorldOrientation().inverse(); + +// cam->NodeSetWorldOrientation(locRot[i]*cam_node_ori); + + MT_Matrix4x4 cam_mat = cam->GetModelviewMatrix(); + + MT_Vector3 vu = MT_Vector3 (cam_mat[1][0], cam_mat[1][1], cam_mat[1][2]); // view up vector + MT_Vector3 vd = MT_Vector3 (cam_mat[2][0], cam_mat[2][1], cam_mat[2][2]); // view direction + MT_Vector3 vp = MT_Vector3 (cam_mat[3][0], cam_mat[3][1], cam_mat[3][2]); // view position + + cam_mat[3][0] += 10.0; + +// cam->SetModelviewMatrix(cam_mat); + +// m_rasterizer->SetViewMatrix(cam_mat); + +// m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix()); +// cam->NodeSetLocalOrientation(locRot[i]*cam_node_ori); +// cam->GetSGNode()->RelativeRotate(locRot[i],true); +// cam->NodeUpdateGS(0,true); +// MT_Matrix4x4 cam_MM = cam->GetModelviewMatrix(); +// cam_MM *= locRot_4[i]; +// cam->SetModelviewMatrix(cam_MM); +// printf("Rotating Camera !!!!!!\n"); + +} +void KX_KetsjiEngine::DomeRotateView(KX_Camera* cam, int i, MT_Matrix4x4 cam_mat){ +//Mix MatrixMethod +//changing camera +// MT_Matrix4x4 cam_mat = cam->GetModelviewMatrix(); + cam_mat = cam->GetModelviewMatrix(); + + + MT_Vector3 vu = MT_Vector3 (cam_mat[1][0], cam_mat[1][1], cam_mat[1][2]); // view up vector + MT_Vector3 vd = MT_Vector3 (cam_mat[2][0], cam_mat[2][1], cam_mat[2][2]); // view direction + MT_Vector3 vp = MT_Vector3 (cam_mat[3][0], cam_mat[3][1], cam_mat[3][2]); // view position + + vp = cam->NodeGetWorldPosition(); + +// cam->SetModelviewMatrix(cam_mat); + + MT_Vector3 vr; // view right vector + MT_Vector3 vl; // view left vector + + MT_Vector3 vright; + MT_Vector3 vleft; + + vd.normalize(); + vu.normalize(); + + vr = MT_cross(vu, vd); + vr.normalize(); + + vl = MT_cross(vd, vu); + vl.normalize(); + + vright = vr - vd; + vleft = vl - vd; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.0,1.0,cam->GetCameraNear(),cam->GetCameraFar()); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + MT_Matrix3x3 m_lookAt; + switch (i){ + case 0: //top + m_lookAt = MT_Matrix3x3(vp[0],vp[1],vp[2],(vp[0]+vu[0]),(vp[1]+vu[1]),(vp[2]+vu[2]),-vright[0],-vright[1],-vright[2]); + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vu[0]),(vp[1]+vu[1]),(vp[2]+vu[2]),-vright[0],-vright[1],-vright[2]); + break; + case 1: //bottom + m_lookAt = MT_Matrix3x3(vp[0],vp[1],vp[2],(vp[0]-vu[0]),(vp[1]-vu[1]),(vp[2]-vu[2]),-vleft[0],-vleft[1],-vleft[2]); + gluLookAt(vp[0],vp[1],vp[2],(vp[0]-vu[0]),(vp[1]-vu[1]),(vp[2]-vu[2]),-vleft[0],-vleft[1],-vleft[2]); + break; + case 2: // left + m_lookAt = MT_Matrix3x3(vp[0],vp[1],vp[2],(vp[0] +vleft[0]),(vp[1] +vleft[1]),(vp[2]+vleft[2]),vu[0], vu[1], vu[2]); + gluLookAt(vp[0],vp[1],vp[2],(vp[0] +vleft[0]),(vp[1] +vleft[1]),(vp[2]+vleft[2]),vu[0], vu[1], vu[2]); + break; + case 3: // right + m_lookAt = MT_Matrix3x3(vp[0],vp[1],vp[2],(vp[0]+vright[0]),(vp[1]+vright[1]),(vp[2]+vright[2]),vu[0],vu[1],vu[2]); + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vright[0]),(vp[1]+vright[1]),(vp[2]+vright[2]),vu[0],vu[1],vu[2]); + break; + default: + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vd[0]),(vp[1]+vd[1]),(vp[2]+vd[2]),vu[0],vu[1],vu[2]); + break; + }; + + // implementing a manual gluLookAt() + MT_Vector3 m_vd = m_lookAt[1]; + MT_Vector3 m_vu = m_lookAt[2]; + + MT_Vector3 f = m_vd - vp; + MT_Vector3 s = f * m_vu; + MT_Vector3 u = s * f; + + MT_Matrix4x4 n_cam_mat = MT_Matrix4x4(s[0], s[1], s[2], 0.0, + u[0], u[1], u[2], 0.0, + -f[0],-f[1],-f[2], 0.0, + 0.0, 0.0, 0.0, 0.0); + n_cam_mat = cam_mat * n_cam_mat; + +// glMatrixMode(GL_MODELVIEW); +// glLoadIdentity(); +// glMultMatrixfv(n_cam_mat); +// +// cam->SetModelviewMatrix(n_cam_mat); +// m_rasterizer->SetViewMatrix(n_cam_mat, cam->NodeGetWorldPosition(), cam->GetCameraLocation(), cam->GetCameraOrientation()); + +} +/* +void DomeRotateView(KX_Camera* cam, int i){ +//Mix MatrixMethod + MT_Matrix4x4 cam_mat = cam->GetModelviewMatrix(); + + MT_Vector3 vu = MT_Vector3 (cam_mat[1][0], cam_mat[1][1], cam_mat[1][2]); // view up vector + MT_Vector3 vd = MT_Vector3 (cam_mat[2][0], cam_mat[2][1], cam_mat[2][2]); // view direction + MT_Vector3 vp = MT_Vector3 (cam_mat[3][0], cam_mat[3][1], cam_mat[3][2]); // view position + MT_Vector3 aup = MT_Vector3 (0.0,0.0,1.0); + + vp = cam->NodeGetWorldPosition(); + +// cam->SetModelviewMatrix(cam_mat); + + MT_Vector3 vr; // view right vector + MT_Vector3 vl; // view left vector + + MT_Vector3 vright; + MT_Vector3 vleft; + + vd.normalize(); + vu.normalize(); + + vr = MT_cross(vu, vd); + vr.normalize(); + + vl = MT_cross(vd, vu); + vl.normalize(); + + vright = vr - vd; + vleft = vl - vd; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.0,1.0,cam->GetCameraNear(),cam->GetCameraFar()); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + switch (i){ + case 0: //top + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vu[0]),(vp[1]+vu[1]),(vp[2]+vu[2]),-vright[0],-vright[1],-vright[2]); + break; + case 1: //bottom + gluLookAt(vp[0],vp[1],vp[2],(vp[0]-vu[0]),(vp[1]-vu[1]),(vp[2]-vu[2]),-vleft[0],-vleft[1],-vleft[2]); + break; + case 2: // left + gluLookAt(vp[0],vp[1],vp[2],(vp[0] +vleft[0]),(vp[1] +vleft[1]),(vp[2]+vleft[2]),vu[0], vu[1], vu[2]); + break; + case 3: // right + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vright[0]),(vp[1]+vright[1]),(vp[2]+vright[2]),vu[0],vu[1],vu[2]); + break; + default: + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vd[0]),(vp[1]+vd[1]),(vp[2]+vd[2]),vu[0],vu[1],vu[2]); + break; + }; +} +*/ +void DomeRotateViewPaul(KX_Camera* cam, int i){ +//PaulBourke +// SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), +// m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + + MT_Matrix3x3 camOrientMat3x3(cam->GetCameraOrientation()); + +// MT_Matrix3x3 camOrientMat3x3(cam->NodeGetWorldOrientation()); + +// MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention + 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 viewcrossleftVec, viewcrossrightVec; + MT_Vector3 viewleftVec, viewrightVec; + MT_Vector3 viewPos = cam->NodeGetWorldPosition(); + + // actual viewDir + viewDir = camOrientMat3x3 * unitViewDir; // this is the moto convention, vector on right hand side + // actual viewup vec + viewupVec = camOrientMat3x3 * unitViewupVec; + + // vector left to the camera + viewcrossleftVec = viewupVec.cross(viewDir); + + // vector right to the camera + viewcrossrightVec = viewDir.cross(viewupVec); + + //I don't think I really need a safe_normalized here (a regular normalized should work) + viewDir.safe_normalized(); + viewupVec.safe_normalized(); + viewcrossrightVec.safe_normalized(); + viewcrossleftVec.safe_normalized(); + + viewrightVec = viewcrossrightVec + viewDir; + viewleftVec = viewcrossleftVec + viewDir; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.0,1.0,cam->GetCameraNear(),cam->GetCameraFar()); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + switch (i){ + case 0: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0] +viewleftVec[0]),(viewPos[1] +viewleftVec[1]),(viewPos[2]+viewleftVec[2]),viewupVec[0], viewupVec[1], viewupVec[2]); + break; + case 1: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0]+viewrightVec[0]),(viewPos[1]+viewrightVec[1]),(viewPos[2]+viewrightVec[2]),viewupVec[0],viewupVec[1],viewupVec[2]); + break; + case 2: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0]+viewupVec[0]),(viewPos[1]+viewupVec[1]),(viewPos[2]+viewupVec[2]),-viewrightVec[0],-viewrightVec[1],-viewrightVec[2]); + break; + case 3: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0]-viewupVec[0]),(viewPos[1]-viewupVec[1]),(viewPos[2]-viewupVec[2]),-viewleftVec[0],-viewleftVec[1],-viewleftVec[2]); + break; + case 4: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0]-viewupVec[0]),(viewPos[1]-viewupVec[1]),(viewPos[2]-viewupVec[2]),-viewleftVec[0],-viewleftVec[1],-viewleftVec[2]); + break; + case 5: + gluLookAt(viewPos[0],viewPos[1],viewPos[2],(viewPos[0] +viewDir[0]),(viewPos[1] +viewDir[1]),(viewPos[2]+viewDir[2]),viewupVec[0], viewupVec[1], viewupVec[2]); + break; + }; + + +// MT_Scalar glviewmat[16]; +// m_viewmatrix.getValue(glviewmat); + +// glMatrixMode(GL_MODELVIEW); +// glLoadMatrixd(glviewmat); +} +void DomeRotateViewOld(KX_Camera* cam, int i){ + + MT_Matrix4x4 cam_mat = cam->GetModelviewMatrix(); + + MT_Vector3 vu = MT_Vector3 (cam_mat[1][0], cam_mat[1][1], cam_mat[1][2]); // view up vector + MT_Vector3 vd = MT_Vector3 (cam_mat[2][0], cam_mat[2][1], cam_mat[2][2]); // view direction + MT_Vector3 vp = MT_Vector3 (cam_mat[3][0], cam_mat[3][1], cam_mat[3][2]); // view position + +// cam_mat[3][0] += 10.0; + +// cam->SetModelviewMatrix(cam_mat); + + MT_Vector3 vr; // view right vector + MT_Vector3 vl; // view left vector + + MT_Vector3 vright; + MT_Vector3 vleft; + + /* vp = view position */ + MT_Point3 pos = cam->NodeGetWorldPosition(); + MT_Point3 ori = MT_Point3 (0.0, 0.0, 0.0); +// vp = pos - ori; +// vp = cam->GetCameraLocation() +// vp = cam->NodeGetWorldPosition(); + + /* vu - view up vector */ +// MT_Matrix3x3 worldori = cam->NodeGetWorldOrientation(); +// vu = cam->PyGetAxisVect(0.0,0.0,1.0); +// vu = worldori * (pos - ori); + + /* vd - view direction */ +// vd = pos - ori; + + vd.safe_normalized(); + vu.safe_normalized(); + + vr = MT_cross(vd, vu); + vr.safe_normalized(); + + vl = MT_cross(vu, vd); + vl.safe_normalized(); + + vright = vr + vd; + vleft = vl + vd; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.0,1.0,cam->GetCameraNear(),cam->GetCameraFar()); + +// GLdouble vp_x = (GLdouble *)vp.x; + + MT_Matrix3x3 locRot [6] = { + MT_Matrix3x3( 0.0, 1.0, 0.0, // 90º - Left + -1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0,-1.0, 0.0, // 90º - Right + 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0, 0.0, 1.0, // 90º - Bottom + 0.0,-1.0, 0.0, + 1.0, 0.0, 0.0), + MT_Matrix3x3( 0.0, 0.0,-1.0, // 90º - Top + 0.0,-1.0, 0.0, + -1.0, 0.0, 0.0), + MT_Matrix3x3( 1.0, 0.0, 0.0, // 0º - Front + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3(-1.0, 0.0, 0.0, // 180º - Back + 0.0,-1.0, 0.0, + 0.0, 0.0, 1.0) + }; + GLfloat directions[] = { + 0.0, 0.0, -1.0, + 0.0, 0.0, 1.0, + 0.0, -1.0, 0.0, + 0.0, 1.0, 0.0, + -1.0, 0.0, 0.0, + 1.0, 0.0, 0.0 + }; + GLfloat ups[] = { + 0.0, -1.0, 0.0, + 0.0, -1.0, 0.0, + 0.0, 0.0, -1.0, + 0.0, 0.0, 1.0, + 0.0, -1.0, 0.0, + 0.0, -1.0, 0.0 + };/* + GLfloat ups[] = { + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0, + 0.0, 0.0, -1.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.0 + };*/ + //hand-rotating the camera +// gluLookAt(locRot[i][0][0],locRot[i][0][1],locRot[i][0][2],locRot[i][1][0],locRot[i][1][1],locRot[i][1][2],locRot[i][2][0],locRot[i][2][1],locRot[i][2][2]); + + GLfloat *direction = directions; + GLfloat *up = ups; + + //counter + direction += 3*i; + up += 3*i; + + gluLookAt(0.0, 0.0, 0.0, direction[0], direction[1], direction[2], + up[0], up[1], up[2]); + + float vp_x = vp[0]; +/* + switch (i){ + case 0: +// gluLookAt(locRot[0][0],locRot[0][1],locRot[0][3],locRot[0][4],locRot[0][5],locRot[0][6],locRot[0][7],locRot[0][8]); + gluLookAt(vp[0],vp[1],vp[2],(vp[0] +vleft[0]),(vp[1] +vleft[1]),(vp[2]+vleft[2]),vu[0], vu[1], vu[2]); + break; + case 1: + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vright[0]),(vp[1]+vright[1]),(vp[2]+vright[2]),vu[0],vu[1],vu[2]); + break; + case 2: + gluLookAt(vp[0],vp[1],vp[2],(vp[0]+vu[0]),(vp[1]+vu[1]),(vp[2]+vu[2]),-vright[0],-vright[1],-vright[2]); + break; + case 3: + gluLookAt(vp[0],vp[1],vp[2],(vp[0]-vu[0]),(vp[1]-vu[1]),(vp[2]-vu[2]),-vleft[0],-vleft[1],-vleft[2]); + break; + };*/ +} +void DomeBindImages(GLuint viewport[4], int i){ + + // Storing the cubemap image +// glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); +// glCopyTexImage2D(DomeFaceTarget[i], 0, GL_RGBA8, 0, 0, DomeFaceSize, DomeFaceSize, 0); + + //storing the plane image (for tests) + glBindTexture(GL_TEXTURE_2D, DomeFaces[i]); +// glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, viewport[2], viewport[3], 0); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, DomeFaceSize, DomeFaceSize, 0); +} +void KX_KetsjiEngine::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam) +{ + //routine to render the dome + const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); + GLuint viewport[4]={0}; + glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); + unsigned int m_viewport[4] = {viewport[0], viewport[1], viewport[2], viewport[3]}; + + //tmp disabling culling + cam->SetFrustumCulling(false); +// KX_Dome my_dome = KX_Dome(scene,cam); +// KX_Dome *kx_dome = &my_dome; + + //the initial orientation of the camera + MT_Matrix4x4 cam_mat = cam->GetModelviewMatrix(); +// cam->SetModelviewMatrix(cam_mat); + MT_Matrix4x4 cam_mat_b = cam->GetModelviewMatrix(); + + DomePreRender(scene,cam); + for (int i=0;i<4;i++){ + DomeRotateView(cam, i, cam_mat); +// DomeRotateCamera(cam, i); + DomeRenderRoutine(scene, cam); + DomeBindImages(viewport, i); + } +// cam->SetModelviewMatrix(cam_mat); + DomePostRender(scene,cam,stereomode); + m_canvas->EndFrame(); +// m_dome->Dome_CubeCreate(1); // in Dome.cpp + m_dome->Dome_CubeDraw(m_viewport,DomeFaces[0]); + //DomeDraw(m_viewport, DomeFaces); +} +void KX_KetsjiEngine::DomePreRender(KX_Scene* m_scene, KX_Camera* m_camera) +{ + // The final one + RAS_FrameFrustum frustrum; +// const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); + + //Set the viewport to be of the size of the Dome face + m_canvas->SetViewPort(0,0, DomeFaceSize, DomeFaceSize); + m_canvas->ClearColor(m_overrideFrameColorR,m_overrideFrameColorB,m_overrideFrameColorB,1.0); + + m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,GetClockTime()); + m_rendertools->BeginFrame(m_rasterizer); + SetWorldSettings(m_scene->GetWorldInfo()); + m_rendertools->SetAuxilaryClientInfo(m_scene); + m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO); + + m_rasterizer->DisplayFog(); + + if (m_camera->hasValidProjectionMatrix()) + { + m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix()); + } else + { + float lens = m_camera->GetLens(); + bool orthographic = !m_camera->GetCameraData()->m_perspective; + float nearfrust = m_camera->GetCameraNear(); + float farfrust = m_camera->GetCameraFar(); + float aspect_ratio = 1.0f; + + + RAS_FramingManager::ComputeDefaultFrustum( + nearfrust, + farfrust, + lens, + aspect_ratio, + frustrum); + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + + m_camera->SetProjectionMatrix(projmat); + } + + MT_Transform camtrans(m_camera->GetWorldToCamera()); + MT_Matrix4x4 viewmat(camtrans); + + m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), + m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + m_camera->SetModelviewMatrix(viewmat); + + m_scene->UpdateMeshTransformations(); +} +void KX_KetsjiEngine::DomeRenderRoutine(KX_Scene* m_scene, KX_Camera* m_camera) +{ + MT_Transform camtrans(m_camera->GetWorldToCamera()); + m_canvas->ClearColor(m_overrideFrameColorR,m_overrideFrameColorB,m_overrideFrameColorB,1.0); + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); + + m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera); + m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); +} +void KX_KetsjiEngine::DomePostRender(KX_Scene* m_scene, KX_Camera* m_camera, RAS_IRasterizer::StereoMode stereomode) +{ + m_rasterizer->SetStereoMode(stereomode); + //restore glViewport(); + //restore glScissor(); +// m_canvas->SetViewport(viewport[0], viewport[1], viewport[2], viewport[3]); +} +void KX_KetsjiEngine::DomeImageRender(KX_Scene* m_scene, KX_Camera* m_camera) +{ + RAS_FrameFrustum frustrum; + const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); + + // The screen area that ImageViewport will copy is also the rendering zone +// m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0]-1, m_position[1]+m_capSize[1]-1); + // m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]); + m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight()); + m_canvas->ClearColor(m_overrideFrameColorR,m_overrideFrameColorB,m_overrideFrameColorB,1.0); + + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); +// m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,m_engine->GetClockTime()); + m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,GetClockTime()); + m_rendertools->BeginFrame(m_rasterizer); +// m_engine->SetWorldSettings(m_scene->GetWorldInfo()); + SetWorldSettings(m_scene->GetWorldInfo()); + m_rendertools->SetAuxilaryClientInfo(m_scene); + m_rasterizer->DisplayFog(); + // matrix calculation, don't apply any of the stereo mode + m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO); + + if (m_camera->hasValidProjectionMatrix()) + { + m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix()); + } else + { + float lens = m_camera->GetLens(); + bool orthographic = !m_camera->GetCameraData()->m_perspective; + float nearfrust = m_camera->GetCameraNear(); + float farfrust = m_camera->GetCameraFar(); + float aspect_ratio = 1.0f; +// Scene *blenderScene = m_scene->GetBlenderScene(); + + // compute the aspect ratio from frame blender scene settings so that render to texture + // works the same in Blender and in Blender player + // if (blenderScene->r.ysch != 0) + // aspect_ratio = float(blenderScene->r.xsch) / float(blenderScene->r.ysch); + + RAS_FramingManager::ComputeDefaultFrustum( + nearfrust, + farfrust, + lens, + aspect_ratio, + frustrum); + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + + m_camera->SetProjectionMatrix(projmat); + } + + MT_Transform camtrans(m_camera->GetWorldToCamera()); +// if (!m_camera->GetCameraData()->m_perspective) +// camtrans.getOrigin()[2] *= ortho; + MT_Matrix4x4 viewmat(camtrans); + + m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), + m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + m_camera->SetModelviewMatrix(viewmat); + // restore the stereo mode now that the matrix is computed + m_rasterizer->SetStereoMode(stereomode); + + // do not update the mesh, we don't want to do it more than once per frame + //m_scene->UpdateMeshTransformations(); + + m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera); + + m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); +} +void KX_KetsjiEngine::DomeOriginalRender() +{ KX_Scene* firstscene = *m_scenes.begin(); const RAS_FrameSettings &framesettings = firstscene->GetFramingType(); @@ -737,9 +1592,567 @@ EndFrame(); } +void KX_KetsjiEngine::oldDomeRender(KX_Scene* scene, KX_Camera* cam) +{ + //old file + /* + Render (call Render) + copy (Bind); + rotate; + Render (call Render) + copy (Bind); + Render (call Render) + copy (Bind); + Draw + */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + bool override_camera; + RAS_Rect viewport, area; + float left, right, bottom, top, nearfrust, farfrust, focallength; + const float ortho = 100.0; +// KX_Camera* cam = scene->GetActiveCamera(); + + if (!cam) + return; + GetSceneViewport(scene, cam, area, viewport); + + // store the computed viewport in the scene + scene->SetSceneViewport(viewport); + + // set the viewport for this frame and scene + m_canvas->SetViewPort(viewport.GetLeft(), viewport.GetBottom(), + viewport.GetRight(), viewport.GetTop()); + + // see KX_BlenderMaterial::Activate + //m_rasterizer->SetAmbient(); + m_rasterizer->DisplayFog(); + + override_camera = m_overrideCam && (scene->GetName() == m_overrideSceneName); + override_camera = override_camera && (cam->GetName() == "__default__cam__"); + + if (override_camera && m_overrideCamUseOrtho) { + MT_CmMatrix4x4 projmat = m_overrideCamProjMat; + m_rasterizer->SetProjectionMatrix(projmat); + } else if (cam->hasValidProjectionMatrix() && !cam->GetViewport() ) + { + m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix()); + } else + { + RAS_FrameFrustum frustum; + float lens = cam->GetLens(); + nearfrust = cam->GetCameraNear(); + farfrust = cam->GetCameraFar(); + focallength = cam->GetFocalLength(); + + if(override_camera) { + nearfrust = m_overrideCamNear; + farfrust = m_overrideCamFar; + } + + RAS_FramingManager::ComputeFrustum( + scene->GetFramingType(), + area, + viewport, + lens, + nearfrust, + farfrust, + frustum + ); + + left = frustum.x1 * m_cameraZoom; + right = frustum.x2 * m_cameraZoom; + bottom = frustum.y1 * m_cameraZoom; + top = frustum.y2 * m_cameraZoom; + nearfrust = frustum.camnear; + farfrust = frustum.camfar; + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + left, right, bottom, top, nearfrust, farfrust, focallength); + + cam->SetProjectionMatrix(projmat); + + } + + MT_Transform camtrans(cam->GetWorldToCamera()); + if (!cam->GetCameraData()->m_perspective) + camtrans.getOrigin()[2] *= ortho; + MT_Matrix4x4 viewmat(camtrans); + + scene->UpdateMeshTransformations(); + + MT_Quaternion cam_ori = cam->GetCameraOrientation(); + MT_Matrix3x3 cam_node_ori = cam->GetSGNode()->GetLocalOrientation(); + MT_Matrix3x3 gloOri = cam->NodeGetWorldOrientation().inverse(); +// MT_Matrix3x3 gloOri = cam->NodeGetWorldOrientation(); + + + MT_Matrix3x3 locRot [6] = { + MT_Matrix3x3( 1.0, 0.0, 0.0, // 0º - Front + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3(-1.0, 0.0, 0.0, // 180º - Back + 0.0,-1.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0, 1.0, 0.0, // 90º - Left + -1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0,-1.0, 0.0, // 90º - Right + 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0), + MT_Matrix3x3( 0.0, 0.0,-1.0, // 90º - Top + 0.0, 1.0, 0.0, + 1.0, 0.0, 0.0), + MT_Matrix3x3( 0.0, 0.0, 1.0, // 90º - Bottom + 0.0, 1.0, 0.0, + -1.0, 0.0, 0.0) + }; + + glEnable(GL_TEXTURE_2D); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + for (int i = 0;i<6;i++){ + + // cam->NodeSetLocalOrientation(locRot*gloOri); + + // cam->NodeSetLocalOrientation(locRot[i]*cam->GetSGNode()->GetLocalOrientation()); + cam->NodeSetLocalOrientation(locRot[i]*cam_node_ori); + // scene->UpdateMeshTransformations(); + + //// RenderDomeCamera(scene, cam, viewmat, camtrans, rotn180); + +/* Code from the top */ + + GetSceneViewport(scene, cam, area, viewport); + + // store the computed viewport in the scene + scene->SetSceneViewport(viewport); + + // set the viewport for this frame and scene + m_canvas->SetViewPort(viewport.GetLeft(), viewport.GetBottom(), + viewport.GetRight(), viewport.GetTop()); + + RAS_FrameFrustum frustum; + float lens = cam->GetLens(); + nearfrust = cam->GetCameraNear(); + farfrust = cam->GetCameraFar(); + focallength = cam->GetFocalLength(); + + if(override_camera) { + nearfrust = m_overrideCamNear; + farfrust = m_overrideCamFar; + } + + RAS_FramingManager::ComputeFrustum( + scene->GetFramingType(), + area, + viewport, + lens, + nearfrust, + farfrust, + frustum + ); + + left = frustum.x1 * m_cameraZoom; + right = frustum.x2 * m_cameraZoom; + bottom = frustum.y1 * m_cameraZoom; + top = frustum.y2 * m_cameraZoom; + nearfrust = frustum.camnear; + farfrust = frustum.camfar; + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + left, right, bottom, top, nearfrust, farfrust, focallength); + + cam->SetProjectionMatrix(projmat); + +/* end: Code from the top */ + + MT_Transform camtrans_b(cam->GetWorldToCamera()); + MT_Matrix4x4 viewmat_b(camtrans_b); + + m_rasterizer->SetViewMatrix(viewmat_b, cam->NodeGetWorldPosition(), + cam->GetCameraLocation(), cam->GetCameraOrientation()); + + // camtrans = cam->GetWorldToCamera(); + // viewmat = camtrans; + + cam->SetModelviewMatrix(viewmat_b); + + + scene->CalculateVisibleMeshes(m_rasterizer,cam); + + scene->UpdateMeshTransformations(); + + glReadBuffer(GL_BACK); + glDrawBuffer(GL_BACK); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); + glFinish(); + + + // save the images +// glActiveTexture(DomeFacesTmp[i]); + +// drawTestTriangle(viewport, i); // test to make each texture different + + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[i]); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, viewport.GetWidth(), viewport.GetHeight(), 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* + unsigned char *pixels; + + // Allocate memory for the pixel data // + if (! (pixels = (unsigned char *)malloc(viewport.GetWidth() * viewport.GetHeight() * 3))) { + fprintf(stderr, "not enough memory for pixel data\n"); + exit(1); + } + + // Read the framebuffer content and create a texture using the image data + // (glCopyTexImage2D does NOT work for this purpose!) // + glReadPixels(viewport.GetLeft(), viewport.GetBottom(), viewport.GetWidth(), viewport.GetHeight(), GL_RGB, + GL_UNSIGNED_BYTE, pixels); +*/ + + } + /* Copy Color Buffer to EnvMap */ +// glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); +// for (int i=0;i<6;i++){ +// glCopyTexImage2D(DomeFaceTarget[i], 0, GL_RGBA8, 0, 0, viewport.GetWidth(), viewport.GetHeight(), 0); +// glCopyTexImage2D(DomeFaceTarget[i], 0, GL_RGBA8, 0, 0, DomeFaceSize, DomeFaceSize, 0); + +/* + unsigned char *pixels; + + // Allocate memory for the pixel data // + if (! (pixels = (unsigned char *)malloc(viewport.GetWidth() * viewport.GetHeight() * 3))) { + fprintf(stderr, "not enough memory for pixel data\n"); + exit(1); + } + + // Read the framebuffer content and create a texture using the image data + // (glCopyTexImage2D does NOT work for this purpose!) // + glReadPixels(viewport.GetLeft(), viewport.GetBottom(), viewport.GetWidth(), viewport.GetHeight(), GL_RGB, + GL_UNSIGNED_BYTE, pixels); + + glTexImage2D(DomeFaceTarget[i], 0, GL_RGB, viewport.GetWidth(), viewport.GetHeight(), 0, GL_RGB, + GL_UNSIGNED_BYTE, pixels); + +*/ +// } + + /* TMP my test */ + /* +//XXX +*/ +// for (int i=0;i<6;i++){ +// glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[i]); +// glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, viewport.GetWidth(), viewport.GetHeight(), 0); +// } +//XXX + + /* Drawing the Sphere on top of the screen */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + /* Making the viewport always square */ + + int can_width = viewport.GetWidth(); + int can_height = viewport.GetHeight(); + + float ortho_width, ortho_height; + + if (can_width < can_height){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height; + ortho_height = 1.0; + } + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + +// glEnable(GL_TEXTURE_CUBE_MAP_EXT); +// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); +/* + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); +*/ + glDisable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_CUBE_MAP); + glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces[0]); +// glBindTexture(GL_TEXTURE_CUBE_MAP, DomeFaces); // original cubemap call + +// DrawDomeSphere(9.0); + + glBegin(GL_TRIANGLES); + glColor3f(0.0f ,0.0f, 1.0f); + glVertex3f( 0.0f, 0.5f, 4.0f); + glColor3f(0.0f ,0.5f, 0.0f); + glVertex3f(-0.5f,-0.5f, 4.0f); + glColor3f(1.0f ,0.0f, 0.0f); + glVertex3f( 0.5f,-0.5f, 4.0f); + glEnd(); + + glDisable(GL_TEXTURE_CUBE_MAP); + glEnable(GL_TEXTURE_2D); +// glBindTexture(GL_TEXTURE_2D, DomeFaces); +// glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[0]); +// glBindTexture(GL_TEXTURE_2D, 7); + +// DomeFacesTmp[0] -> GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[0]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.35f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.95f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.95f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.35f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[1] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[1]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( -0.35f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.95f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.95f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(-0.35f,-0.8f, 3.0f); + glEnd(); + +// DomeFacesTmp[2] -> GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[2]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.3f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.3f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.3f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(0.3f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[3] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[3]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.3f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(-0.3f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(-0.3f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f(0.3f,-0.8f, 3.0f); + glEnd(); + +// DomeFacesTmp[4] -> GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[4]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.95f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f( 0.35f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f( 0.35f,0.2f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f( 0.95f,0.2f, 3.0f); + glEnd(); + +// DomeFacesTmp[5] -> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT + glBindTexture(GL_TEXTURE_2D, DomeFacesTmp[5]); + glBegin(GL_QUADS); + glColor3f(1.0f ,1.0f, 1.0f); + glTexCoord2f(1.0,1.0); + glVertex3f( 0.95f, -0.2f, 3.0f); + glTexCoord2f(0.0,1.0); + glVertex3f(0.35f,-0.2f, 3.0f); + glTexCoord2f(0.0,0.0); + glVertex3f(0.35f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glVertex3f( 0.95f,-0.8f, 3.0f); + glEnd(); + +/* + glBegin(GL_QUADS); + glTexCoord2f(1.0,1.0); + glColor3f(0.0f ,0.0f, 1.0f); + glVertex3f( 0.8f, 0.8f, 3.0f); + glTexCoord2f(0.0,1.0); + glColor3f(0.0f ,0.5f, 0.0f); + glVertex3f(-0.8f,0.8f, 3.0f); + glTexCoord2f(0.0,0.0); + glColor3f(1.0f ,0.0f, 0.0f); + glVertex3f(-0.8f,-0.8f, 3.0f); + glTexCoord2f(1.0,0.0); + glColor3f(0.5f ,0.5f, 0.0f); + glVertex3f(0.8f,-0.8f, 3.0f); + glEnd(); +*/ + + glEnable(GL_DEPTH_TEST); + + PostRenderFrame(); + + printf("\nRendering Dome\n"); +} + +void KX_KetsjiEngine::Render() +{ + KX_Scene* firstscene = *m_scenes.begin(); + const RAS_FrameSettings &framesettings = firstscene->GetFramingType(); + + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); + + // hiding mouse cursor each frame + // (came back when going out of focus and then back in again) + if (m_hideCursor) + m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); + + // clear the entire game screen with the border color + // only once per frame + m_canvas->BeginDraw(); + if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) { + m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight()); + if (m_overrideFrameColor) + { + // Do not use the framing bar color set in the Blender scenes + m_canvas->ClearColor( + m_overrideFrameColorR, + m_overrideFrameColorG, + m_overrideFrameColorB, + 1.0 + ); + } + else + { + // Use the framing bar color set in the Blender scenes + m_canvas->ClearColor( + framesettings.BarRed(), + framesettings.BarGreen(), + framesettings.BarBlue(), + 1.0 + ); + } + // clear the -whole- viewport + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); + } + + m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_LEFTEYE); + + // BeginFrame() sets the actual drawing area. You can use a part of the window + if (!BeginFrame()) + return; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + KX_Camera* cam = scene->GetActiveCamera(); + // pass the scene's worldsettings to the rasterizer + SetWorldSettings(scene->GetWorldInfo()); + + // shadow buffers + RenderShadowBuffers(scene); + + // Avoid drawing the scene with the active camera twice when it's viewport is enabled + if(cam && !cam->GetViewport()) + { + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + // dome checking + if(m_rasterizer->GetStereoMode()==RAS_IRasterizer::RAS_STEREO_DOME) + RenderDomeFrame(scene,cam); + else + RenderFrame(scene, cam); + } + + list<class KX_Camera*>* cameras = scene->GetCameras(); + + // Draw the scene once for each camera with an enabled viewport + list<KX_Camera*>::iterator it = cameras->begin(); + while(it != cameras->end()) + { + if((*it)->GetViewport()) + { + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + if(m_rasterizer->GetStereoMode()==RAS_IRasterizer::RAS_STEREO_DOME) + RenderDomeFrame(scene, (*it)); + else + RenderFrame(scene, (*it)); + } + + it++; + } + } + + // only one place that checks for stereo + if(m_rasterizer->Stereo()) + { + m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_RIGHTEYE); + + if (!BeginFrame()) + return; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + KX_Camera* cam = scene->GetActiveCamera(); + + // pass the scene's worldsettings to the rasterizer + SetWorldSettings(scene->GetWorldInfo()); + + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + //pass the scene, for picking and raycasting (shadows) + m_rendertools->SetAuxilaryClientInfo(scene); + + // do the rendering + //RenderFrame(scene); + RenderFrame(scene, cam); + } + } // if(m_rasterizer->Stereo()) + + EndFrame(); +} + + + void KX_KetsjiEngine::RequestExit(int exitrequestmode) { m_exitcode = exitrequestmode; Index: source/gameengine/Ketsji/KX_KetsjiEngine.h =================================================================== --- source/gameengine/Ketsji/KX_KetsjiEngine.h (revision 18000) +++ source/gameengine/Ketsji/KX_KetsjiEngine.h (working copy) @@ -37,6 +37,7 @@ #include "KX_Scene.h" #include "KX_Python.h" #include "KX_WorldInfo.h" +#include "RAS_IRasterizer.h" #include <vector> #include <set> @@ -74,6 +75,7 @@ PyObject* m_pythondictionary; class SCA_IInputDevice* m_keyboarddevice; class SCA_IInputDevice* m_mousedevice; + class KX_Dome* m_dome; // dome stereo mode /** Lists of scenes scheduled to be removed at the end of the frame. */ std::set<STR_String> m_removingScenes; @@ -208,6 +210,31 @@ RAS_ICanvas* GetCanvas(){return m_canvas;}; RAS_IRenderTools* GetRenderTools(){return m_rendertools;}; + /// Dome functions + void InitDome(); //recycled :) + void tmpInitDome(); + void EndDome(); + + void RenderDomeFrame(KX_Scene* scene, KX_Camera* cam); + + void DomePreRender(KX_Scene* m_scene, KX_Camera* m_cam); + void DomeRenderRoutine(KX_Scene* m_scene, KX_Camera* m_cam); + void DomePostRender(KX_Scene* m_scene, KX_Camera* m_cam, RAS_IRasterizer::StereoMode stereomode); + + void DomeRotateView(KX_Camera* cam, int i, MT_Matrix4x4 cam_mat); + + + //to be deleted:: + void oldDomeRender(KX_Scene* scene, KX_Camera* cam); + void DomeOriginalRender(); + void DomeImageRender(KX_Scene* m_scene, KX_Camera* m_cam); + void RenderDomeCamera(KX_Scene* scene, KX_Camera* cam, MT_Matrix4x4 viewmat, MT_Transform camtrans, MT_Vector3 camrot); + void DomeRotateCamera(KX_Camera* cam, int i); +// void DrawDomeVert(float theta, float phi); +// void DrawDomeSphere(float del); +// static const enum DomeFaceTarget; + + ///returns true if an update happened to indicate -> Render bool NextFrame(); void Render(); Index: source/gameengine/Rasterizer/RAS_IRasterizer.h =================================================================== --- source/gameengine/Rasterizer/RAS_IRasterizer.h (revision 18000) +++ source/gameengine/Rasterizer/RAS_IRasterizer.h (working copy) @@ -113,6 +113,7 @@ RAS_STEREO_ANAGLYPH, RAS_STEREO_SIDEBYSIDE, RAS_STEREO_VINTERLACE, + RAS_STEREO_DOME, RAS_STEREO_MAXSTEREO }; Index: source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp =================================================================== --- source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp (revision 18000) +++ source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp (working copy) @@ -419,7 +419,7 @@ bool RAS_OpenGLRasterizer::Stereo() { - if(m_stereomode == RAS_STEREO_NOSTEREO) + if(m_stereomode == RAS_STEREO_NOSTEREO || m_stereomode == RAS_STEREO_DOME) return false; else return true;
|