From c3fbb17e030c77cf94d1646dabd0e5af4150a02b Mon Sep 17 00:00:00 2001 From: Dalai Felinto <dfelinto@gmail.com> Date: Sat, 4 Apr 2009 02:05:57 +0000 Subject: [PATCH] Warp Mesh supported now. CopyTexSubImage2D implemented now instead of CopyTexImage2D --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenloader/intern/readfile.c | 10 +- source/blender/makesdna/DNA_scene_types.h | 3 + source/blender/src/buttons_scene.c | 6 +- .../BlenderRoutines/BL_KetsjiEmbedStart.cpp | 2 +- .../GamePlayer/ghost/GPG_Application.cpp | 2 +- source/gameengine/Ketsji/KX_Dome.cpp | 371 +++++++++++++++--- source/gameengine/Ketsji/KX_Dome.h | 32 +- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 5 +- source/gameengine/Ketsji/KX_KetsjiEngine.h | 2 +- 10 files changed, 361 insertions(+), 74 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index db6d4762b17..d49a5425b61 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -41,7 +41,7 @@ struct ListBase; struct MemFile; #define BLENDER_VERSION 248 -#define BLENDER_SUBVERSION 3 +#define BLENDER_SUBVERSION 4 #define BLENDER_MINVERSION 245 #define BLENDER_MINSUBVERSION 15 diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 4317cddd4c2..d03bcfa09e5 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3531,7 +3531,9 @@ static void lib_link_scene(FileData *fd, Main *main) srl->mat_override= newlibadr_us(fd, sce->id.lib, srl->mat_override); srl->light_override= newlibadr_us(fd, sce->id.lib, srl->light_override); } - + /*Game Settings: Dome Warp Text*/ + sce->r.dometext= newlibadr_us(fd, sce->id.lib, sce->r.dometext); + sce->id.flag -= LIB_NEEDLINK; } @@ -8035,7 +8037,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } - if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 3)) { + if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 4)) { Scene *sce; /* Dome (Fisheye) default parameters */ @@ -8854,7 +8856,9 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce) expand_doit(fd, mainvar, srl->mat_override); expand_doit(fd, mainvar, srl->light_override); } - + + if(sce->r.dometext) + expand_doit(fd, mainvar, sce->r.dometext); } static void expand_camera(FileData *fd, Main *mainvar, Camera *ca) diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 3742aabb95a..bf5b2ad3df5 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -45,6 +45,7 @@ struct World; struct Scene; struct Image; struct Group; +struct Text; struct bNodeTree; typedef struct Base { @@ -320,6 +321,8 @@ typedef struct RenderData { short domeangle, pad9; float domesize; float domeresbuf; + struct Text *dometext; + } RenderData; /* control render convert and shading engine */ diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 68f043540c7..f026e5f4034 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1766,13 +1766,13 @@ static uiBlock *edge_render_menu(void *arg_unused) static uiBlock *framing_render_menu(void *arg_unused) { uiBlock *block; - short yco = 241, xco = 0; + short yco = 267, xco = 0; int randomcolorindex = 1234; block= uiNewBlock(&curarea->uiblocks, "framing_options", UI_EMBOSS, UI_HELV, curarea->win); /* use this for a fake extra empy space around the buttons */ - uiDefBut(block, LABEL, 0, "", -5, -10, 295, 275, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "", -5, -10, 295, 300, NULL, 0, 0, 0, 0, ""); uiDefBut(block, LABEL, 0, "Framing:", xco, yco, 68,19, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); @@ -1834,6 +1834,8 @@ static uiBlock *framing_render_menu(void *arg_unused) uiDefButF(block, NUM, 0, "Size:", xco-=180, yco-=21, 88, 19, &G.scene->r.domesize, 0.5, 3.5, 0, 0, "Size adjustments"); uiDefButS(block, NUM, 0, "Tes:", xco+=90, yco, 88, 19, &G.scene->r.domeres, 1.0, 8.0, 0, 0, "Tesselation level - 1 to 8"); uiDefButF(block, NUM, 0, "Res:", xco+=90, yco, 88, 19, &G.scene->r.domeresbuf, 0.1, 1.0, 0, 0, "Buffer Resolution - decrease it to increase speed"); + + uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Warp Data: ", xco-180,yco-=21,268, 19, &G.scene->r.dometext, "Custom Warp Mesh data file"); uiBlockEndAlign(block); uiBlockSetDirection(block, UI_TOP); diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index b2761e31f24..0cc574d762d 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -374,7 +374,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, //initialize Dome Settings if(blscene->r.stereomode == RAS_IRasterizer::RAS_STEREO_DOME) - ketsjiengine->InitDome(blscene->r.domesize, blscene->r.domeres, blscene->r.domemode, blscene->r.domeangle, blscene->r.domeresbuf); + ketsjiengine->InitDome(blscene->r.domesize, blscene->r.domeres, blscene->r.domemode, blscene->r.domeangle, blscene->r.domeresbuf, blscene->r.dometext); if (sceneconverter) { diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 9c28a26cf1b..beb74add946 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -695,7 +695,7 @@ bool GPG_Application::startEngine(void) //initialize Dome Settings if(m_startScene->r.stereomode == RAS_IRasterizer::RAS_STEREO_DOME) - m_ketsjiengine->InitDome(m_startScene->r.domesize, m_startScene->r.domeres, m_startScene->r.domemode, m_startScene->r.domeangle, m_startScene->r.domeresbuf); + m_ketsjiengine->InitDome(m_startScene->r.domesize, m_startScene->r.domeres, m_startScene->r.domemode, m_startScene->r.domeangle, m_startScene->r.domeresbuf, m_startScene->r.dometext); // Set the GameLogic.globalDict from marshal'd data, so we can // load new blend files and keep data in GameLogic.globalDict diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index 6c0e1db01c3..3485d0f506f 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -49,7 +49,8 @@ KX_Dome::KX_Dome ( short res, //resolution of the mesh short mode, //mode - fisheye, truncated, warped, panoramic, ... short angle, - float resbuf //size adjustment of the buffer + float resbuf, //size adjustment of the buffer + struct Text* warptext ): m_canvas(canvas), @@ -65,9 +66,22 @@ KX_Dome::KX_Dome ( canvaswidth(-1), canvasheight(-1), dlistSupported(false) { - if (mode > DOME_NUM_MODES) + warp.usemesh = false; + + 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 GLuint viewport[4]={0}; glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); @@ -118,33 +132,58 @@ KX_Dome::KX_Dome ( break; } + m_numimages =(warp.usemesh?m_numfaces+1:m_numfaces); + CalculateCameraOrientation(); CreateGLImages(); - //openGL check - if(GLEW_VERSION_1_1){ - dlistSupported = true; - CreateDL(); - } + dlistSupported = CreateDL(); } // destructor KX_Dome::~KX_Dome (void) { + GLuint m_numimages = m_numfaces; + ClearGLImages(); if(dlistSupported) - glDeleteLists(dlistId, (GLsizei) m_numfaces); + glDeleteLists(dlistId, (GLsizei) m_numimages); } -void KX_Dome::CreateGLImages(void){ - glGenTextures(m_numfaces, (GLuint*)&domefacesId); +void KX_Dome::SetViewPort(GLuint viewport[4]) +{ + if(canvaswidth != m_canvas->GetWidth() || canvasheight != m_canvas->GetHeight()) + { + 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); for (int j=0;j<m_numfaces;j++){ glBindTexture(GL_TEXTURE_2D, domefacesId[j]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, m_imagesize, m_imagesize, 0, GL_RGBA, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, m_imagesize, m_imagesize, 0, GL_RGB8, + GL_UNSIGNED_BYTE, 0); + 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); + } + if(warp.usemesh){ + glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, warp.imagewidth, warp.imageheight, 0, GL_RGB8, GL_UNSIGNED_BYTE, 0); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, warp.imagewidth, warp.imageheight, 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); @@ -154,9 +193,9 @@ void KX_Dome::CreateGLImages(void){ void KX_Dome::ClearGLImages(void) { - glDeleteTextures(m_numfaces, (GLuint*)&domefacesId); + glDeleteTextures(m_numimages, (GLuint*)&domefacesId); /* - for (int i=0;i<m_numfaces;i++) + for (int i=0;i<m_numimages;i++) if(glIsTexture(domefacesId[i])) glDeleteTextures(1, (GLuint*)&domefacesId[i]); */ @@ -180,12 +219,27 @@ void KX_Dome::CalculateImageSize(void) while ((1 << i) <= m_buffersize) i++; m_imagesize = (1 << i); + + if (warp.usemesh){ + warp.bufferwidth = canvaswidth; + warp.bufferheight = canvasheight; + + i = 0; + while ((1 << i) <= warp.bufferwidth) + i++; + warp.imagewidth = (1 << i); + + i = 0; + while ((1 << i) <= warp.bufferheight) + i++; + warp.imageheight = (1 << i); + } } -void KX_Dome::CreateDL(){ +bool KX_Dome::CreateDL(){ int i,j; - dlistId = glGenLists((GLsizei) m_numfaces); + dlistId = glGenLists((GLsizei) m_numimages); if (dlistId != 0) { if(m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED){ glNewList(dlistId, GL_COMPILE); @@ -210,8 +264,8 @@ void KX_Dome::CreateDL(){ glEndList(); } } - else if (m_mode == DOME_PANORAM_SPH){ - + else if (m_mode == DOME_PANORAM_SPH) + { glNewList(dlistId, GL_COMPILE); GLDrawTriangles(cubetop, nfacestop); glEndList(); @@ -236,6 +290,13 @@ void KX_Dome::CreateDL(){ GLDrawTriangles(cuberightback, nfacesrightback); glEndList(); } + + if(warp.usemesh){ + glNewList((dlistId + m_numfaces), GL_COMPILE); + GLDrawWarpQuads(); + glEndList(); + } + //clearing the vectors cubetop.clear(); cubebottom.clear(); @@ -244,9 +305,12 @@ void KX_Dome::CreateDL(){ cubefront.clear(); cubeleftback.clear(); cuberightback.clear(); + warp.nodes.clear(); } else // genList failed - dlistSupported = false; + return false; + + return true; } void KX_Dome::GLDrawTriangles(vector <DomeFace>& face, int nfaces) @@ -261,6 +325,148 @@ void KX_Dome::GLDrawTriangles(vector <DomeFace>& face, int nfaces) } glEnd(); } + +void KX_Dome::GLDrawWarpQuads(void) +{ + int i, j, i2; + float uv_width = (float)warp.bufferwidth / warp.imagewidth; + float uv_height = (float)warp.bufferheight / warp.imageheight; + + if(warp.mode ==2 ){ + glBegin(GL_QUADS); + for (i=0;i<warp.n_height-1;i++) { + for (j=0;j<warp.n_width-1;j++) { + 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) + continue; + + 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)); + glVertex3f(warp.nodes[i][j].x, warp.nodes[i][j].y,0.0); + + 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)); + glVertex3f(warp.nodes[i+1][j].x, warp.nodes[i+1][j].y,0.0); + + 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)); + glVertex3f(warp.nodes[i+1][j+1].x, warp.nodes[i+1][j+1].y,0.0); + + 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)); + glVertex3f(warp.nodes[i][j+1].x, warp.nodes[i][j+1].y,0.0); + } + } + glEnd(); + } + else if (warp.mode == 1){ + 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; + + 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)); + glVertex3f(warp.nodes[i][j].x,warp.nodes[i][j].y,0.0); + + 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)); + glVertex3f(warp.nodes[i2][j].x,warp.nodes[i2][j].y,0.0); + + 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)); + glVertex3f(warp.nodes[i2][j+1].x,warp.nodes[i2][j+1].y,0.0); + + 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)); + glVertex3f(warp.nodes[i2][j+1].x,warp.nodes[i2][j+1].y,0.0); + + } + } + glEnd(); + } else{ + printf("Error: Warp Mode unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n"); + } +} + + +bool KX_Dome::ParseWarpMesh(STR_String text) +{ +/* +//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 +Tthe next line has the mesh dimensions +Rest of the lines are the nodes of the mesh. Each line has x y u v i + (x,y) are the normalised screen coordinates + (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 +*/ + int i,j,k; + int nodeX=0, nodeY=0; + + vector<STR_String> columns, lines; + + lines = text.Explode('\n'); + if(lines.size() < 6){ + printf("Error: Warp Mesh File with insufficient data!\n"); + return false; + } + columns = lines[1].Explode(' '); + + if(columns.size() !=2){ + printf("Error: Warp Mesh File incorrect. The second line should contain: width height.\n"); + return false; + } + + warp.mode = atoi(lines[0]);// 1 = radial, 2 = fisheye + + warp.n_width = atoi(columns[0]); + warp.n_height = atoi(columns[1]); + + if (lines.size() < 2 + (warp.n_width * warp.n_height)){ + printf("Error: Warp Mesh File with insufficient data!\n"); + return false; + }else{ + warp.nodes = vector<vector <WarpMeshNode>> (warp.n_height, vector<WarpMeshNode>(warp.n_width)); + + for(i=2; i-2 < (warp.n_width*warp.n_height); i++){ + columns = lines[i].Explode(' '); + + if (columns.size() == 5){ + 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]); + } + else{ + warp.nodes.clear(); + printf("Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n"); + return false; + } + } + } + return true; +} + void KX_Dome::CreateMeshDome180(void) { /* @@ -1321,6 +1527,7 @@ void KX_Dome::RotateCamera(KX_Camera* cam, int i) void KX_Dome::Draw(void) { + switch(m_mode){ case DOME_FISHEYE: DrawDomeFisheye(); @@ -1332,6 +1539,13 @@ void KX_Dome::Draw(void) DrawPanorama(); break; } + + if(warp.usemesh) + { + glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_viewport.GetLeft(), m_viewport.GetBottom(), warp.bufferwidth+1, warp.bufferheight+1); + DrawDomeWarped(); + } } void KX_Dome::DrawDomeFisheye(void) @@ -1349,15 +1563,17 @@ void KX_Dome::DrawDomeFisheye(void) float ortho_width, ortho_height; - if (m_mode == DOME_TRUNCATED){ - ortho_width = 1.0; - ortho_height = 2 * ((float)can_height/can_width) - 1.0 ; - - ortho_width /= m_size; - ortho_height /= m_size; + if (warp.usemesh) + glOrtho((-1.0), 1.0, (-1.0), 1.0, -20.0, 10.0); //stretch the image to reduce resolution lost + + else if(m_mode == DOME_TRUNCATED){ + ortho_width = 1.0; + ortho_height = 2 * ((float)can_height/can_width) - 1.0 ; + + ortho_width /= m_size; + ortho_height /= m_size; - glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_width, -20.0, 10.0); - + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_width, -20.0, 10.0); } else { if (can_width < can_height){ ortho_width = 1.0; @@ -1439,19 +1655,24 @@ void KX_Dome::DrawPanorama(void) float ortho_height = 1.0; float ortho_width = 1.0; - //using all the screen - if ((can_width / 2) <= (can_height)){ - ortho_width = 1.0; - ortho_height = (float)can_height/can_width; - }else{ - ortho_width = (float)can_width/can_height * 0.5; - ortho_height = 0.5; - } + if (warp.usemesh) + glOrtho((-1.0), 1.0, (-0.5), 0.5, -20.0, 10.0); //stretch the image to reduce resolution lost - ortho_width /= m_size; - ortho_height /= m_size; - - glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + else { + //using all the screen + if ((can_width / 2) <= (can_height)){ + ortho_width = 1.0; + ortho_height = (float)can_height/can_width; + }else{ + ortho_width = (float)can_width/can_height * 0.5; + ortho_height = 0.5; + } + + ortho_width /= m_size; + ortho_height /= m_size; + + glOrtho((-ortho_width), ortho_width, (-ortho_height), ortho_height, -20.0, 10.0); + } glMatrixMode(GL_TEXTURE); glLoadIdentity(); @@ -1506,28 +1727,62 @@ void KX_Dome::DrawPanorama(void) glEnable(GL_DEPTH_TEST); } -void KX_Dome::BindImages(int i) +void KX_Dome::DrawDomeWarped(void) { -/* -todo: I'm copying more than I need. -I would like to change glCopyTexImage by glCopyTexSubImage but I couldn't make it work. -the copy size can be only m_buffersize -*/ - glBindTexture(GL_TEXTURE_2D, domefacesId[i]); - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_viewport.GetLeft(), m_viewport.GetBottom(), m_imagesize, m_imagesize, 0); -} + int i,j; -void KX_Dome::SetViewPort(GLuint viewport[4]) -{ - if(canvaswidth != m_canvas->GetWidth() || canvasheight != m_canvas->GetHeight()) - { - m_viewport.SetLeft(viewport[0]); - m_viewport.SetBottom(viewport[1]); - m_viewport.SetRight(viewport[2]); - m_viewport.SetTop(viewport[3]); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); - CalculateImageSize(); + // Making the viewport always square + int can_width = m_viewport.GetRight(); + int can_height = m_viewport.GetTop(); + + double screen_ratio = can_width/ (double) can_height; + screen_ratio /= m_size; + + glOrtho(-screen_ratio,screen_ratio,-1.0,1.0,-20.0,10.0); + + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0.0, 0.0, 1.0, 0.0,0.0,0.0, 0.0,1.0,0.0); + + if(m_drawingmode == RAS_IRasterizer::KX_WIREFRAME) + 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); + glColor3f(1.0,1.0,1.0); + + + float uv_width = (float)warp.bufferwidth / warp.imagewidth; + float uv_height = (float)warp.bufferheight / warp.imageheight; + + if (dlistSupported){ + glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]); + glCallList(dlistId + m_numfaces); + } + else{ + 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+1, m_buffersize+1); } void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i) @@ -1537,7 +1792,7 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i) m_canvas->SetViewPort(0,0,m_buffersize,m_buffersize); - //m_rasterizer->SetAmbient(); +// m_rasterizer->SetAmbient(); m_rasterizer->DisplayFog(); CalculateFrustum(cam); //calculates m_projmat diff --git a/source/gameengine/Ketsji/KX_Dome.h b/source/gameengine/Ketsji/KX_Dome.h index aac35003653..de3360cd897 100644 --- a/source/gameengine/Ketsji/KX_Dome.h +++ b/source/gameengine/Ketsji/KX_Dome.h @@ -36,6 +36,10 @@ Developed as part of a Research and Development project for SAT - La Soci #include <BIF_gl.h> #include <vector> +#include "MEM_guardedalloc.h" +#include "BKE_text.h" +//#include "BLI_blenlib.h" + //Dome modes: limit hardcoded in buttons_scene.c #define DOME_FISHEYE 1 #define DOME_TRUNCATED 2 @@ -61,7 +65,8 @@ public: short res, short mode, short angle, - float resbuf + float resbuf, + struct Text* warptext ); /// destructor @@ -71,7 +76,7 @@ public: bool dlistSupported; //openGL names: - GLuint domefacesId[6]; // ID of the images -- room for 6 images, using only 4 for 180� x 360� dome + GLuint domefacesId[7]; // ID of the images -- room for 7 images, using only 4 for 180� x 360� dome, 6 for panoramic and +1 for warp mesh GLuint dlistId; // ID of the Display Lists of the images (used as an offset) typedef struct { @@ -79,7 +84,23 @@ public: MT_Vector3 verts[3]; //three verts } DomeFace; - vector <DomeFace> cubetop, cubebottom, cuberight, cubeleft, cubefront, cubeback; //for dome + //mesh warp functions + typedef struct { + double x, y, u, v, i; + } WarpMeshNode; + + struct { + bool usemesh; + int mode; + int n_width, n_height; //nodes width and height + int imagewidth, imageheight; + int bufferwidth, bufferheight; + vector <vector <WarpMeshNode> > nodes; + } warp; + + bool ParseWarpMesh(STR_String text); + + vector <DomeFace> cubetop, cubebottom, cuberight, cubeleft, cubefront, cubeback; //for fisheye vector <DomeFace> cubeleftback, cuberightback; //for panorama int nfacestop, nfacesbottom, nfacesleft, nfacesright, nfacesfront, nfacesback; @@ -107,14 +128,16 @@ public: //Draw functions void GLDrawTriangles(vector <DomeFace>& face, int nfaces); + void GLDrawWarpQuads(void); void Draw(void); void DrawDomeFisheye(void); void DrawPanorama(void); + void DrawDomeWarped(void); //setting up openGL void CreateGLImages(void); void ClearGLImages(void);//called on resize - void CreateDL(void); //create Display Lists + bool CreateDL(void); //create Display Lists void ClearDL(void); //remove Display Lists void CalculateCameraOrientation(); @@ -129,6 +152,7 @@ protected: int m_imagesize; int m_buffersize; // canvas small dimension int m_numfaces; // 4 to 6 depending on the kind of dome image + int m_numimages; //numfaces +1 if we have warp mesh float m_size; // size to adjust short m_resolution; //resolution to tesselate the mesh diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 5bd74f4621d..68eb9f55378 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -261,15 +261,14 @@ void KX_KetsjiEngine::SetSceneConverter(KX_ISceneConverter* sceneconverter) m_sceneconverter = sceneconverter; } -void KX_KetsjiEngine::InitDome(float size, short res, short mode, short angle, float resbuf) +void KX_KetsjiEngine::InitDome(float size, short res, short mode, short angle, float resbuf, struct Text* text) { - m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this, size, res, mode, angle, resbuf); + m_dome = new KX_Dome(m_canvas, m_rasterizer, m_rendertools,this, size, res, mode, angle, resbuf, text); m_usedome = true; } void KX_KetsjiEngine::RenderDome() { - GLuint viewport[4]={0}; glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); // unsigned int m_viewport[4] = {viewport[0], viewport[1], viewport[2], viewport[3]}; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index ccffd7b1e51..a8ccd6100d7 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -210,7 +210,7 @@ public: RAS_IRenderTools* GetRenderTools(){return m_rendertools;}; /// Dome functions - void InitDome(float size, short res, short mode, short angle, float resbuf); + void InitDome(float size, short res, short mode, short angle, float resbuf, struct Text* text); void EndDome(); void RenderDome(); bool m_usedome; -- GitLab