[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20099] trunk/blender/source/gameengine/ Ketsji: BGE Dome: Implementation of FBO to handle warp mesh rendering.

Dalai Felinto dfelinto at gmail.com
Thu May 7 22:00:12 CEST 2009


Revision: 20099
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20099
Author:   dfelinto
Date:     2009-05-07 22:00:09 +0200 (Thu, 07 May 2009)

Log Message:
-----------
BGE Dome: Implementation of FBO to handle warp mesh rendering.
We are using an image twice as big to render the fisheye before warping.
It'll slow down warping meshes a little, but we get way more resolution.

Therefore I will bring Truncated Dome mode back in order to avoid using warping mesh for that.

Modified Paths:
--------------
    trunk/blender/source/gameengine/Ketsji/KX_Dome.cpp
    trunk/blender/source/gameengine/Ketsji/KX_Dome.h

Modified: trunk/blender/source/gameengine/Ketsji/KX_Dome.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_Dome.cpp	2009-05-07 19:36:12 UTC (rev 20098)
+++ trunk/blender/source/gameengine/Ketsji/KX_Dome.cpp	2009-05-07 20:00:09 UTC (rev 20099)
@@ -66,6 +66,7 @@
 	m_engine(engine)
 {
 	warp.usemesh = false;
+	fboSupported = false;
 
 	if (mode >= DOME_NUM_MODES)
 		m_mode = DOME_FISHEYE;
@@ -131,16 +132,20 @@
 
 	CreateGLImages();
 
+	if(warp.usemesh)
+		fboSupported = CreateFBO();
+
 	dlistSupported = CreateDL();
 }
 
 // destructor
 KX_Dome::~KX_Dome (void)
 {
-	GLuint m_numimages = m_numfaces;
-
 	ClearGLImages();
 
+	if(fboSupported)
+		glDeleteFramebuffersEXT(1, &warp.fboId);
+
 	if(dlistSupported)
 		glDeleteLists(dlistId, (GLsizei) m_numimages);
 }
@@ -174,9 +179,9 @@
 	}
 	if(warp.usemesh){
 		glBindTexture(GL_TEXTURE_2D, domefacesId[m_numfaces]);
-		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, warp.imagewidth, warp.imageheight, 0, GL_RGB8,
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, warp.imagesize, warp.imagesize, 0, GL_RGB8,
 				GL_UNSIGNED_BYTE, 0);
-		glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, warp.imagewidth, warp.imageheight, 0);
+		glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, warp.imagesize, warp.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);
@@ -227,19 +232,21 @@
 	m_imagesize = (1 << i);
 
 	if (warp.usemesh){
-		warp.bufferwidth = canvaswidth;
-		warp.bufferheight = canvasheight;
+		// trying to use twice the size of the cube faces
+		GLint glMaxTexDim;
+		glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim);
 
-		i = 0;
-		while ((1 << i) <= warp.bufferwidth)
-			i++;
-		warp.imagewidth = (1 << i);
+		if (2 * m_imagesize > glMaxTexDim)
+			warp.imagesize = m_imagesize;
 
-		i = 0;
-		while ((1 << i) <= warp.bufferheight)
-			i++;
-		warp.imageheight = (1 << i);
+		else
+			warp.imagesize = 2 * m_imagesize;
+
+		//if FBO is not working/supported, we use the canvas dimension as buffer
+		warp.bufferwidth  = canvaswidth;
+		warp.bufferheight = canvasheight;
 	}
+
 	//XXX HACK
 	canvaswidth  = m_viewport.GetWidth();
 	canvasheight = m_viewport.GetHeight();
@@ -320,6 +327,40 @@
 	return true;
 }
 
