2011-10-23 17:52:20 +00:00
|
|
|
/*
|
2012-11-18 00:30:06 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
2012-03-09 18:28:30 +00:00
|
|
|
*
|
2012-11-18 00:30:06 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2012-03-09 18:28:30 +00:00
|
|
|
*
|
2012-11-18 00:30:06 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2012-03-09 18:28:30 +00:00
|
|
|
*
|
2012-11-18 00:30:06 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2012-03-09 18:28:30 +00:00
|
|
|
*
|
|
|
|
* Contributor(s): Dalai Felinto
|
|
|
|
*
|
|
|
|
* This code is originally inspired on some of the ideas and codes from Paul Bourke.
|
2012-11-18 00:30:06 +00:00
|
|
|
* Developed as part of a Research and Development project for
|
|
|
|
* SAT - La Société des arts technologiques.
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
2012-03-09 18:28:30 +00:00
|
|
|
*/
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2011-10-23 17:52:20 +00:00
|
|
|
/** \file gameengine/Ketsji/KX_Dome.cpp
|
|
|
|
* \ingroup ketsji
|
|
|
|
*/
|
|
|
|
|
2009-04-08 15:06:20 +00:00
|
|
|
#include "KX_Dome.h"
|
|
|
|
|
2010-10-31 04:11:39 +00:00
|
|
|
#ifdef WITH_PYTHON
|
2009-04-08 15:06:20 +00:00
|
|
|
#include <structmember.h>
|
2009-09-29 21:42:40 +00:00
|
|
|
#endif
|
|
|
|
|
2009-04-08 15:06:20 +00:00
|
|
|
#include <float.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "RAS_CameraData.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2014-10-07 20:46:19 +00:00
|
|
|
#include "glew-mx.h"
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
// constructor
|
|
|
|
KX_Dome::KX_Dome (
|
2011-09-01 02:12:53 +00:00
|
|
|
RAS_ICanvas* canvas,
|
|
|
|
/// rasterizer
|
|
|
|
RAS_IRasterizer* rasterizer,
|
|
|
|
/// engine
|
|
|
|
KX_KetsjiEngine* engine,
|
|
|
|
|
|
|
|
short res, //resolution of the mesh
|
|
|
|
short mode, //mode - fisheye, truncated, warped, panoramic, ...
|
|
|
|
short angle,
|
|
|
|
float resbuf, //size adjustment of the buffer
|
|
|
|
short tilt,
|
|
|
|
struct Text* warptext
|
|
|
|
|
|
|
|
):
|
|
|
|
dlistSupported(false),
|
|
|
|
canvaswidth(-1), canvasheight(-1),
|
2014-03-25 03:11:11 +00:00
|
|
|
m_drawingmode(rasterizer->GetDrawingMode()),
|
2011-09-01 02:12:53 +00:00
|
|
|
m_resolution(res),
|
|
|
|
m_mode(mode),
|
|
|
|
m_angle(angle),
|
|
|
|
m_resbuffer(resbuf),
|
|
|
|
m_tilt(tilt),
|
|
|
|
m_canvas(canvas),
|
|
|
|
m_rasterizer(rasterizer),
|
|
|
|
m_engine(engine)
|
2009-04-08 15:06:20 +00:00
|
|
|
{
|
|
|
|
warp.usemesh = false;
|
2009-05-07 20:00:09 +00:00
|
|
|
fboSupported = false;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
if (mode >= DOME_NUM_MODES)
|
|
|
|
m_mode = DOME_FISHEYE;
|
|
|
|
|
|
|
|
if (warptext) // it there is a text data try to warp it
|
|
|
|
{
|
|
|
|
char *buf;
|
|
|
|
buf = txt_to_buf(warptext);
|
|
|
|
if (buf)
|
|
|
|
{
|
|
|
|
warp.usemesh = ParseWarpMesh(STR_String(buf));
|
|
|
|
MEM_freeN(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//setting the viewport size
|
2012-10-08 03:28:11 +00:00
|
|
|
const int *viewport = m_canvas->GetViewPort();
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
SetViewPort(viewport);
|
|
|
|
|
2012-10-21 07:58:38 +00:00
|
|
|
switch (m_mode) {
|
2009-04-08 15:06:20 +00:00
|
|
|
case DOME_FISHEYE:
|
2012-03-28 05:03:24 +00:00
|
|
|
if (m_angle <= 180) {
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop.resize(1);
|
|
|
|
cubebottom.resize(1);
|
|
|
|
cubeleft.resize(2);
|
|
|
|
cuberight.resize(2);
|
|
|
|
|
|
|
|
CreateMeshDome180();
|
|
|
|
m_numfaces = 4;
|
2012-06-17 09:58:26 +00:00
|
|
|
}
|
|
|
|
else if (m_angle > 180) {
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop.resize(2);
|
|
|
|
cubebottom.resize(2);
|
|
|
|
cubeleft.resize(2);
|
|
|
|
cubefront.resize(2);
|
|
|
|
cuberight.resize(2);
|
|
|
|
|
|
|
|
CreateMeshDome250();
|
|
|
|
m_numfaces = 5;
|
|
|
|
} break;
|
2009-04-23 02:27:11 +00:00
|
|
|
case DOME_ENVMAP:
|
|
|
|
m_angle = 360;
|
|
|
|
m_numfaces = 6;
|
2009-04-08 15:06:20 +00:00
|
|
|
break;
|
|
|
|
case DOME_PANORAM_SPH:
|
|
|
|
cubeleft.resize(2);
|
|
|
|
cubeleftback.resize(2);
|
|
|
|
cuberight.resize(2);
|
|
|
|
cuberightback.resize(2);
|
|
|
|
cubetop.resize(2);
|
|
|
|
cubebottom.resize(2);
|
|
|
|
|
|
|
|
m_angle = 360;
|
|
|
|
CreateMeshPanorama();
|
|
|
|
m_numfaces = 6;
|
|
|
|
break;
|
2009-05-17 20:37:13 +00:00
|
|
|
default: //DOME_TRUNCATED_FRONT and DOME_TRUNCATED_REAR
|
2012-03-28 05:03:24 +00:00
|
|
|
if (m_angle <= 180) {
|
2009-05-09 21:04:03 +00:00
|
|
|
cubetop.resize(1);
|
|
|
|
cubebottom.resize(1);
|
|
|
|
cubeleft.resize(2);
|
|
|
|
cuberight.resize(2);
|
2009-05-08 18:59:08 +00:00
|
|
|
|
2009-05-09 21:04:03 +00:00
|
|
|
CreateMeshDome180();
|
|
|
|
m_numfaces = 4;
|
2012-06-17 09:58:26 +00:00
|
|
|
}
|
|
|
|
else if (m_angle > 180) {
|
2009-05-09 21:04:03 +00:00
|
|
|
cubetop.resize(2);
|
|
|
|
cubebottom.resize(2);
|
|
|
|
cubeleft.resize(2);
|
|
|
|
cubefront.resize(2);
|
|
|
|
cuberight.resize(2);
|
|
|
|
|
|
|
|
CreateMeshDome250();
|
|
|
|
m_numfaces = 5;
|
|
|
|
} break;
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
m_numimages =(warp.usemesh?m_numfaces+1:m_numfaces);
|
|
|
|
|
|
|
|
CalculateCameraOrientation();
|
|
|
|
|
|
|
|
CreateGLImages();
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
if (warp.usemesh)
|
2009-05-07 20:00:09 +00:00
|
|
|
fboSupported = CreateFBO();
|
|
|
|
|
2009-04-08 15:06:20 +00:00
|
|
|
dlistSupported = CreateDL();
|
|
|
|
}
|
|
|
|
|
|
|
|
// destructor
|
|
|
|
KX_Dome::~KX_Dome (void)
|
|
|
|
{
|
|
|
|
ClearGLImages();
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
if (fboSupported)
|
2009-05-07 20:00:09 +00:00
|
|
|
glDeleteFramebuffersEXT(1, &warp.fboId);
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
if (dlistSupported)
|
2009-04-08 15:06:20 +00:00
|
|
|
glDeleteLists(dlistId, (GLsizei) m_numimages);
|
|
|
|
}
|
|
|
|
|
2012-10-08 03:28:11 +00:00
|
|
|
void KX_Dome::SetViewPort(const int viewport[4])
|
2009-04-08 15:06:20 +00:00
|
|
|
{
|
2012-03-24 07:52:14 +00:00
|
|
|
if (canvaswidth != m_viewport.GetWidth() || canvasheight != m_viewport.GetHeight())
|
2009-04-08 15:06:20 +00:00
|
|
|
{
|
|
|
|
m_viewport.SetLeft(viewport[0]);
|
|
|
|
m_viewport.SetBottom(viewport[1]);
|
|
|
|
m_viewport.SetRight(viewport[2]);
|
|
|
|
m_viewport.SetTop(viewport[3]);
|
|
|
|
|
|
|
|
CalculateImageSize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::CreateGLImages(void)
|
|
|
|
{
|
|
|
|
glGenTextures(m_numimages, (GLuint*)&domefacesId);
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
for (int j=0;j<m_numfaces;j++) {
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[j]);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, m_imagesize, m_imagesize, 0, GL_RGB8,
|
2013-03-27 20:27:07 +00:00
|
|
|
GL_UNSIGNED_BYTE, NULL);
|
2009-04-08 15:06:20 +00:00
|
|
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, m_imagesize, m_imagesize, 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);
|
|
|
|
}
|
2012-03-28 05:03:24 +00:00
|
|
|
if (warp.usemesh) {
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]);
|
2009-05-07 20:00:09 +00:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, warp.imagesize, warp.imagesize, 0, GL_RGB8,
|
2013-03-27 20:27:07 +00:00
|
|
|
GL_UNSIGNED_BYTE, NULL);
|
2009-05-07 20:00:09 +00:00
|
|
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, warp.imagesize, warp.imagesize, 0);
|
2009-04-08 15:06:20 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::ClearGLImages(void)
|
|
|
|
{
|
|
|
|
glDeleteTextures(m_numimages, (GLuint*)&domefacesId);
|
2012-03-09 18:28:30 +00:00
|
|
|
#if 0
|
2009-04-08 15:06:20 +00:00
|
|
|
for (int i=0;i<m_numimages;i++)
|
2012-03-24 07:52:14 +00:00
|
|
|
if (glIsTexture(domefacesId[i]))
|
2009-04-08 15:06:20 +00:00
|
|
|
glDeleteTextures(1, (GLuint*)&domefacesId[i]);
|
2012-03-09 18:28:30 +00:00
|
|
|
#endif
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::CalculateImageSize(void)
|
|
|
|
{
|
2012-03-09 18:28:30 +00:00
|
|
|
/*
|
|
|
|
* - determine the minimum buffer size
|
2012-03-18 07:38:51 +00:00
|
|
|
* - reduce the buffer for better performance
|
2012-03-09 18:28:30 +00:00
|
|
|
* - create a power of 2 texture bigger than the buffer
|
|
|
|
*/
|
2009-04-08 15:06:20 +00:00
|
|
|
canvaswidth = m_canvas->GetWidth();
|
|
|
|
canvasheight = m_canvas->GetHeight();
|
|
|
|
|
|
|
|
m_buffersize = (canvaswidth > canvasheight?canvasheight:canvaswidth);
|
2009-04-23 13:30:34 +00:00
|
|
|
m_buffersize = (int)(m_buffersize*m_resbuffer); //reduce buffer size for better performance
|
2009-04-30 02:41:07 +00:00
|
|
|
|
2009-04-08 15:06:20 +00:00
|
|
|
int i = 0;
|
|
|
|
while ((1 << i) <= m_buffersize)
|
|
|
|
i++;
|
|
|
|
m_imagesize = (1 << i);
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (warp.usemesh) {
|
2009-05-09 21:54:22 +00:00
|
|
|
// warp FBO needs to be up to twice as big as m_buffersize to get more resolution
|
|
|
|
warp.imagesize = m_imagesize;
|
|
|
|
if (m_buffersize == m_imagesize)
|
|
|
|
warp.imagesize *= 2;
|
2009-05-07 20:00:09 +00:00
|
|
|
|
|
|
|
//if FBO is not working/supported, we use the canvas dimension as buffer
|
|
|
|
warp.bufferwidth = canvaswidth;
|
|
|
|
warp.bufferheight = canvasheight;
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-30 11:49:58 +00:00
|
|
|
bool KX_Dome::CreateDL()
|
|
|
|
{
|
2009-04-08 15:06:20 +00:00
|
|
|
dlistId = glGenLists((GLsizei) m_numimages);
|
|
|
|
if (dlistId != 0) {
|
2012-03-28 05:03:24 +00:00
|
|
|
if (m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED_FRONT || m_mode == DOME_TRUNCATED_REAR) {
|
2009-04-08 15:06:20 +00:00
|
|
|
glNewList(dlistId, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cubetop, nfacestop);
|
|
|
|
glEndList();
|
|
|
|
|
|
|
|
glNewList(dlistId+1, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cubebottom, nfacesbottom);
|
|
|
|
glEndList();
|
|
|
|
|
|
|
|
glNewList(dlistId+2, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cubeleft, nfacesleft);
|
|
|
|
glEndList();
|
|
|
|
|
|
|
|
glNewList(dlistId+3, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cuberight, nfacesright);
|
|
|
|
glEndList();
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (m_angle > 180) {
|
2009-04-08 15:06:20 +00:00
|
|
|
glNewList(dlistId+4, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cubefront, nfacesfront);
|
|
|
|
glEndList();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (m_mode == DOME_PANORAM_SPH)
|
|
|
|
{
|
|
|
|
glNewList(dlistId, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cubetop, nfacestop);
|
|
|
|
glEndList();
|
|
|
|
|
|
|
|
glNewList(dlistId+1, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cubebottom, nfacesbottom);
|
|
|
|
glEndList();
|
|
|
|
|
|
|
|
glNewList(dlistId+2, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cubeleft, nfacesleft);
|
|
|
|
glEndList();
|
|
|
|
|
|
|
|
glNewList(dlistId+3, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cuberight, nfacesright);
|
|
|
|
glEndList();
|
|
|
|
|
|
|
|
glNewList(dlistId+4, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cubeleftback, nfacesleftback);
|
|
|
|
glEndList();
|
|
|
|
|
|
|
|
glNewList(dlistId+5, GL_COMPILE);
|
|
|
|
GLDrawTriangles(cuberightback, nfacesrightback);
|
|
|
|
glEndList();
|
|
|
|
}
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (warp.usemesh) {
|
2009-04-08 15:06:20 +00:00
|
|
|
glNewList((dlistId + m_numfaces), GL_COMPILE);
|
|
|
|
GLDrawWarpQuads();
|
|
|
|
glEndList();
|
|
|
|
}
|
|
|
|
|
|
|
|
//clearing the vectors
|
|
|
|
cubetop.clear();
|
|
|
|
cubebottom.clear();
|
|
|
|
cuberight.clear();
|
|
|
|
cubeleft.clear();
|
|
|
|
cubefront.clear();
|
|
|
|
cubeleftback.clear();
|
|
|
|
cuberightback.clear();
|
|
|
|
warp.nodes.clear();
|
|
|
|
|
|
|
|
} else // genList failed
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-05-07 20:00:09 +00:00
|
|
|
bool KX_Dome::CreateFBO(void)
|
|
|
|
{
|
2009-05-08 18:59:08 +00:00
|
|
|
if (!GLEW_EXT_framebuffer_object)
|
|
|
|
{
|
|
|
|
printf("Dome Error: FrameBuffer unsupported. Using low resolution warp image.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-05-07 20:00:09 +00:00
|
|
|
glGenFramebuffersEXT(1, &warp.fboId);
|
2012-03-24 07:52:14 +00:00
|
|
|
if (warp.fboId==0)
|
2009-05-07 20:00:09 +00:00
|
|
|
{
|
|
|
|
printf("Dome Error: Invalid frame buffer object. Using low resolution warp image.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, warp.fboId);
|
|
|
|
|
|
|
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
|
|
|
GL_TEXTURE_2D, domefacesId[m_numfaces], 0);
|
|
|
|
|
|
|
|
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
if (status == GL_FRAMEBUFFER_UNSUPPORTED_EXT)
|
2009-05-07 20:00:09 +00:00
|
|
|
{
|
2009-05-08 18:59:08 +00:00
|
|
|
printf("Dome Error: FrameBuffer settings unsupported. Using low resolution warp image.");
|
2009-05-07 20:00:09 +00:00
|
|
|
return false;
|
|
|
|
}
|
2012-03-24 07:52:14 +00:00
|
|
|
else if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
2009-05-07 20:00:09 +00:00
|
|
|
{
|
|
|
|
glDeleteFramebuffersEXT(1, &warp.fboId);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
|
|
|
|
|
|
|
//nothing failed: we can use the whole FBO as buffersize
|
|
|
|
warp.bufferwidth = warp.bufferheight = warp.imagesize;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-04-08 15:06:20 +00:00
|
|
|
void KX_Dome::GLDrawTriangles(vector <DomeFace>& face, int nfaces)
|
|
|
|
{
|
|
|
|
int i,j;
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
for (i=0;i<nfaces;i++) {
|
|
|
|
for (j=0;j<3;j++) {
|
|
|
|
glTexCoord2f(face[i].u[j],face[i].v[j]);
|
|
|
|
glVertex3f((GLfloat)face[i].verts[j][0],(GLfloat)face[i].verts[j][1],(GLfloat)face[i].verts[j][2]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::GLDrawWarpQuads(void)
|
|
|
|
{
|
|
|
|
int i, j, i2;
|
2009-05-07 20:00:09 +00:00
|
|
|
|
|
|
|
float uv_width = (float)(warp.bufferwidth) / warp.imagesize;
|
|
|
|
float uv_height = (float)(warp.bufferheight) / warp.imagesize;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (warp.mode ==2 ) {
|
2009-04-08 15:06:20 +00:00
|
|
|
glBegin(GL_QUADS);
|
|
|
|
for (i=0;i<warp.n_height-1;i++) {
|
|
|
|
for (j=0;j<warp.n_width-1;j++) {
|
2012-03-24 07:52:14 +00:00
|
|
|
if (warp.nodes[i][j].i < 0 || warp.nodes[i+1][j].i < 0 || warp.nodes[i+1][j+1].i < 0 || warp.nodes[i][j+1].i < 0)
|
2009-04-08 15:06:20 +00:00
|
|
|
continue;
|
|
|
|
|
2013-08-14 02:59:09 +00:00
|
|
|
glColor3f(warp.nodes[i][j+1].i, warp.nodes[i][j+1].i, warp.nodes[i][j+1].i);
|
|
|
|
glTexCoord2f((warp.nodes[i][j+1].u * uv_width), (warp.nodes[i][j+1].v * uv_height));
|
2015-12-16 00:31:38 +00:00
|
|
|
glVertex3f(warp.nodes[i][j+1].x, warp.nodes[i][j+1].y,0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
glColor3f(warp.nodes[i+1][j+1].i, warp.nodes[i+1][j+1].i, warp.nodes[i+1][j+1].i);
|
|
|
|
glTexCoord2f((warp.nodes[i+1][j+1].u * uv_width), (warp.nodes[i+1][j+1].v * uv_height));
|
2015-12-16 00:31:38 +00:00
|
|
|
glVertex3f(warp.nodes[i+1][j+1].x, warp.nodes[i+1][j+1].y,0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2013-08-14 02:59:09 +00:00
|
|
|
glColor3f(warp.nodes[i+1][j].i, warp.nodes[i+1][j].i, warp.nodes[i+1][j].i);
|
|
|
|
glTexCoord2f((warp.nodes[i+1][j].u * uv_width), (warp.nodes[i+1][j].v * uv_height));
|
2015-12-16 00:31:38 +00:00
|
|
|
glVertex3f(warp.nodes[i+1][j].x, warp.nodes[i+1][j].y,0.0f);
|
2013-08-14 02:59:09 +00:00
|
|
|
|
|
|
|
glColor3f(warp.nodes[i][j].i, warp.nodes[i][j].i, warp.nodes[i][j].i);
|
|
|
|
glTexCoord2f((warp.nodes[i][j].u * uv_width), (warp.nodes[i][j].v * uv_height));
|
2015-12-16 00:31:38 +00:00
|
|
|
glVertex3f(warp.nodes[i][j].x, warp.nodes[i][j].y,0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
2012-03-28 05:03:24 +00:00
|
|
|
else if (warp.mode == 1) {
|
2009-04-08 15:06:20 +00:00
|
|
|
glBegin(GL_QUADS);
|
|
|
|
for (i=0;i<warp.n_height-1;i++) {
|
|
|
|
for (j=0;j<warp.n_width-1;j++) {
|
|
|
|
i2 = (i+1) % warp.n_width; // Wrap around, i = warp.n_width = 0
|
|
|
|
|
|
|
|
if (warp.nodes[i][j].i < 0 || warp.nodes[i2][j].i < 0 || warp.nodes[i2][j+1].i < 0 || warp.nodes[i][j+1].i < 0)
|
|
|
|
continue;
|
|
|
|
|
2011-11-11 13:09:14 +00:00
|
|
|
glColor3f(warp.nodes[i][j].i,warp.nodes[i][j].i,warp.nodes[i][j].i);
|
|
|
|
glTexCoord2f((warp.nodes[i][j].u * uv_width), (warp.nodes[i][j].v * uv_height));
|
2015-12-16 00:31:38 +00:00
|
|
|
glVertex3f(warp.nodes[i][j].x,warp.nodes[i][j].y,0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2011-11-11 13:09:14 +00:00
|
|
|
glColor3f(warp.nodes[i2][j].i,warp.nodes[i2][j].i,warp.nodes[i2][j].i);
|
|
|
|
glTexCoord2f((warp.nodes[i2][j].u * uv_width), (warp.nodes[i2][j].v * uv_height));
|
2015-12-16 00:31:38 +00:00
|
|
|
glVertex3f(warp.nodes[i2][j].x,warp.nodes[i2][j].y,0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2011-11-11 13:09:14 +00:00
|
|
|
glColor3f(warp.nodes[i2][j+1].i,warp.nodes[i2][j+1].i,warp.nodes[i2][j+1].i);
|
|
|
|
glTexCoord2f((warp.nodes[i2][j+1].u * uv_width), (warp.nodes[i2][j+1].v * uv_height));
|
2015-12-16 00:31:38 +00:00
|
|
|
glVertex3f(warp.nodes[i2][j+1].x,warp.nodes[i2][j+1].y,0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2011-11-11 13:09:14 +00:00
|
|
|
glColor3f(warp.nodes[i2][j+1].i,warp.nodes[i2][j+1].i,warp.nodes[i2][j+1].i);
|
|
|
|
glTexCoord2f((warp.nodes[i2][j+1].u * uv_width), (warp.nodes[i2][j+1].v * uv_height));
|
2015-12-16 00:31:38 +00:00
|
|
|
glVertex3f(warp.nodes[i2][j+1].x,warp.nodes[i2][j+1].y,0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
glEnd();
|
2012-06-06 22:38:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-05-07 20:00:09 +00:00
|
|
|
printf("Dome Error: Warp Mode %d unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n", warp.mode);
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool KX_Dome::ParseWarpMesh(STR_String text)
|
|
|
|
{
|
2012-03-09 18:28:30 +00:00
|
|
|
/*
|
|
|
|
* //Notes about the supported data format:
|
|
|
|
* File example::
|
|
|
|
* mode
|
|
|
|
* width height
|
|
|
|
* n0_x n0_y n0_u n0_v n0_i
|
|
|
|
* n1_x n1_y n1_u n1_v n1_i
|
|
|
|
* n2_x n1_y n2_u n2_v n2_i
|
|
|
|
* n3_x n3_y n3_u n3_v n3_i
|
|
|
|
* (...)
|
|
|
|
* First line is the image type the mesh is support to be applied to: 2 = fisheye, 1=radial
|
2013-06-25 22:58:23 +00:00
|
|
|
* The next line has the mesh dimensions
|
2012-03-09 18:28:30 +00:00
|
|
|
* Rest of the lines are the nodes of the mesh. Each line has x y u v i
|
2012-07-03 19:09:07 +00:00
|
|
|
* (x,y) are the normalized screen coordinates
|
2012-03-09 18:28:30 +00:00
|
|
|
* (u,v) texture coordinates
|
|
|
|
* i a multiplicative intensity factor
|
|
|
|
*
|
|
|
|
* x varies from -screen aspect to screen aspect
|
|
|
|
* y varies from -1 to 1
|
|
|
|
* u and v vary from 0 to 1
|
|
|
|
* i ranges from 0 to 1, if negative don't draw that mesh node
|
|
|
|
*/
|
2009-04-23 13:30:34 +00:00
|
|
|
int i;
|
2009-04-08 15:06:20 +00:00
|
|
|
int nodeX=0, nodeY=0;
|
|
|
|
|
|
|
|
vector<STR_String> columns, lines;
|
|
|
|
|
|
|
|
lines = text.Explode('\n');
|
2012-03-28 05:03:24 +00:00
|
|
|
if (lines.size() < 6) {
|
2009-05-07 20:00:09 +00:00
|
|
|
printf("Dome Error: Warp Mesh File with insufficient data!\n");
|
2009-04-08 15:06:20 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
columns = lines[1].Explode(' ');
|
2012-03-24 07:52:14 +00:00
|
|
|
if (columns.size() == 1)
|
2009-04-30 15:27:38 +00:00
|
|
|
columns = lines[1].Explode('\t');
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (columns.size() !=2) {
|
2009-05-07 20:00:09 +00:00
|
|
|
printf("Dome Error: Warp Mesh File incorrect. The second line should contain: width height.\n");
|
2009-04-08 15:06:20 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
warp.mode = atoi(lines[0]);// 1 = radial, 2 = fisheye
|
|
|
|
|
|
|
|
warp.n_width = atoi(columns[0]);
|
|
|
|
warp.n_height = atoi(columns[1]);
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if ((int)lines.size() < 2 + (warp.n_width * warp.n_height)) {
|
2009-05-07 20:00:09 +00:00
|
|
|
printf("Dome Error: Warp Mesh File with insufficient data!\n");
|
2009-04-08 15:06:20 +00:00
|
|
|
return false;
|
2012-06-06 22:38:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-04-08 20:10:27 +00:00
|
|
|
warp.nodes = vector<vector<WarpMeshNode> > (warp.n_height, vector<WarpMeshNode>(warp.n_width));
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
for (i=2; i-2 < (warp.n_width*warp.n_height); i++) {
|
2009-04-08 15:06:20 +00:00
|
|
|
columns = lines[i].Explode(' ');
|
2012-03-24 07:52:14 +00:00
|
|
|
if (columns.size() == 1)
|
2009-04-30 15:27:38 +00:00
|
|
|
columns = lines[i].Explode('\t');
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (columns.size() == 5) {
|
2009-04-08 15:06:20 +00:00
|
|
|
nodeX = (i-2)%warp.n_width;
|
|
|
|
nodeY = ((i-2) - nodeX) / warp.n_width;
|
|
|
|
|
|
|
|
warp.nodes[nodeY][nodeX].x = atof(columns[0]);
|
|
|
|
warp.nodes[nodeY][nodeX].y = atof(columns[1]);
|
|
|
|
warp.nodes[nodeY][nodeX].u = atof(columns[2]);
|
|
|
|
warp.nodes[nodeY][nodeX].v = atof(columns[3]);
|
|
|
|
warp.nodes[nodeY][nodeX].i = atof(columns[4]);
|
|
|
|
}
|
2012-06-06 22:38:39 +00:00
|
|
|
else {
|
2009-04-08 15:06:20 +00:00
|
|
|
warp.nodes.clear();
|
2009-05-07 20:00:09 +00:00
|
|
|
printf("Dome Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n");
|
2009-04-08 15:06:20 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::CreateMeshDome180(void)
|
|
|
|
{
|
2012-03-09 18:28:30 +00:00
|
|
|
/*
|
|
|
|
* 1)- Define the faces of half of a cube
|
|
|
|
* - each face is made out of 2 triangles
|
|
|
|
* 2) Subdivide the faces
|
|
|
|
* - more resolution == more curved lines
|
|
|
|
* 3) Spherize the cube
|
|
|
|
* - normalize the verts
|
|
|
|
* 4) Flatten onto xz plane
|
|
|
|
* - transform it onto an equidistant spherical projection techniques to transform the sphere onto a dome image
|
|
|
|
*/
|
2009-04-08 15:06:20 +00:00
|
|
|
int i,j;
|
|
|
|
float uv_ratio = (float)(m_buffersize-1) / m_imagesize;
|
|
|
|
|
2011-09-17 09:43:51 +00:00
|
|
|
m_radangle = DEG2RADF(m_angle); //calculates the radians angle, used for flattening
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
//creating faces for the env mapcube 180deg Dome
|
2009-04-08 15:06:20 +00:00
|
|
|
// Top Face - just a triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[0][0] = (float)(-M_SQRT2) / 2.0f;
|
|
|
|
cubetop[0].verts[0][1] = 0.0f;
|
|
|
|
cubetop[0].verts[0][2] = 0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].u[0] = 0.0;
|
|
|
|
cubetop[0].v[0] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[1][0] = 0.0f;
|
|
|
|
cubetop[0].verts[1][1] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cubetop[0].verts[1][2] = 0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].u[1] = 0.0;
|
|
|
|
cubetop[0].v[1] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[2][0] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cubetop[0].verts[2][1] = 0.0f;
|
|
|
|
cubetop[0].verts[2][2] = 0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].u[2] = uv_ratio;
|
|
|
|
cubetop[0].v[2] = 0.0;
|
|
|
|
|
|
|
|
nfacestop = 1;
|
|
|
|
|
|
|
|
/* Bottom face - just a triangle */
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[0][0] = (float)(-M_SQRT2) / 2.0f;
|
|
|
|
cubebottom[0].verts[0][1] = 0.0f;
|
|
|
|
cubebottom[0].verts[0][2] = -0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].u[0] = uv_ratio;
|
|
|
|
cubebottom[0].v[0] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[1][0] = (float)M_SQRT2 / 2.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].verts[1][1] = 0;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[1][2] = -0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].u[1] = 0.0;
|
|
|
|
cubebottom[0].v[1] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[2][0] = 0.0f;
|
|
|
|
cubebottom[0].verts[2][1] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cubebottom[0].verts[2][2] = -0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].u[2] = 0.0;
|
|
|
|
cubebottom[0].v[2] = 0.0;
|
|
|
|
|
2012-09-16 04:58:18 +00:00
|
|
|
nfacesbottom = 1;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
/* Left face - two triangles */
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].verts[0][0] = (float)(-M_SQRT2) / 2.0f;
|
|
|
|
cubeleft[0].verts[0][1] = 0.0f;
|
|
|
|
cubeleft[0].verts[0][2] = -0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[0].u[0] = 0.0;
|
|
|
|
cubeleft[0].v[0] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].verts[1][0] = 0.0f;
|
|
|
|
cubeleft[0].verts[1][1] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cubeleft[0].verts[1][2] = -0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[0].u[1] = uv_ratio;
|
|
|
|
cubeleft[0].v[1] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].verts[2][0] = (float)(-M_SQRT2) / 2.0f;
|
|
|
|
cubeleft[0].verts[2][1] = 0.0f;
|
|
|
|
cubeleft[0].verts[2][2] = 0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[0].u[2] = 0.0;
|
|
|
|
cubeleft[0].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].verts[0][0] = (float)(-M_SQRT2) / 2.0f;
|
|
|
|
cubeleft[1].verts[0][1] = 0.0f;
|
|
|
|
cubeleft[1].verts[0][2] = 0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[1].u[0] = 0.0;
|
|
|
|
cubeleft[1].v[0] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].verts[1][0] = 0.0f;
|
|
|
|
cubeleft[1].verts[1][1] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cubeleft[1].verts[1][2] = -0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[1].u[1] = uv_ratio;
|
|
|
|
cubeleft[1].v[1] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].verts[2][0] = 0.0f;
|
|
|
|
cubeleft[1].verts[2][1] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cubeleft[1].verts[2][2] = 0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[1].u[2] = uv_ratio;
|
|
|
|
cubeleft[1].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
nfacesleft = 2;
|
|
|
|
|
|
|
|
/* Right face - two triangles */
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].verts[0][0] = 0.0f;
|
|
|
|
cuberight[0].verts[0][1] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cuberight[0].verts[0][2] = -0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[0].u[0] = 0.0;
|
|
|
|
cuberight[0].v[0] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].verts[1][0] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cuberight[0].verts[1][1] = 0.0f;
|
|
|
|
cuberight[0].verts[1][2] = -0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[0].u[1] = uv_ratio;
|
|
|
|
cuberight[0].v[1] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].verts[2][0] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cuberight[0].verts[2][1] = 0.0f;
|
|
|
|
cuberight[0].verts[2][2] = 0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[0].u[2] = uv_ratio;
|
|
|
|
cuberight[0].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[1].verts[0][0] = 0.0f;
|
|
|
|
cuberight[1].verts[0][1] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cuberight[1].verts[0][2] = -0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[1].u[0] = 0.0;
|
|
|
|
cuberight[1].v[0] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[1].verts[1][0] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cuberight[1].verts[1][1] = 0.0f;
|
|
|
|
cuberight[1].verts[1][2] = 0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[1].u[1] = uv_ratio;
|
|
|
|
cuberight[1].v[1] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[1].verts[2][0] = 0.0f;
|
|
|
|
cuberight[1].verts[2][1] = (float)M_SQRT2 / 2.0f;
|
|
|
|
cuberight[1].verts[2][2] = 0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[1].u[2] = 0.0;
|
|
|
|
cuberight[1].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
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. Not that important since we are using DisplayLists
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
for (i=0;i<m_resolution;i++) {
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop.resize(4*nfacestop);
|
|
|
|
SplitFace(cubetop,&nfacestop);
|
|
|
|
cubebottom.resize(4*nfacesbottom);
|
2012-09-16 04:58:18 +00:00
|
|
|
SplitFace(cubebottom,&nfacesbottom);
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft.resize(4*nfacesleft);
|
|
|
|
SplitFace(cubeleft,&nfacesleft);
|
|
|
|
cuberight.resize(4*nfacesright);
|
|
|
|
SplitFace(cuberight,&nfacesright);
|
2012-09-16 04:58:18 +00:00
|
|
|
}
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
// Turn into a hemisphere
|
2012-03-28 05:03:24 +00:00
|
|
|
for (j=0;j<3;j++) {
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacestop;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[i].verts[j].normalize();
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesbottom;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[i].verts[j].normalize();
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesleft;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[i].verts[j].normalize();
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesright;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[i].verts[j].normalize();
|
|
|
|
}
|
|
|
|
|
|
|
|
//flatten onto xz plane
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacestop;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenDome(cubetop[i].verts);
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesbottom;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenDome(cubebottom[i].verts);
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesleft;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenDome(cubeleft[i].verts);
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesright;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenDome(cuberight[i].verts);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::CreateMeshDome250(void)
|
|
|
|
{
|
2012-03-09 18:28:30 +00:00
|
|
|
/*
|
|
|
|
* 1)- Define the faces of a cube without the back face
|
|
|
|
* - each face is made out of 2 triangles
|
|
|
|
* 2) Subdivide the faces
|
|
|
|
* - more resolution == more curved lines
|
|
|
|
* 3) Spherize the cube
|
|
|
|
* - normalize the verts
|
|
|
|
* 4) Flatten onto xz plane
|
|
|
|
* - transform it onto an equidistant spherical projection techniques to transform the sphere onto a dome image
|
|
|
|
*/
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
int i,j;
|
|
|
|
float uv_height, uv_base;
|
|
|
|
float verts_height;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
float rad_ang = m_angle * MT_PI / 180.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
float uv_ratio = (float)(m_buffersize-1) / m_imagesize;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
m_radangle = m_angle * (float)M_PI/180.0f;//calculates the radians angle, used for flattening
|
2012-03-09 18:28:30 +00:00
|
|
|
/*
|
|
|
|
* verts_height is the exactly needed height of the cube faces (not always 1.0).
|
2012-03-20 22:56:26 +00:00
|
|
|
* When we want some horizontal information (e.g. for horizontal 220deg domes) we don't need to create and tessellate the whole cube.
|
|
|
|
* Therefore the lateral cube faces could be small, and the tessellate mesh would be completely used.
|
2012-03-18 07:38:51 +00:00
|
|
|
* (if we always worked with verts_height = 1.0, we would be discarding a lot of the calculated and tessellated geometry).
|
2012-03-09 18:28:30 +00:00
|
|
|
*
|
|
|
|
* So I came out with this formula:
|
|
|
|
* verts_height = tan((rad_ang/2) - (MT_PI/2))*sqrt(2.0);
|
|
|
|
*
|
|
|
|
* Here we take half the sphere(rad_ang/2) and subtract a quarter of it (MT_PI/2)
|
|
|
|
* Therefore we have the length in radians of the dome/sphere over the horizon.
|
|
|
|
* Once we take the tangent of that angle, you have the verts coordinate corresponding to the verts on the side faces.
|
|
|
|
* Then we need to multiply it by sqrt(2.0) to get the coordinate of the verts on the diagonal of the original cube.
|
|
|
|
*/
|
2015-12-16 00:31:38 +00:00
|
|
|
verts_height = tanf((rad_ang / 2.0f) - (MT_PI / 2.0f)) * (float)M_SQRT2;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-08-02 21:17:12 +00:00
|
|
|
uv_height = uv_ratio * ( (verts_height / 2.0f) + 0.5f);
|
2015-12-16 00:31:38 +00:00
|
|
|
uv_base = uv_ratio * (1.0f - ((verts_height / 2.0f) + 0.5f));
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
//creating faces for the env mapcube 180deg Dome
|
2009-04-08 15:06:20 +00:00
|
|
|
// Front Face - 2 triangles
|
2015-12-16 00:31:38 +00:00
|
|
|
cubefront[0].verts[0][0] =-1.0f;
|
|
|
|
cubefront[0].verts[0][1] = 1.0f;
|
|
|
|
cubefront[0].verts[0][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubefront[0].u[0] = 0.0;
|
|
|
|
cubefront[0].v[0] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubefront[0].verts[1][0] = 1.0f;
|
|
|
|
cubefront[0].verts[1][1] = 1.0f;
|
|
|
|
cubefront[0].verts[1][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubefront[0].u[1] = uv_ratio;
|
|
|
|
cubefront[0].v[1] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubefront[0].verts[2][0] =-1.0f;
|
|
|
|
cubefront[0].verts[2][1] = 1.0f;
|
|
|
|
cubefront[0].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubefront[0].u[2] = 0.0;
|
|
|
|
cubefront[0].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cubefront[1].verts[0][0] = 1.0f;
|
|
|
|
cubefront[1].verts[0][1] = 1.0f;
|
|
|
|
cubefront[1].verts[0][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubefront[1].u[0] = uv_ratio;
|
|
|
|
cubefront[1].v[0] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubefront[1].verts[1][0] =-1.0f;
|
|
|
|
cubefront[1].verts[1][1] = 1.0f;
|
|
|
|
cubefront[1].verts[1][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubefront[1].u[1] = 0.0;
|
|
|
|
cubefront[1].v[1] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubefront[1].verts[2][0] = 1.0f;
|
|
|
|
cubefront[1].verts[2][1] = 1.0f;
|
|
|
|
cubefront[1].verts[2][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubefront[1].u[2] = uv_ratio;
|
|
|
|
cubefront[1].v[2] = 0.0;
|
|
|
|
|
|
|
|
nfacesfront = 2;
|
|
|
|
|
|
|
|
// Left Face - 2 triangles
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].verts[0][0] =-1.0f;
|
|
|
|
cubeleft[0].verts[0][1] = 1.0f;
|
|
|
|
cubeleft[0].verts[0][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[0].u[0] = uv_ratio;
|
|
|
|
cubeleft[0].v[0] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].verts[1][0] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[0].verts[1][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].verts[1][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[0].u[1] = uv_base;
|
|
|
|
cubeleft[0].v[1] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].verts[2][0] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[0].verts[2][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].verts[2][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[0].u[2] = uv_base;
|
|
|
|
cubeleft[0].v[2] = 0.0;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].verts[0][0] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[1].verts[0][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].verts[0][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[1].u[0] = uv_base;
|
|
|
|
cubeleft[1].v[0] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].verts[1][0] =-1.0f;
|
|
|
|
cubeleft[1].verts[1][1] = 1.0f;
|
|
|
|
cubeleft[1].verts[1][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[1].u[1] = uv_ratio;
|
|
|
|
cubeleft[1].v[1] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].verts[2][0] =-1.0f;
|
|
|
|
cubeleft[1].verts[2][1] = 1.0f;
|
|
|
|
cubeleft[1].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[1].u[2] = uv_ratio;
|
|
|
|
cubeleft[1].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
nfacesleft = 2;
|
|
|
|
|
|
|
|
// right Face - 2 triangles
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].verts[0][0] = 1.0f;
|
|
|
|
cuberight[0].verts[0][1] = 1.0f;
|
|
|
|
cuberight[0].verts[0][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[0].u[0] = 0.0;
|
|
|
|
cuberight[0].v[0] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].verts[1][0] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[0].verts[1][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].verts[1][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[0].u[1] = uv_height;
|
|
|
|
cuberight[0].v[1] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].verts[2][0] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[0].verts[2][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[0].u[2] = uv_height;
|
|
|
|
cuberight[0].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[1].verts[0][0] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[1].verts[0][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[1].verts[0][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[1].u[0] = uv_height;
|
|
|
|
cuberight[1].v[0] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[1].verts[1][0] = 1.0f;
|
|
|
|
cuberight[1].verts[1][1] = 1.0f;
|
|
|
|
cuberight[1].verts[1][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[1].u[1] = 0.0;
|
|
|
|
cuberight[1].v[1] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[1].verts[2][0] = 1.0f;
|
|
|
|
cuberight[1].verts[2][1] = 1.0f;
|
|
|
|
cuberight[1].verts[2][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[1].u[2] = 0.0;
|
|
|
|
cuberight[1].v[2] = 0.0;
|
|
|
|
|
|
|
|
nfacesright = 2;
|
|
|
|
|
|
|
|
// top Face - 2 triangles
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[0][0] =-1.0f;
|
|
|
|
cubetop[0].verts[0][1] = 1.0f;
|
|
|
|
cubetop[0].verts[0][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].u[0] = 0.0;
|
|
|
|
cubetop[0].v[0] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[1][0] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].verts[1][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[1][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].u[1] = uv_ratio;
|
|
|
|
cubetop[0].v[1] = uv_height;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[2][0] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].verts[2][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].u[2] = 0.0;
|
|
|
|
cubetop[0].v[2] = uv_height;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[1].verts[0][0] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[1].verts[0][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[1].verts[0][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[1].u[0] = uv_ratio;
|
|
|
|
cubetop[1].v[0] = uv_height;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[1].verts[1][0] =-1.0f;
|
|
|
|
cubetop[1].verts[1][1] = 1.0f;
|
|
|
|
cubetop[1].verts[1][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[1].u[1] = 0.0;
|
|
|
|
cubetop[1].v[1] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[1].verts[2][0] = 1.0f;
|
|
|
|
cubetop[1].verts[2][1] = 1.0f;
|
|
|
|
cubetop[1].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[1].u[2] = uv_ratio;
|
|
|
|
cubetop[1].v[2] = 0.0;
|
|
|
|
|
|
|
|
nfacestop = 2;
|
|
|
|
|
|
|
|
// bottom Face - 2 triangles
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[0][0] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].verts[0][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[0][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].u[0] = 0.0;
|
|
|
|
cubebottom[0].v[0] = uv_base;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[1][0] = 1.0f;
|
|
|
|
cubebottom[0].verts[1][1] = 1.0f;
|
|
|
|
cubebottom[0].verts[1][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].u[1] = uv_ratio;
|
|
|
|
cubebottom[0].v[1] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[2][0] =-1.0f;
|
|
|
|
cubebottom[0].verts[2][1] = 1.0f;
|
|
|
|
cubebottom[0].verts[2][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].u[2] = 0.0;
|
|
|
|
cubebottom[0].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[1].verts[0][0] = 1.0f;
|
|
|
|
cubebottom[1].verts[0][1] = 1.0f;
|
|
|
|
cubebottom[1].verts[0][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[1].u[0] = uv_ratio;
|
|
|
|
cubebottom[1].v[0] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[1].verts[1][0] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[1].verts[1][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[1].verts[1][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[1].u[1] = 0.0;
|
|
|
|
cubebottom[1].v[1] = uv_base;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[1].verts[2][0] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[1].verts[2][1] =-verts_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[1].verts[2][2] =-1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[1].u[2] = uv_ratio;
|
|
|
|
cubebottom[1].v[2] = uv_base;
|
|
|
|
|
|
|
|
nfacesbottom = 2;
|
|
|
|
|
|
|
|
//Refine a triangular mesh by bisecting each edge forms 3 new triangles for each existing triangle on each iteration
|
|
|
|
//It could be made more efficient for drawing if the triangles were ordered in a strip!
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
for (i=0;i<m_resolution;i++) {
|
2009-04-08 15:06:20 +00:00
|
|
|
cubefront.resize(4*nfacesfront);
|
|
|
|
SplitFace(cubefront,&nfacesfront);
|
|
|
|
cubetop.resize(4*nfacestop);
|
|
|
|
SplitFace(cubetop,&nfacestop);
|
|
|
|
cubebottom.resize(4*nfacesbottom);
|
2012-09-16 04:58:18 +00:00
|
|
|
SplitFace(cubebottom,&nfacesbottom);
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft.resize(4*nfacesleft);
|
|
|
|
SplitFace(cubeleft,&nfacesleft);
|
|
|
|
cuberight.resize(4*nfacesright);
|
|
|
|
SplitFace(cuberight,&nfacesright);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Turn into a hemisphere/sphere
|
2012-03-28 05:03:24 +00:00
|
|
|
for (j=0;j<3;j++) {
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesfront;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubefront[i].verts[j].normalize();
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacestop;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[i].verts[j].normalize();
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesbottom;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[i].verts[j].normalize();
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesleft;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[i].verts[j].normalize();
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesright;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[i].verts[j].normalize();
|
|
|
|
}
|
|
|
|
|
|
|
|
//flatten onto xz plane
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesfront;i++)
|
2012-09-16 04:58:18 +00:00
|
|
|
FlattenDome(cubefront[i].verts);
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacestop;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenDome(cubetop[i].verts);
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesbottom;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenDome(cubebottom[i].verts);
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesleft;i++)
|
2012-09-16 04:58:18 +00:00
|
|
|
FlattenDome(cubeleft[i].verts);
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesright;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenDome(cuberight[i].verts);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::CreateMeshPanorama(void)
|
|
|
|
{
|
2012-03-09 18:28:30 +00:00
|
|
|
/*
|
|
|
|
* 1)- Define the faces of a cube without the top and bottom faces
|
|
|
|
* - each face is made out of 2 triangles
|
|
|
|
* 2) Subdivide the faces
|
|
|
|
* - more resolution == more curved lines
|
|
|
|
* 3) Spherize the cube
|
|
|
|
* - normalize the verts t
|
|
|
|
* 4) Flatten onto xz plane
|
|
|
|
* - use spherical projection techniques to transform the sphere onto a flat panorama
|
|
|
|
*/
|
2009-04-08 15:06:20 +00:00
|
|
|
int i,j;
|
|
|
|
|
|
|
|
float uv_ratio = (float)(m_buffersize-1) / m_imagesize;
|
|
|
|
|
|
|
|
/* Top face - two triangles */
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[0][0] = (float)(-M_SQRT2);
|
|
|
|
cubetop[0].verts[0][1] = 0.0f;
|
|
|
|
cubetop[0].verts[0][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].u[0] = 0.0;
|
|
|
|
cubetop[0].v[0] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[1][0] = 0.0f;
|
|
|
|
cubetop[0].verts[1][1] = (float)M_SQRT2;
|
|
|
|
cubetop[0].verts[1][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].u[1] = 0.0;
|
|
|
|
cubetop[0].v[1] = 0.0;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[0].verts[2][0] = (float)M_SQRT2;
|
|
|
|
cubetop[0].verts[2][1] = 0.0f;
|
|
|
|
cubetop[0].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[0].u[2] = uv_ratio;
|
|
|
|
cubetop[0].v[2] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[1].verts[0][0] = (float)M_SQRT2;
|
|
|
|
cubetop[1].verts[0][1] = 0.0f;
|
|
|
|
cubetop[1].verts[0][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[1].u[0] = uv_ratio;
|
|
|
|
cubetop[1].v[0] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[1].verts[1][0] = 0.0f;
|
|
|
|
cubetop[1].verts[1][1] = (float)(-M_SQRT2);
|
|
|
|
cubetop[1].verts[1][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[1].u[1] = uv_ratio;
|
|
|
|
cubetop[1].v[1] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubetop[1].verts[2][0] = (float)(-M_SQRT2);
|
|
|
|
cubetop[1].verts[2][1] = 0.0f;
|
|
|
|
cubetop[1].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[1].u[2] = 0.0;
|
|
|
|
cubetop[1].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
nfacestop = 2;
|
|
|
|
|
|
|
|
/* Bottom face - two triangles */
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[0][0] = (float)(-M_SQRT2);
|
|
|
|
cubebottom[0].verts[0][1] = 0.0f;
|
|
|
|
cubebottom[0].verts[0][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].u[0] = uv_ratio;
|
|
|
|
cubebottom[0].v[0] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[1][0] = (float)M_SQRT2;
|
|
|
|
cubebottom[0].verts[1][1] = 0.0f;
|
|
|
|
cubebottom[0].verts[1][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].u[1] = 0.0;
|
|
|
|
cubebottom[0].v[1] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[0].verts[2][0] = 0.0f;
|
|
|
|
cubebottom[0].verts[2][1] = (float)M_SQRT2;
|
|
|
|
cubebottom[0].verts[2][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[0].u[2] = 0.0;
|
|
|
|
cubebottom[0].v[2] = 0.0;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[1].verts[0][0] = (float)M_SQRT2;
|
|
|
|
cubebottom[1].verts[0][1] = 0.0f;
|
|
|
|
cubebottom[1].verts[0][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[1].u[0] = 0.0;
|
|
|
|
cubebottom[1].v[0] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[1].verts[1][0] = (float)(-M_SQRT2);
|
|
|
|
cubebottom[1].verts[1][1] = 0.0f;
|
|
|
|
cubebottom[1].verts[1][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[1].u[1] = uv_ratio;
|
|
|
|
cubebottom[1].v[1] = 0.0;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubebottom[1].verts[2][0] = 0.0f;
|
|
|
|
cubebottom[1].verts[2][1] = (float)(-M_SQRT2);
|
|
|
|
cubebottom[1].verts[2][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[1].u[2] = uv_ratio;
|
|
|
|
cubebottom[1].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
nfacesbottom = 2;
|
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
/* Left Back (135deg) face - two triangles */
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleftback[0].verts[0][0] = 0.0f;
|
|
|
|
cubeleftback[0].verts[0][1] = (float)(-M_SQRT2);
|
|
|
|
cubeleftback[0].verts[0][2] = -1.0f;
|
|
|
|
cubeleftback[0].u[0] = 0.0;
|
|
|
|
cubeleftback[0].v[0] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleftback[0].verts[1][0] = (float)(-M_SQRT2);
|
|
|
|
cubeleftback[0].verts[1][1] = 0.0f;
|
|
|
|
cubeleftback[0].verts[1][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleftback[0].u[1] = uv_ratio;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleftback[0].v[1] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleftback[0].verts[2][0] = 0.0f;
|
|
|
|
cubeleftback[0].verts[2][1] = (float)(-M_SQRT2);
|
|
|
|
cubeleftback[0].verts[2][2] = 1.0f;
|
|
|
|
cubeleftback[0].u[2] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleftback[0].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleftback[1].verts[0][0] = 0.0f;
|
|
|
|
cubeleftback[1].verts[0][1] = (float)(-M_SQRT2);
|
|
|
|
cubeleftback[1].verts[0][2] = 1.0f;
|
|
|
|
cubeleftback[1].u[0] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleftback[1].v[0] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleftback[1].verts[1][0] = (float)(-M_SQRT2);
|
|
|
|
cubeleftback[1].verts[1][1] = 0.0f;
|
|
|
|
cubeleftback[1].verts[1][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleftback[1].u[1] = uv_ratio;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleftback[1].v[1] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleftback[1].verts[2][0] = (float)(-M_SQRT2);
|
|
|
|
cubeleftback[1].verts[2][1] = 0.0f;
|
|
|
|
cubeleftback[1].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleftback[1].u[2] = uv_ratio;
|
|
|
|
cubeleftback[1].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
nfacesleftback = 2;
|
|
|
|
|
|
|
|
/* Left face - two triangles */
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].verts[0][0] = (float)(-M_SQRT2);
|
|
|
|
cubeleft[0].verts[0][1] = 0.0f;
|
|
|
|
cubeleft[0].verts[0][2] = -1.0f;
|
|
|
|
cubeleft[0].u[0] = 0.0;
|
|
|
|
cubeleft[0].v[0] = 0.0;
|
|
|
|
|
|
|
|
cubeleft[0].verts[1][0] = 0.0f;
|
|
|
|
cubeleft[0].verts[1][1] = (float)M_SQRT2;
|
|
|
|
cubeleft[0].verts[1][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[0].u[1] = uv_ratio;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].v[1] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[0].verts[2][0] = (float)(-M_SQRT2);
|
|
|
|
cubeleft[0].verts[2][1] = 0.0f;
|
|
|
|
cubeleft[0].verts[2][2] = 1.0f;
|
|
|
|
cubeleft[0].u[2] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[0].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].verts[0][0] = (float)(-M_SQRT2);
|
|
|
|
cubeleft[1].verts[0][1] = 0.0f;
|
|
|
|
cubeleft[1].verts[0][2] = 1.0f;
|
|
|
|
cubeleft[1].u[0] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[1].v[0] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].verts[1][0] = 0.0f;
|
|
|
|
cubeleft[1].verts[1][1] = (float)M_SQRT2;
|
|
|
|
cubeleft[1].verts[1][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[1].u[1] = uv_ratio;
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].v[1] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cubeleft[1].verts[2][0] = 0.0f;
|
|
|
|
cubeleft[1].verts[2][1] = (float)M_SQRT2;
|
|
|
|
cubeleft[1].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[1].u[2] = uv_ratio;
|
|
|
|
cubeleft[1].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
nfacesleft = 2;
|
|
|
|
|
|
|
|
/* Right face - two triangles */
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].verts[0][0] = 0.0f;
|
|
|
|
cuberight[0].verts[0][1] = (float)M_SQRT2;
|
|
|
|
cuberight[0].verts[0][2] = -1.0f;
|
|
|
|
cuberight[0].u[0] = 0.0;
|
|
|
|
cuberight[0].v[0] = 0.0;
|
|
|
|
|
|
|
|
cuberight[0].verts[1][0] = (float)M_SQRT2;
|
|
|
|
cuberight[0].verts[1][1] = 0.0f;
|
|
|
|
cuberight[0].verts[1][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[0].u[1] = uv_ratio;
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].v[1] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[0].verts[2][0] = (float)M_SQRT2;
|
|
|
|
cuberight[0].verts[2][1] = 0.0f;
|
|
|
|
cuberight[0].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[0].u[2] = uv_ratio;
|
|
|
|
cuberight[0].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[1].verts[0][0] = 0.0f;
|
|
|
|
cuberight[1].verts[0][1] = (float)M_SQRT2;
|
|
|
|
cuberight[1].verts[0][2] = -1.0f;
|
|
|
|
cuberight[1].u[0] = 0.0;
|
|
|
|
cuberight[1].v[0] = 0.0;
|
|
|
|
|
|
|
|
cuberight[1].verts[1][0] = (float)M_SQRT2;
|
|
|
|
cuberight[1].verts[1][1] = 0.0f;
|
|
|
|
cuberight[1].verts[1][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[1].u[1] = uv_ratio;
|
|
|
|
cuberight[1].v[1] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberight[1].verts[2][0] = 0.0f;
|
|
|
|
cuberight[1].verts[2][1] = (float)M_SQRT2;
|
|
|
|
cuberight[1].verts[2][2] = 1.0f;
|
|
|
|
cuberight[1].u[2] = 0.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[1].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
nfacesright = 2;
|
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
/* Right Back (-135deg) face - two triangles */
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberightback[0].verts[0][0] = (float)M_SQRT2;
|
|
|
|
cuberightback[0].verts[0][1] = 0.0f;
|
|
|
|
cuberightback[0].verts[0][2] = -1.0f;
|
|
|
|
cuberightback[0].u[0] = 0.0;
|
|
|
|
cuberightback[0].v[0] = 0.0;
|
|
|
|
|
|
|
|
cuberightback[0].verts[1][0] = 0.0f;
|
|
|
|
cuberightback[0].verts[1][1] = (float)(-M_SQRT2);
|
|
|
|
cuberightback[0].verts[1][2] = -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberightback[0].u[1] = uv_ratio;
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberightback[0].v[1] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberightback[0].verts[2][0] = 0.0f;
|
|
|
|
cuberightback[0].verts[2][1] = (float)(-M_SQRT2);
|
|
|
|
cuberightback[0].verts[2][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberightback[0].u[2] = uv_ratio;
|
|
|
|
cuberightback[0].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
//second triangle
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberightback[1].verts[0][0] = (float)M_SQRT2;
|
|
|
|
cuberightback[1].verts[0][1] = 0.0f;
|
|
|
|
cuberightback[1].verts[0][2] = -1.0f;
|
|
|
|
cuberightback[1].u[0] = 0.0;
|
|
|
|
cuberightback[1].v[0] = 0.0;
|
|
|
|
|
|
|
|
cuberightback[1].verts[1][0] = 0.0f;
|
|
|
|
cuberightback[1].verts[1][1] = (float)(-M_SQRT2);
|
|
|
|
cuberightback[1].verts[1][2] = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberightback[1].u[1] = uv_ratio;
|
|
|
|
cuberightback[1].v[1] = uv_ratio;
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
cuberightback[1].verts[2][0] = (float)M_SQRT2;
|
|
|
|
cuberightback[1].verts[2][1] = 0.0f;
|
|
|
|
cuberightback[1].verts[2][2] = 1.0f;
|
|
|
|
cuberightback[1].u[2] = 0.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberightback[1].v[2] = uv_ratio;
|
|
|
|
|
|
|
|
nfacesrightback = 2;
|
|
|
|
|
|
|
|
// Subdivide the faces
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<m_resolution;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
{
|
|
|
|
cubetop.resize(4*nfacestop);
|
|
|
|
SplitFace(cubetop,&nfacestop);
|
|
|
|
|
|
|
|
cubebottom.resize(4*nfacesbottom);
|
|
|
|
SplitFace(cubebottom,&nfacesbottom);
|
|
|
|
|
|
|
|
cubeleft.resize(4*nfacesleft);
|
|
|
|
SplitFace(cubeleft,&nfacesleft);
|
|
|
|
|
|
|
|
cuberight.resize(4*nfacesright);
|
|
|
|
SplitFace(cuberight,&nfacesright);
|
|
|
|
|
|
|
|
cubeleftback.resize(4*nfacesleftback);
|
|
|
|
SplitFace(cubeleftback,&nfacesleftback);
|
|
|
|
|
|
|
|
cuberightback.resize(4*nfacesrightback);
|
|
|
|
SplitFace(cuberightback,&nfacesrightback);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Spherize the cube
|
2012-03-24 07:52:14 +00:00
|
|
|
for (j=0;j<3;j++)
|
2009-04-08 15:06:20 +00:00
|
|
|
{
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacestop;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubetop[i].verts[j].normalize();
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesbottom;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubebottom[i].verts[j].normalize();
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesleftback;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleftback[i].verts[j].normalize();
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesleft;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cubeleft[i].verts[j].normalize();
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesright;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberight[i].verts[j].normalize();
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesrightback;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
cuberightback[i].verts[j].normalize();
|
|
|
|
}
|
|
|
|
|
|
|
|
//Flatten onto xz plane
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesleftback;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenPanorama(cubeleftback[i].verts);
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesleft;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenPanorama(cubeleft[i].verts);
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesright;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenPanorama(cuberight[i].verts);
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesrightback;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenPanorama(cuberightback[i].verts);
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacestop;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenPanorama(cubetop[i].verts);
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
for (i=0;i<nfacesbottom;i++)
|
2009-04-08 15:06:20 +00:00
|
|
|
FlattenPanorama(cubebottom[i].verts);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::FlattenDome(MT_Vector3 verts[3])
|
|
|
|
{
|
|
|
|
double phi, r;
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
for (int i=0;i<3;i++) {
|
2009-04-08 15:06:20 +00:00
|
|
|
r = atan2(sqrt(verts[i][0]*verts[i][0] + verts[i][2]*verts[i][2]), verts[i][1]);
|
2012-08-02 21:17:12 +00:00
|
|
|
r /= (double)this->m_radangle / 2.0;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
phi = atan2(verts[i][2], verts[i][0]);
|
|
|
|
|
|
|
|
verts[i][0] = r * cos(phi);
|
2015-12-16 00:31:38 +00:00
|
|
|
verts[i][1] = 0.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
verts[i][2] = r * sin(phi);
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (r > 1.0) {
|
2009-04-08 15:06:20 +00:00
|
|
|
//round the border
|
|
|
|
verts[i][0] = cos(phi);
|
2015-12-16 00:31:38 +00:00
|
|
|
verts[i][1] = -3.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
verts[i][2] = sin(phi);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::FlattenPanorama(MT_Vector3 verts[3])
|
|
|
|
{
|
2010-09-30 07:06:00 +00:00
|
|
|
// it creates a full spherical panoramic (360deg)
|
2009-04-08 15:06:20 +00:00
|
|
|
int i;
|
2012-04-05 22:06:45 +00:00
|
|
|
double phi, theta;
|
2009-04-08 15:06:20 +00:00
|
|
|
bool edge=false;
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
for (i=0;i<3;i++) {
|
2009-04-08 15:06:20 +00:00
|
|
|
phi = atan2(verts[i][1], verts[i][0]);
|
|
|
|
phi *= -1.0; //flipping
|
|
|
|
|
|
|
|
if (phi == -MT_PI) //It's on the edge
|
|
|
|
edge=true;
|
|
|
|
|
|
|
|
verts[i][0] = phi / MT_PI;
|
2015-12-16 00:31:38 +00:00
|
|
|
verts[i][1] = 0.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-04-05 22:06:45 +00:00
|
|
|
theta = asin(verts[i][2]);
|
|
|
|
verts[i][2] = theta / MT_PI;
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
2012-03-28 05:03:24 +00:00
|
|
|
if (edge) {
|
2009-04-08 15:06:20 +00:00
|
|
|
bool right=false;
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
for (i=0;i<3;i++) {
|
2015-12-16 00:31:38 +00:00
|
|
|
if (fmodf(verts[i][0],1.0f) > 0.0f) {
|
2009-04-08 15:06:20 +00:00
|
|
|
right=true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-03-28 05:03:24 +00:00
|
|
|
if (right) {
|
|
|
|
for (i=0;i<3;i++) {
|
2015-12-16 00:31:38 +00:00
|
|
|
if (verts[i][0] < 0.0f)
|
|
|
|
verts[i][0] *= -1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::SplitFace(vector <DomeFace>& face, int *nfaces)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int n1, n2;
|
|
|
|
|
|
|
|
n1 = n2 = *nfaces;
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
for (i=0;i<n1;i++) {
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
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;
|
2012-09-16 04:58:18 +00:00
|
|
|
face[n2+2].v[2] = (face[i].v[2] + face[i].v[0]) /2;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-02-27 10:35:39 +00:00
|
|
|
//face[i].verts[0] = face[i].verts[0];
|
2009-04-08 15:06:20 +00:00
|
|
|
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;
|
2012-02-27 10:35:39 +00:00
|
|
|
//face[i].v[0] = face[i].v[0];
|
2009-04-08 15:06:20 +00:00
|
|
|
face[i].v[1] = (face[i].v[0] + face[i].v[1]) /2;
|
2012-09-16 04:58:18 +00:00
|
|
|
face[i].v[2] = (face[i].v[0] + face[i].v[2]) /2;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
n2 += 3; // number of faces
|
|
|
|
}
|
|
|
|
*nfaces = n2;
|
|
|
|
}
|
|
|
|
|
2013-03-26 07:29:01 +00:00
|
|
|
void KX_Dome::CalculateFrustum(KX_Camera *cam)
|
2009-04-08 15:06:20 +00:00
|
|
|
{
|
2012-03-09 18:28:30 +00:00
|
|
|
#if 0
|
2010-09-30 07:06:00 +00:00
|
|
|
// manually creating a 90deg Field of View Frustum
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-09 18:28:30 +00:00
|
|
|
// the original formula:
|
2015-12-16 00:31:38 +00:00
|
|
|
top = tan(fov*3.14159f/30.0f)) * near [for fov in degrees]
|
|
|
|
fov*0.5f = arctan ((top-bottom)*0.5f / near) [for fov in radians]
|
2009-04-08 15:06:20 +00:00
|
|
|
bottom = -top
|
|
|
|
left = aspect * bottom
|
|
|
|
right = aspect * top
|
|
|
|
|
|
|
|
// the equivalent GLU call is:
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
2015-12-16 00:31:38 +00:00
|
|
|
gluPerspective(90.0f,1.0f,cam->GetCameraNear(),cam->GetCameraFar());
|
2012-03-09 18:28:30 +00:00
|
|
|
#endif
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2016-01-28 06:35:50 +00:00
|
|
|
RAS_FrameFrustum m_frustum; //90 deg. Frustum
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2016-01-28 06:35:50 +00:00
|
|
|
m_frustum.camnear = cam->GetCameraNear();
|
|
|
|
m_frustum.camfar = cam->GetCameraFar();
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2016-01-28 06:35:50 +00:00
|
|
|
// float top = tan(90.0f*MT_PI/360.0f) * m_frustum.camnear;
|
|
|
|
float top = m_frustum.camnear; // for deg = 90deg, tan = 1
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2016-01-28 06:35:50 +00:00
|
|
|
m_frustum.x1 = -top;
|
|
|
|
m_frustum.x2 = top;
|
|
|
|
m_frustum.y1 = -top;
|
|
|
|
m_frustum.y2 = top;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
m_projmat = m_rasterizer->GetFrustumMatrix(
|
2016-01-28 06:35:50 +00:00
|
|
|
m_frustum.x1, m_frustum.x2, m_frustum.y1, m_frustum.y2, m_frustum.camnear, m_frustum.camfar);
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::CalculateCameraOrientation()
|
|
|
|
{
|
|
|
|
/*
|
2012-03-09 18:28:30 +00:00
|
|
|
* Uses 4 cameras for angles up to 180deg
|
|
|
|
* Uses 5 cameras for angles up to 250deg
|
|
|
|
* Uses 6 cameras for angles up to 360deg
|
|
|
|
*/
|
2009-05-17 20:37:13 +00:00
|
|
|
int i;
|
2015-12-16 00:52:30 +00:00
|
|
|
float deg45 = MT_PI / 4.0f;
|
|
|
|
MT_Scalar c = cosf(deg45);
|
|
|
|
MT_Scalar s = sinf(deg45);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2009-05-09 21:04:03 +00:00
|
|
|
if (m_angle <= 180 && (m_mode == DOME_FISHEYE
|
2009-05-17 20:37:13 +00:00
|
|
|
|| m_mode == DOME_TRUNCATED_FRONT
|
2012-03-28 05:03:24 +00:00
|
|
|
|| m_mode == DOME_TRUNCATED_REAR)) {
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[0] = MT_Matrix3x3( // 90deg - Top
|
2015-12-16 00:31:38 +00:00
|
|
|
c, -s, 0.0f,
|
|
|
|
0.0f,0.0f, -1.0f,
|
|
|
|
s, c, 0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[1] = MT_Matrix3x3( // 90deg - Bottom
|
2015-12-16 00:31:38 +00:00
|
|
|
-s, c, 0.0f,
|
|
|
|
0.0f,0.0f, 1.0f,
|
|
|
|
s, c, 0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[2] = MT_Matrix3x3( // 45deg - Left
|
2015-12-16 00:31:38 +00:00
|
|
|
c, 0.0f, s,
|
|
|
|
0, 1.0f, 0.0f,
|
|
|
|
-s, 0.0f, c);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[3] = MT_Matrix3x3( // 45deg - Right
|
2015-12-16 00:31:38 +00:00
|
|
|
c, 0.0f, -s,
|
|
|
|
0.0f, 1.0f, 0.0f,
|
|
|
|
s, 0.0f, c);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2009-05-09 21:04:03 +00:00
|
|
|
} else if (m_mode == DOME_ENVMAP || (m_angle > 180 && (m_mode == DOME_FISHEYE
|
2009-05-17 20:37:13 +00:00
|
|
|
|| m_mode == DOME_TRUNCATED_FRONT
|
2012-03-28 05:03:24 +00:00
|
|
|
|| m_mode == DOME_TRUNCATED_REAR))) {
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[0] = MT_Matrix3x3( // 90deg - Top
|
2015-12-16 00:31:38 +00:00
|
|
|
1.0f, 0.0f, 0.0f,
|
|
|
|
0.0f, 0.0f,-1.0f,
|
|
|
|
0.0f, 1.0f, 0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[1] = MT_Matrix3x3( // 90deg - Bottom
|
2015-12-16 00:31:38 +00:00
|
|
|
1.0f, 0.0f, 0.0f,
|
|
|
|
0.0f, 0.0f, 1.0f,
|
|
|
|
0.0f,-1.0f, 0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[2] = MT_Matrix3x3( // -90deg - Left
|
2015-12-16 00:31:38 +00:00
|
|
|
0.0f, 0.0f, 1.0f,
|
|
|
|
0.0f, 1.0f, 0.0f,
|
|
|
|
-1.0f, 0.0f, 0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[3] = MT_Matrix3x3( // 90deg - Right
|
2015-12-16 00:31:38 +00:00
|
|
|
0.0f, 0.0f,-1.0f,
|
|
|
|
0.0f, 1.0f, 0.0f,
|
|
|
|
1.0f, 0.0f, 0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[4] = MT_Matrix3x3( // 0deg - Front
|
2015-12-16 00:31:38 +00:00
|
|
|
1.0f, 0.0f, 0.0f,
|
|
|
|
0.0f, 1.0f, 0.0f,
|
|
|
|
0.0f, 0.0f, 1.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[5] = MT_Matrix3x3( // 180deg - Back - USED for ENVMAP only
|
2015-12-16 00:31:38 +00:00
|
|
|
-1.0f, 0.0f, 0.0f,
|
|
|
|
0.0f, 1.0f, 0.0f,
|
|
|
|
0.0f, 0.0f,-1.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
} else if (m_mode == DOME_PANORAM_SPH) {
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
m_locRot[0] = MT_Matrix3x3( // Top
|
2015-12-16 00:31:38 +00:00
|
|
|
c, s, 0.0f,
|
|
|
|
0.0f,0.0f, -1.0f,
|
|
|
|
-s, c, 0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
m_locRot[1] = MT_Matrix3x3( // Bottom
|
2015-12-16 00:31:38 +00:00
|
|
|
c, s, 0.0f,
|
|
|
|
0.0f, 0.0f, 1.0f,
|
|
|
|
s, -c, 0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[2] = MT_Matrix3x3( // 45deg - Left
|
2015-12-16 00:31:38 +00:00
|
|
|
-s, 0.0f, c,
|
|
|
|
0, 1.0f, 0.0f,
|
|
|
|
-c, 0.0f, -s);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[3] = MT_Matrix3x3( // 45deg - Right
|
2015-12-16 00:31:38 +00:00
|
|
|
c, 0.0f, s,
|
|
|
|
0, 1.0f, 0.0f,
|
|
|
|
-s, 0.0f, c);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[4] = MT_Matrix3x3( // 135deg - LeftBack
|
2015-12-16 00:31:38 +00:00
|
|
|
-s, 0.0f, -c,
|
|
|
|
0.0f, 1.0f, 0.0f,
|
|
|
|
c, 0.0f, -s);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
m_locRot[5] = MT_Matrix3x3( // 135deg - RightBack
|
2015-12-16 00:31:38 +00:00
|
|
|
c, 0.0f, -s,
|
|
|
|
0.0f, 1.0f, 0.0f,
|
|
|
|
s, 0.0f, c);
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
2009-05-17 20:37:13 +00:00
|
|
|
|
|
|
|
// rotating the camera in horizontal axis
|
|
|
|
if (m_tilt)
|
|
|
|
{
|
|
|
|
float tiltdeg = ((m_tilt % 360) * 2 * MT_PI) / 360;
|
2015-12-16 00:52:30 +00:00
|
|
|
c = cosf(tiltdeg);
|
|
|
|
s = sinf(tiltdeg);
|
2009-05-17 20:37:13 +00:00
|
|
|
|
|
|
|
MT_Matrix3x3 tilt_mat = MT_Matrix3x3(
|
2015-12-16 00:31:38 +00:00
|
|
|
1.0f, 0.0f, 0.0f,
|
|
|
|
0.0f, c, -s,
|
|
|
|
0.0f, s, c
|
2009-05-17 20:37:13 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
for (i =0;i<6;i++)
|
|
|
|
m_locRot[i] = tilt_mat * m_locRot[i];
|
|
|
|
}
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::RotateCamera(KX_Camera* cam, int i)
|
|
|
|
{
|
|
|
|
// I'm not using it, I'm doing inline calls for these commands
|
|
|
|
// but it's nice to have it here in case I need it
|
|
|
|
|
|
|
|
MT_Matrix3x3 camori = cam->GetSGNode()->GetLocalOrientation();
|
|
|
|
|
|
|
|
cam->NodeSetLocalOrientation(camori*m_locRot[i]);
|
|
|
|
cam->NodeUpdateGS(0.f);
|
|
|
|
|
|
|
|
MT_Transform camtrans(cam->GetWorldToCamera());
|
|
|
|
MT_Matrix4x4 viewmat(camtrans);
|
BGE: Various render improvements.
bge.logic.setRender(flag) to enable/disable render.
The render pass is enabled by default but it can be disabled with
bge.logic.setRender(False).
Once disabled, the render pass is skipped and a new logic frame starts
immediately. Note that VSync no longer limits the fps when render is off
but the 'Use Frame Rate' option in the Render Properties still does.
To run as many frames as possible, untick the option
This function is useful when you don't need the default render, e.g.
when doing offscreen render to an alternate device than the monitor.
Note that without VSync, you must limit the frame rate by other means.
fbo = bge.render.offScreenCreate(width,height,[,samples=0][,target=bge.render.RAS_OFS_RENDER_BUFFER])
Use this method to create an offscreen buffer of given size, with given MSAA
samples and targetting either a render buffer (bge.render.RAS_OFS_RENDER_BUFFER)
or a texture (bge.render.RAS_OFS_RENDER_TEXTURE). Use the former if you want to
retrieve the frame buffer on the host and the latter if you want to pass the render
to another context (texture are proper OGL object, render buffers aren't)
The object created by this function can only be used as a parameter of the
bge.texture.ImageRender() constructor to send the the render to the FBO rather
than to the frame buffer. This is best suited when you want to create a render
of specific size, or if you need an image with an alpha channel.
bge.texture.<imagetype>.refresh(buffer=None, format="RGBA", ts=-1.0)
Without arg, the refresh method of the image objects is pretty much a no-op, it
simply invalidates the image so that on next texture refresh, the image will
be recalculated.
It is now possible to pass an optional buffer object to transfer the image (and
recalculate it if it was invalid) to an external object. The object must implement
the 'buffer protocol'. The image will be transfered as "RGBA" or "BGRA" pixels
depending on format argument (only those 2 formats are supported) and ts is an
optional timestamp in the image depends on it (e.g. VideoFFmpeg playing a video file).
With this function you don't need anymore to link the image object to a Texture
object to use: the image object is self-sufficient.
bge.texture.ImageRender(scene, camera, fbo=None)
Render to buffer is possible by passing a FBO object (see offScreenCreate).
bge.texture.ImageRender.render()
Allows asynchronous render: call this method to render the scene but without
extracting the pixels yet. The function returns as soon as the render commands
have been send to the GPU. The render will proceed asynchronously in the GPU
while the host can perform other tasks.
To complete the render, you can either call refresh() directly of refresh the texture
to which this object is the source. Asynchronous render is useful to achieve optimal
performance: call render() on frame N and refresh() on frame N+1 to give as much as
time as possible to the GPU to render the frame while the game engine can perform other tasks.
Support negative scale on camera.
Camera scale was previously ignored in the BGE.
It is now injected in the modelview matrix as a vertical or horizontal flip
of the scene (respectively if scaleY<0 and scaleX<0).
Note that the actual value of the scale is not used, only the sign.
This allows to flip the image produced by ImageRender() without any performance
degradation: the flip is integrated in the render itself.
Optimized image transfer from ImageRender to buffer.
Previously, images that were transferred to the host were always going through
buffers in VideoTexture. It is now possible to transfer ImageRender
images to external buffer without intermediate copy (i.e. directly from OGL to buffer)
if the attributes of the ImageRender objects are set as follow:
flip=False, alpha=True, scale=False, depth=False, zbuff=False.
(if you need to flip the image, use camera negative scale)
2016-06-09 21:56:45 +00:00
|
|
|
m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->NodeGetLocalScaling(), cam->GetCameraData()->m_perspective);
|
2009-04-08 15:06:20 +00:00
|
|
|
cam->SetModelviewMatrix(viewmat);
|
|
|
|
|
|
|
|
// restore the original orientation
|
|
|
|
cam->NodeSetLocalOrientation(camori);
|
|
|
|
cam->NodeUpdateGS(0.f);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::Draw(void)
|
|
|
|
{
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (fboSupported) {
|
2009-05-07 20:00:09 +00:00
|
|
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, warp.fboId);
|
|
|
|
|
|
|
|
glViewport(0,0,warp.imagesize, warp.imagesize);
|
|
|
|
glScissor(0,0,warp.imagesize, warp.imagesize);
|
|
|
|
}
|
|
|
|
|
2012-10-21 07:58:38 +00:00
|
|
|
switch (m_mode) {
|
2009-04-08 15:06:20 +00:00
|
|
|
case DOME_FISHEYE:
|
|
|
|
DrawDomeFisheye();
|
|
|
|
break;
|
2009-04-23 02:27:11 +00:00
|
|
|
case DOME_ENVMAP:
|
|
|
|
DrawEnvMap();
|
2009-04-08 15:06:20 +00:00
|
|
|
break;
|
|
|
|
case DOME_PANORAM_SPH:
|
|
|
|
DrawPanorama();
|
|
|
|
break;
|
2009-05-17 20:37:13 +00:00
|
|
|
case DOME_TRUNCATED_FRONT:
|
2009-05-08 18:59:08 +00:00
|
|
|
DrawDomeFisheye();
|
|
|
|
break;
|
2009-05-17 20:37:13 +00:00
|
|
|
case DOME_TRUNCATED_REAR:
|
2009-05-08 18:59:08 +00:00
|
|
|
DrawDomeFisheye();
|
|
|
|
break;
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
if (warp.usemesh)
|
2009-04-08 15:06:20 +00:00
|
|
|
{
|
2012-03-24 07:52:14 +00:00
|
|
|
if (fboSupported)
|
2009-05-07 20:00:09 +00:00
|
|
|
{
|
|
|
|
m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight());
|
|
|
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]);
|
|
|
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_viewport.GetLeft(), m_viewport.GetBottom(), warp.bufferwidth, warp.bufferheight);
|
|
|
|
}
|
2009-04-08 15:06:20 +00:00
|
|
|
DrawDomeWarped();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-23 02:27:11 +00:00
|
|
|
void KX_Dome::DrawEnvMap(void)
|
2009-04-08 15:06:20 +00:00
|
|
|
{
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
// Making the viewport always square
|
|
|
|
|
|
|
|
int can_width = m_viewport.GetRight();
|
|
|
|
int can_height = m_viewport.GetTop();
|
|
|
|
|
|
|
|
float ortho_width, ortho_height;
|
|
|
|
|
|
|
|
if (warp.usemesh)
|
2015-12-16 00:31:38 +00:00
|
|
|
glOrtho((-1.0), 1.0, (-0.66), 0.66, 0.0, 0.0); //stretch the image to reduce resolution lost
|
2009-04-23 02:27:11 +00:00
|
|
|
|
|
|
|
else {
|
2012-03-28 05:03:24 +00:00
|
|
|
if (can_width/3 <= can_height/2) {
|
2015-12-16 00:31:38 +00:00
|
|
|
ortho_width = 1.0f;
|
2009-04-23 02:27:11 +00:00
|
|
|
ortho_height = (float)can_height/can_width;
|
2012-06-06 22:38:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-04-23 02:27:11 +00:00
|
|
|
ortho_height = 2.0f / 3;
|
|
|
|
ortho_width = (float)can_width/can_height * ortho_height;
|
|
|
|
}
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0f, 10.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
2015-12-16 00:31:38 +00:00
|
|
|
gluLookAt(0.0f,0.0f,1.0f, 0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
|
|
|
|
glPolygonMode(GL_FRONT, GL_FILL);
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
2015-12-16 00:31:38 +00:00
|
|
|
glColor3f(1.0f,1.0f,1.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
|
|
|
|
float uv_ratio = (float)(m_buffersize-1) / m_imagesize;
|
|
|
|
double onebythree = 1.0f / 3;
|
|
|
|
|
|
|
|
// domefacesId[0] => (top)
|
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[0]);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2f(uv_ratio,uv_ratio);
|
|
|
|
glVertex3f( onebythree, 0.0f, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,uv_ratio);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(-onebythree, 0.0f, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(-onebythree,-2 * onebythree, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(uv_ratio,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(onebythree,-2 * onebythree, 3.0f);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
// domefacesId[1] => (bottom)
|
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[1]);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2f(uv_ratio,uv_ratio);
|
|
|
|
glVertex3f(-onebythree, 0.0f, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,uv_ratio);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(-1.0f, 0.0f, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(-1.0f,-2 * onebythree, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(uv_ratio,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(-onebythree,-2 * onebythree, 3.0f);
|
|
|
|
glEnd();
|
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
// domefacesId[2] => -90deg (left)
|
2009-04-23 02:27:11 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[2]);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2f(uv_ratio,uv_ratio);
|
|
|
|
glVertex3f(-onebythree, 2 * onebythree, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,uv_ratio);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(-1.0f, 2 * onebythree, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(-1.0f, 0.0f, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(uv_ratio,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(-onebythree, 0.0f, 3.0f);
|
|
|
|
glEnd();
|
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
// domefacesId[3] => 90deg (right)
|
2009-04-23 02:27:11 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[3]);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2f(uv_ratio,uv_ratio);
|
|
|
|
glVertex3f( 1.0f, 2 * onebythree, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,uv_ratio);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f( onebythree, 2 * onebythree, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f( onebythree, 0.0f, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(uv_ratio,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(1.0f, 0.0f, 3.0f);
|
|
|
|
glEnd();
|
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
// domefacesId[4] => 0deg (front)
|
2009-04-23 02:27:11 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[4]);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2f(uv_ratio,uv_ratio);
|
|
|
|
glVertex3f( 1.0f, 0.0f, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,uv_ratio);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f( onebythree, 0.0f, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f( onebythree,-2 * onebythree, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(uv_ratio,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(1.0f, -2 * onebythree, 3.0f);
|
|
|
|
glEnd();
|
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
// domefacesId[5] => 180deg (back)
|
2009-04-23 02:27:11 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[5]);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2f(uv_ratio,uv_ratio);
|
|
|
|
glVertex3f( onebythree, 2 * onebythree, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,uv_ratio);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(-onebythree, 2 * onebythree, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(0.0f,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(-onebythree, 0.0f, 3.0f);
|
2015-12-16 00:31:38 +00:00
|
|
|
glTexCoord2f(uv_ratio,0.0f);
|
2009-04-23 02:27:11 +00:00
|
|
|
glVertex3f(onebythree, 0.0f, 3.0f);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::DrawDomeFisheye(void)
|
|
|
|
{
|
2009-04-23 13:30:34 +00:00
|
|
|
int i;
|
2009-04-23 02:27:11 +00:00
|
|
|
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
// Making the viewport always square
|
|
|
|
|
|
|
|
int can_width = m_viewport.GetRight();
|
|
|
|
int can_height = m_viewport.GetTop();
|
|
|
|
|
|
|
|
float ortho_width, ortho_height;
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
if (m_mode == DOME_FISHEYE) {
|
2009-05-08 18:59:08 +00:00
|
|
|
if (warp.usemesh)
|
2015-12-16 00:31:38 +00:00
|
|
|
glOrtho((-1.0f), 1.0f, (-1.0f), 1.0f, -20.0f, 10.0f); //stretch the image to reduce resolution lost
|
2009-05-08 18:59:08 +00:00
|
|
|
|
|
|
|
else {
|
2012-03-28 05:03:24 +00:00
|
|
|
if (can_width < can_height) {
|
2015-12-16 00:31:38 +00:00
|
|
|
ortho_width = 1.0f;
|
2009-05-08 18:59:08 +00:00
|
|
|
ortho_height = (float)can_height/can_width;
|
2012-06-06 22:38:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-05-08 18:59:08 +00:00
|
|
|
ortho_width = (float)can_width/can_height;
|
2015-12-16 00:31:38 +00:00
|
|
|
ortho_height = 1.0f;
|
2009-05-08 18:59:08 +00:00
|
|
|
}
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0f, 10.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
2009-05-08 18:59:08 +00:00
|
|
|
}
|
2012-03-24 07:52:14 +00:00
|
|
|
else if (m_mode == DOME_TRUNCATED_FRONT)
|
2009-05-08 18:59:08 +00:00
|
|
|
{
|
2015-12-16 00:31:38 +00:00
|
|
|
ortho_width = 1.0f;
|
2012-08-02 21:17:12 +00:00
|
|
|
ortho_height = 2.0f * ((float)can_height / can_width) - 1.0f;
|
2009-05-08 18:59:08 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_width, -20.0f, 10.0f);
|
2009-05-08 18:59:08 +00:00
|
|
|
}
|
2009-05-17 20:37:13 +00:00
|
|
|
else { //m_mode == DOME_TRUNCATED_REAR
|
2015-12-16 00:31:38 +00:00
|
|
|
ortho_width = 1.0f;
|
2012-08-02 21:17:12 +00:00
|
|
|
ortho_height = 2.0f * ((float)can_height / can_width) - 1.0f;
|
2009-05-08 18:59:08 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
glOrtho((-ortho_width), ortho_width, (-ortho_width), ortho_height, -20.0f, 10.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
2015-12-16 00:31:38 +00:00
|
|
|
gluLookAt(0.0f,-1.0f,0.0f, 0.0f,0.0f,0.0f, 0.0f,0.0f,1.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
if (m_drawingmode == RAS_IRasterizer::KX_WIREFRAME)
|
2009-04-08 15:06:20 +00:00
|
|
|
glPolygonMode(GL_FRONT, GL_LINE);
|
|
|
|
else
|
|
|
|
glPolygonMode(GL_FRONT, GL_FILL);
|
|
|
|
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
2015-12-16 00:31:38 +00:00
|
|
|
glColor3f(1.0f,1.0f,1.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (dlistSupported) {
|
|
|
|
for (i=0;i<m_numfaces;i++) {
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[i]);
|
|
|
|
glCallList(dlistId+i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else { // DisplayLists not supported
|
|
|
|
// top triangle
|
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[0]);
|
|
|
|
GLDrawTriangles(cubetop, nfacestop);
|
|
|
|
|
2012-09-16 04:58:18 +00:00
|
|
|
// bottom triangle
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[1]);
|
|
|
|
GLDrawTriangles(cubebottom, nfacesbottom);
|
|
|
|
|
|
|
|
// left triangle
|
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[2]);
|
|
|
|
GLDrawTriangles(cubeleft, nfacesleft);
|
|
|
|
|
|
|
|
// right triangle
|
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[3]);
|
|
|
|
GLDrawTriangles(cuberight, nfacesright);
|
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (m_angle > 180) {
|
2009-04-08 15:06:20 +00:00
|
|
|
// front triangle
|
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[4]);
|
|
|
|
GLDrawTriangles(cubefront, nfacesfront);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::DrawPanorama(void)
|
|
|
|
{
|
2009-04-23 13:30:34 +00:00
|
|
|
int i;
|
2009-04-08 15:06:20 +00:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
// Making the viewport always square
|
|
|
|
|
|
|
|
int can_width = m_viewport.GetRight();
|
|
|
|
int can_height = m_viewport.GetTop();
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
float ortho_height = 1.0f;
|
|
|
|
float ortho_width = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
if (warp.usemesh)
|
2015-12-16 00:31:38 +00:00
|
|
|
glOrtho((-1.0f), 1.0f, (-0.5f), 0.5f, -20.0f, 10.0f); //stretch the image to reduce resolution lost
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
else {
|
|
|
|
//using all the screen
|
2012-03-28 05:03:24 +00:00
|
|
|
if ((can_width / 2) <= (can_height)) {
|
2015-12-16 00:31:38 +00:00
|
|
|
ortho_width = 1.0f;
|
2009-04-08 15:06:20 +00:00
|
|
|
ortho_height = (float)can_height/can_width;
|
2012-06-06 22:38:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-08-02 21:17:12 +00:00
|
|
|
ortho_width = (float)can_width / can_height * 0.5f;
|
|
|
|
ortho_height = 0.5f;
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0f, 10.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
2015-12-16 00:31:38 +00:00
|
|
|
gluLookAt(0.0f,-1.0f,0.0f, 0.0f,0.0f,0.0f, 0.0f,0.0f,1.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
if (m_drawingmode == RAS_IRasterizer::KX_WIREFRAME)
|
2009-04-08 15:06:20 +00:00
|
|
|
glPolygonMode(GL_FRONT, GL_LINE);
|
|
|
|
else
|
|
|
|
glPolygonMode(GL_FRONT, GL_FILL);
|
|
|
|
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
2015-12-16 00:31:38 +00:00
|
|
|
glColor3f(1.0f,1.0f,1.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (dlistSupported) {
|
|
|
|
for (i=0;i<m_numfaces;i++) {
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[i]);
|
|
|
|
glCallList(dlistId+i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// domefacesId[4] => (top)
|
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[0]);
|
|
|
|
GLDrawTriangles(cubetop, nfacestop);
|
|
|
|
|
|
|
|
// domefacesId[5] => (bottom)
|
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[1]);
|
|
|
|
GLDrawTriangles(cubebottom, nfacesbottom);
|
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
// domefacesId[1] => -45deg (left)
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[2]);
|
|
|
|
GLDrawTriangles(cubeleft, nfacesleft);
|
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
// domefacesId[2] => 45deg (right)
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[3]);
|
|
|
|
GLDrawTriangles(cuberight, nfacesright);
|
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
// domefacesId[0] => -135deg (leftback)
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[4]);
|
|
|
|
GLDrawTriangles(cubeleftback, nfacesleftback);
|
|
|
|
|
2010-09-30 07:06:00 +00:00
|
|
|
// domefacesId[3] => 135deg (rightback)
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[5]);
|
|
|
|
GLDrawTriangles(cuberightback, nfacesrightback);
|
|
|
|
}
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::DrawDomeWarped(void)
|
|
|
|
{
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
// Making the viewport always square
|
|
|
|
int can_width = m_viewport.GetRight();
|
|
|
|
int can_height = m_viewport.GetTop();
|
|
|
|
|
2011-09-01 02:12:53 +00:00
|
|
|
double screen_ratio = can_width/ (double) can_height;
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2015-12-16 00:31:38 +00:00
|
|
|
glOrtho(-screen_ratio,screen_ratio,-1.0f,1.0f,-20.0f,10.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
2015-12-16 00:31:38 +00:00
|
|
|
gluLookAt(0.0f, 0.0f, 1.0f, 0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
if (m_drawingmode == RAS_IRasterizer::KX_WIREFRAME)
|
2009-04-08 15:06:20 +00:00
|
|
|
glPolygonMode(GL_FRONT, GL_LINE);
|
|
|
|
else
|
|
|
|
glPolygonMode(GL_FRONT, GL_FILL);
|
|
|
|
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
2015-12-16 00:31:38 +00:00
|
|
|
glColor3f(1.0f,1.0f,1.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
|
2012-03-28 05:03:24 +00:00
|
|
|
if (dlistSupported) {
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]);
|
|
|
|
glCallList(dlistId + m_numfaces);
|
|
|
|
}
|
2012-06-06 22:38:39 +00:00
|
|
|
else {
|
2009-04-08 15:06:20 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]);
|
|
|
|
GLDrawWarpQuads();
|
|
|
|
}
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::BindImages(int i)
|
|
|
|
{
|
|
|
|
glBindTexture(GL_TEXTURE_2D, domefacesId[i]);
|
|
|
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_viewport.GetLeft(), m_viewport.GetBottom(), m_buffersize, m_buffersize);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i)
|
|
|
|
{
|
|
|
|
if (!cam)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_canvas->SetViewPort(0,0,m_buffersize-1,m_buffersize-1);
|
|
|
|
|
|
|
|
// m_rasterizer->SetAmbient();
|
|
|
|
m_rasterizer->DisplayFog();
|
|
|
|
|
|
|
|
CalculateFrustum(cam); //calculates m_projmat
|
|
|
|
cam->SetProjectionMatrix(m_projmat);
|
|
|
|
m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix());
|
|
|
|
// Dome_RotateCamera(cam,i);
|
|
|
|
|
|
|
|
MT_Matrix3x3 camori = cam->GetSGNode()->GetLocalOrientation();
|
|
|
|
|
|
|
|
cam->NodeSetLocalOrientation(camori*m_locRot[i]);
|
|
|
|
cam->NodeUpdateGS(0.f);
|
|
|
|
|
|
|
|
MT_Transform camtrans(cam->GetWorldToCamera());
|
|
|
|
MT_Matrix4x4 viewmat(camtrans);
|
BGE: Various render improvements.
bge.logic.setRender(flag) to enable/disable render.
The render pass is enabled by default but it can be disabled with
bge.logic.setRender(False).
Once disabled, the render pass is skipped and a new logic frame starts
immediately. Note that VSync no longer limits the fps when render is off
but the 'Use Frame Rate' option in the Render Properties still does.
To run as many frames as possible, untick the option
This function is useful when you don't need the default render, e.g.
when doing offscreen render to an alternate device than the monitor.
Note that without VSync, you must limit the frame rate by other means.
fbo = bge.render.offScreenCreate(width,height,[,samples=0][,target=bge.render.RAS_OFS_RENDER_BUFFER])
Use this method to create an offscreen buffer of given size, with given MSAA
samples and targetting either a render buffer (bge.render.RAS_OFS_RENDER_BUFFER)
or a texture (bge.render.RAS_OFS_RENDER_TEXTURE). Use the former if you want to
retrieve the frame buffer on the host and the latter if you want to pass the render
to another context (texture are proper OGL object, render buffers aren't)
The object created by this function can only be used as a parameter of the
bge.texture.ImageRender() constructor to send the the render to the FBO rather
than to the frame buffer. This is best suited when you want to create a render
of specific size, or if you need an image with an alpha channel.
bge.texture.<imagetype>.refresh(buffer=None, format="RGBA", ts=-1.0)
Without arg, the refresh method of the image objects is pretty much a no-op, it
simply invalidates the image so that on next texture refresh, the image will
be recalculated.
It is now possible to pass an optional buffer object to transfer the image (and
recalculate it if it was invalid) to an external object. The object must implement
the 'buffer protocol'. The image will be transfered as "RGBA" or "BGRA" pixels
depending on format argument (only those 2 formats are supported) and ts is an
optional timestamp in the image depends on it (e.g. VideoFFmpeg playing a video file).
With this function you don't need anymore to link the image object to a Texture
object to use: the image object is self-sufficient.
bge.texture.ImageRender(scene, camera, fbo=None)
Render to buffer is possible by passing a FBO object (see offScreenCreate).
bge.texture.ImageRender.render()
Allows asynchronous render: call this method to render the scene but without
extracting the pixels yet. The function returns as soon as the render commands
have been send to the GPU. The render will proceed asynchronously in the GPU
while the host can perform other tasks.
To complete the render, you can either call refresh() directly of refresh the texture
to which this object is the source. Asynchronous render is useful to achieve optimal
performance: call render() on frame N and refresh() on frame N+1 to give as much as
time as possible to the GPU to render the frame while the game engine can perform other tasks.
Support negative scale on camera.
Camera scale was previously ignored in the BGE.
It is now injected in the modelview matrix as a vertical or horizontal flip
of the scene (respectively if scaleY<0 and scaleX<0).
Note that the actual value of the scale is not used, only the sign.
This allows to flip the image produced by ImageRender() without any performance
degradation: the flip is integrated in the render itself.
Optimized image transfer from ImageRender to buffer.
Previously, images that were transferred to the host were always going through
buffers in VideoTexture. It is now possible to transfer ImageRender
images to external buffer without intermediate copy (i.e. directly from OGL to buffer)
if the attributes of the ImageRender objects are set as follow:
flip=False, alpha=True, scale=False, depth=False, zbuff=False.
(if you need to flip the image, use camera negative scale)
2016-06-09 21:56:45 +00:00
|
|
|
m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->NodeGetLocalScaling(), 1.0f);
|
2009-04-08 15:06:20 +00:00
|
|
|
cam->SetModelviewMatrix(viewmat);
|
|
|
|
|
|
|
|
// restore the original orientation
|
|
|
|
cam->NodeSetLocalOrientation(camori);
|
|
|
|
cam->NodeUpdateGS(0.f);
|
2010-09-15 07:05:55 +00:00
|
|
|
|
|
|
|
scene->CalculateVisibleMeshes(m_rasterizer,cam);
|
2015-06-22 14:44:16 +00:00
|
|
|
|
|
|
|
m_engine->UpdateAnimations(scene);
|
|
|
|
|
2013-11-04 19:21:07 +00:00
|
|
|
scene->RenderBuckets(camtrans, m_rasterizer);
|
2009-04-23 13:30:34 +00:00
|
|
|
}
|
|
|
|
|