+bool KX_Dome::CreateFBO(void)
+{
+	glGenFramebuffersEXT(1, &warp.fboId);
+	if(warp.fboId==0)
+	{
+		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);
+
+	if(status == GL_FRAMEBUFFER_UNSUPPORTED_EXT)
+	{
+		printf("Dome Error: FrameBuffer unsupported. Using low resolution warp image.");
+		return false;
+	}
+	else if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
+	{
+		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;
+}
+
 void KX_Dome::GLDrawTriangles(vector <DomeFace>& face, int nfaces)
 {
 	int i,j;
@@ -336,9 +377,10 @@
 void KX_Dome::GLDrawWarpQuads(void)
 {
 	int i, j, i2;
-	float uv_width = (float)(warp.bufferwidth-1) / warp.imagewidth;
-	float uv_height = (float)(warp.bufferheight-1) / warp.imageheight;
 
+	float uv_width = (float)(warp.bufferwidth) / warp.imagesize;
+	float uv_height = (float)(warp.bufferheight) / warp.imagesize;
+
 	if(warp.mode ==2 ){
 		glBegin(GL_QUADS);
 		for (i=0;i<warp.n_height-1;i++) {
@@ -394,7 +436,7 @@
 		}
 		glEnd();
 	} else{
-		printf("Error: Warp Mode %d unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n", warp.mode);
+		printf("Dome Error: Warp Mode %d unsupported. Try 1 for Polar Mesh or 2 for Fisheye.\n", warp.mode);
 	}
 }
 
@@ -430,7 +472,7 @@
 
 	lines = text.Explode('\n');
 	if(lines.size() < 6){
-		printf("Error: Warp Mesh File with insufficient data!\n");
+		printf("Dome Error: Warp Mesh File with insufficient data!\n");
 		return false;
 	}
 	columns = lines[1].Explode(' ');
@@ -438,7 +480,7 @@
 		columns = lines[1].Explode('\t');
 
 	if(columns.size() !=2){
-		printf("Error: Warp Mesh File incorrect. The second line should contain: width height.\n");
+		printf("Dome Error: Warp Mesh File incorrect. The second line should contain: width height.\n");
 		return false;
 	}
 
@@ -448,7 +490,7 @@
 	warp.n_height = atoi(columns[1]);
 
 	if ((int)lines.size() < 2 + (warp.n_width * warp.n_height)){
-		printf("Error: Warp Mesh File with insufficient data!\n");
+		printf("Dome Error: Warp Mesh File with insufficient data!\n");
 		return false;
 	}else{
 		warp.nodes = vector<vector<WarpMeshNode> > (warp.n_height, vector<WarpMeshNode>(warp.n_width));
@@ -470,7 +512,7 @@
 			}
 			else{
 				warp.nodes.clear();
-				printf("Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n");
+				printf("Dome Error: Warp Mesh File with wrong number of fields. You should use 5: x y u v i.\n");
 				return false;
 			}
 		}
@@ -1538,6 +1580,13 @@
 void KX_Dome::Draw(void)
 {
 
+	if (fboSupported){
+		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, warp.fboId);
+
+		glViewport(0,0,warp.imagesize, warp.imagesize);
+		glScissor(0,0,warp.imagesize, warp.imagesize);
+	}
+
 	switch(m_mode){
 		case DOME_FISHEYE:
 			DrawDomeFisheye();
@@ -1552,8 +1601,16 @@
 
 	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, warp.bufferheight);
+		if(fboSupported)
+		{
+			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);
+		}
 		DrawDomeWarped();
 	}
 }

Modified: trunk/blender/source/gameengine/Ketsji/KX_Dome.h
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_Dome.h	2009-05-07 19:36:12 UTC (rev 20098)
+++ trunk/blender/source/gameengine/Ketsji/KX_Dome.h	2009-05-07 20:00:09 UTC (rev 20099)
@@ -74,6 +74,7 @@
 
 	//openGL checks:
 	bool	dlistSupported;
+	bool	fboSupported;
 
 	//openGL names:
 	GLuint domefacesId[7];		// ID of the images -- room for 7 images, using only 4 for 180\xBA x 360\xBA dome, 6 for panoramic and +1 for warp mesh
@@ -93,8 +94,9 @@
 		bool usemesh;
 		int mode;
 		int n_width, n_height; //nodes width and height
-		int imagewidth, imageheight;
+		int imagesize;
 		int bufferwidth, bufferheight;
+		GLuint fboId;
 		vector <vector <WarpMeshNode> > nodes;
 	} warp;
 
@@ -140,6 +142,8 @@
 	void ClearGLImages(void);//called on resize
 	bool CreateDL(void); //create Display Lists
 	void ClearDL(void);  //remove Display Lists 
+	bool CreateFBO(void);//create FBO (for warp mesh)
+	void ClearFBO(void); //remove FBO
 
 	void CalculateCameraOrientation();
 	void CalculateImageSize(); //set m_imagesize





More information about the Bf-blender-cvs mailing list