/******************************************************************************
* Renders the modifier's visual representation and computes its bounding box.
******************************************************************************/
Box3 SliceModifier::renderVisual(TimePoint time, ObjectNode* contextNode, SceneRenderer* renderer)
{
	TimeInterval interval;

	Box3 bb = contextNode->localBoundingBox(time);
	if(bb.isEmpty())
		return Box3();

	Plane3 plane = slicingPlane(time, interval);

	FloatType sliceWidth = 0;
	if(_widthCtrl) sliceWidth = _widthCtrl->getFloatValue(time, interval);

	ColorA color(0.8f, 0.3f, 0.3f);
	if(sliceWidth <= 0) {
		return renderPlane(renderer, plane, bb, color);
	}
	else {
		plane.dist += sliceWidth / 2;
		Box3 box = renderPlane(renderer, plane, bb, color);
		plane.dist -= sliceWidth;
		box.addBox(renderPlane(renderer, plane, bb, color));
		return box;
	}
}
void PlayerModel::render() {
    TextureManager::getInstance()->enableTexture();
	glBindTexture(GL_TEXTURE_2D, TextureManager::getInstance()->getTextures("gold.bmp"));
	
    glPushMatrix();
        glScalef(0.3f,0.3f,0.3f);
        glColor3f(1, 1, 0);

        renderPlane();

        glPushMatrix();
            glTranslatef(0, 1.0f, 0);
            renderPlane();
        glPopMatrix();

        //front
        renderOneSide();

        //right side
        glPushMatrix();
            glTranslatef(3.0f, 0.0f, 0.0f);
            glRotated(-90.0f, 0, 1.0f, 0);
            renderOneSide();
        glPopMatrix();

        //back
        glPushMatrix();
            glTranslatef(3.0f, 0.0f, 3.0f);
            glRotated(180.0f, 0, 1.0f, 0);
            renderOneSide();
        glPopMatrix();

        //left side
        glPushMatrix();
            glTranslatef(0.0f, 0.0f, 3.0f);
            glRotated(90.0f, 0, 1.0f, 0);
            renderOneSide();
        glPopMatrix();
    glPopMatrix();
    
    glDisable(GL_TEXTURE_2D);
}
void Planes::render()
{
    if(displaylist_index)
	   glCallList(displaylist_index);
    else
    {
    	for(int plane_index=0;plane_index<plane_number;++plane_index)
    	{
    	    if(plane_enabled[plane_index])
    		renderPlane(plane_index);
    	}
    }
}
Exemple #4
0
void renderFn()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);



	g_program.use();
	setPerspective();
	glActiveTexture(GL_TEXTURE9);
	glBindTexture(GL_TEXTURE_2D, omap2);

	g_program.setUniform("MaxTessLevel", max_tess);
	g_program.setUniform("ModelView", g_modelview);
	g_program.setUniform("Projection", g_projection);
	g_program.setUniform("MVP", g_projection * g_modelview);
	g_program.setUniform("NormalMatrix", 
			glm::inverseTranspose(mat3(g_modelview)));
	g_program.setUniform("MousePosition", mouse);
	
	g_program.setUniform("Time", elapsed);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	renderLand();

	d_program.use();
	
	glUniformSubroutinesuiv(GL_VERTEX_SHADER, 1, &plv); 
	glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &plf); 

	glActiveTexture(GL_TEXTURE9);
	glBindTexture(GL_TEXTURE_2D, plane);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	renderPlane(scene->mRootNode);

	glDisable(GL_DEPTH_TEST);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	d_program.setUniform("FrameTime", clockdiff);
	d_program.setUniform("Elapsed", elapsed);
	glUniformSubroutinesuiv(GL_VERTEX_SHADER, 1, &pav); 
	glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &paf); 
	renderParticles();

	glEnable(GL_DEPTH_TEST);
	glDisable(GL_BLEND);
}
void Planes::setEnableStatus(bool status,int plane_idx)
{
    if(plane_idx<=0||plane_idx>plane_number)
	return;
    plane_enabled[plane_idx-1]=status?1:0;
    //update display list
    glDeleteLists(displaylist_index,1);
    //build display list for the enabled planes
    displaylist_index=glGenLists(1);
    if(displaylist_index!=0)
    {
	glNewList(displaylist_index,GL_COMPILE);
	for(int plane_index=0;plane_index<plane_number;++plane_index)
	{
	    if(plane_enabled[plane_index])
		renderPlane(plane_index);
	}
	glEndList();
    }
}
Exemple #6
0
//------------------------------------------------------------------------------
void PlaneAnimation::clockDetected() {
    if (clockCounter == 0) {
        if (addingX) {
            if (xCoefficient >= 0.5)
                addingX = false;
        }
        else {
            if (xCoefficient <= -0.5)
                addingX = true;
        }

        if (addingY) {
            if (yCoefficient >= 0.75)
                addingY = false;
        }
        else {
            if (yCoefficient <= -0.75)
                addingY = true;
        }

        if (addingX) {
            xCoefficient += 0.25;
        }
        else {
            xCoefficient -= 0.25;
        }

        if (addingY) {
            yCoefficient += 0.25;
        }
        else {
            yCoefficient -= 0.25;
        }

        // qDebug() << "xCoeff " << xCoefficient;

        renderPlane();
    }
    clockCounter++;
    clockCounter %= NUM_CLOCKS_PER_BEAT / 6;
}
Exemple #7
0
void renderPlane(const struct aiNode *nd)
{
	aiMatrix4x4 m = nd->mTransformation;
	m.Transpose();

	GLfloat aux[16];
	memcpy(aux, &m, sizeof(GLfloat) * 16);

	mat4 matrix = mstack.top() * glm::make_mat4(aux);
	mstack.push(matrix);

	for (GLuint n = 0; n < nd->mNumMeshes; ++n) {
		GLuint index = nd->mMeshes[n];
		const aiMesh* mesh = scene->mMeshes[index];
		d_program.setUniform("ModelView", mstack.top());
		d_program.setUniform("Projection", pstack.top());
		d_program.setUniform("MVP", pstack.top() * mstack.top());
		d_program.setUniform("NormalMatrix", 
					glm::inverseTranspose(mat3(mstack.top()) * mat3(g_modelview)));

		if (mesh->mPrimitiveTypes == aiPrimitiveType_TRIANGLE) {			
			glBindVertexArray(vaos[index]);
			glDrawElements(GL_TRIANGLES, index_count[index], GL_UNSIGNED_INT, 0);
		} 
		else if (mesh->mPrimitiveTypes == aiPrimitiveType_POINT) {			
			glBindVertexArray(vaos[index]);
			glDrawElements(GL_POINTS, index_count[index], GL_UNSIGNED_INT, 0);
		}
		else if (mesh->mPrimitiveTypes == aiPrimitiveType_LINE) {			
			glBindVertexArray(vaos[index]);
			glDrawElements(GL_LINES, index_count[index], GL_UNSIGNED_INT, 0);
		} 
	}

	for (GLuint n = 0; n < nd->mNumChildren; ++n)
		renderPlane(nd->mChildren[n]);

	mstack.pop();
}
Exemple #8
0
void ViewWindow::onIdle(const float delta)
{
	if (NULL == getRenderContex())
	{
		return;
	}
	//
	if (!getRenderContex()->isInitialized())
	{
		getRenderContex()->setWaitForVBL(false);
		int index = 0;
		bool pf = false;
		for (int i = 0; i != getRenderContex()->getDevicesNumber(); ++i)
		{
			DeviceInfo di = getRenderContex()->getDeviceInfo(i);
			std::string dp(di.identifier_.Description);
			if (dp.find("PerfHUD") != std::string::npos)
			{
				index = i;
				pf = true;
				break;
			}
		}
		getRenderContex()->createDevice(m_hWnd, index, 0, true, true, Vector2::Zero);
		getGlobal()->create();
		camera_.setSpeed(5.0f);
		Vector3 minBound = -Vector3( 100.5f, 0.f, 100.5f );
		Vector3 maxBound = Vector3(10000, 5000.0f, 10000.0f);
		camera_.limit_ =  BoundingBox( minBound, maxBound );
		camera_.create(30, MATH_PI*0.75f, MATH_PI_Half*0.5f);
		//
		Camera c = getRenderContex()->getCamera();
		c.setFarPlane(10000.0f);
		getRenderContex()->setCamera(c);
		getRenderContex()->updateProjectionMatrix();
		getSceneManager()->setRunType(eRunType_Editor);
		getSceneManager()->setAllChunksVisible(true);
		//
		{
			font_ = FontManager::getPointer()->createFont(std::string("freetype\\LuYaHeiMb.TTF"), 18, eFontProperty_Normal, "freeNormal");
		}
	}
	//
	camera_.update(delta, 0.0f);
	getSceneManager()->update(delta);
	{
		getGlobal()->update(delta);
	}
	//
	getRenderContex()->setViewMatrix(camera_.view_);
	//
	u32 clearFlags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER;
	if ( getRenderContex()->isStencilAvailable() )
		clearFlags |= D3DCLEAR_STENCIL;
	static Vector4 scc(0.5f,0.5f,0.5f, 0.5f);
	getRenderContex()->getDxDevice()->Clear( 0, NULL, clearFlags, scc.getARGB(), 1, 0 );
	getRenderContex()->beginScene();
	//plane
	renderPlane();
	//axis
	renderAxisXYZ();
	//
	if (getSceneManager())
	{
		getSceneManager()->render();
		getGlobal()->render();
	}
	//屏幕字,最后画
	{
		std::ostringstream ss;
		ss<<"FPS = "<<_fps;
		font_->render(Vector2(10, 10), Vector4(1, 0, 0, 1), ss.str());
	}
	font_->render();
	getRenderContex()->endScene();
	getRenderContex()->present();
}
Exemple #9
0
int main( void )
{
	//init bullet
	initBullet();
	// Initialise GLFW
	if( !glfwInit() )
	{
		fprintf( stderr, "Failed to initialize GLFW\n" );
		return -1;
	}
	glfwWindowHint(GLFW_SAMPLES, 4);
//	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
//	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	//screen resolution GLFW
	const GLFWvidmode * mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
	int  w = mode->width;
	int  h = mode->height;

	if(MessageBox(NULL, L"Would you like to run in fullscreen?", L"Fullscreen", MB_ICONQUESTION | MB_YESNO) == IDYES) 
	{
		window = glfwCreateWindow( w, h, "Ray Tracing - Alfonso Oricchio", glfwGetPrimaryMonitor(), NULL);
		printf("fullscreen\n");
	}
	else
	{
		window = glfwCreateWindow( WINDOW_WIDTH, WINDOW_HEIGHT, "Ray Tracing - Alfonso Oricchio", NULL, NULL);
		printf("window\n");
	}
	// Open a window and create its OpenGL context
	
	if( window == NULL ){
		fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	// Initialize GLEW
	glewExperimental = true; // Needed for core profile
	if (glewInit() != GLEW_OK) {
		fprintf(stderr, "Failed to initialize GLEW\n");
		return -1;
	}

	// Ensure we can capture the escape key being pressed below
	glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
	glfwSetCursorPos(window, WINDOW_WIDTH/2, WINDOW_HEIGHT/2);

	// Dark blue background
	glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

	// Enable depth test
	glEnable(GL_DEPTH_TEST);
	// Accept fragment if it closer to the camera than the former one
	glDepthFunc(GL_LESS); 
	// Cull triangles which normal is not towards the camera
	//glEnable(GL_CULL_FACE);

	GLuint VertexArrayID;
	glGenVertexArrays(1, &VertexArrayID);
	glBindVertexArray(VertexArrayID);
	
		// Create and compile our GLSL program from the shaders
	GLuint depthProgramID = LoadShaders( "DepthRTT.vertexshader", "DepthRTT.fragmentshader" );

	// Get a handle for our "MVP" uniform
	GLuint depthMatrixID = glGetUniformLocation(depthProgramID, "depthMVP");
	
	// The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer.
	GLuint FramebufferName = 0;
	glGenFramebuffers(1, &FramebufferName);
	glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);

	// Depth texture. Slower than a depth buffer, but you can sample it later in your shader
	GLuint depthTexture;
	glGenTextures(1, &depthTexture);
	glBindTexture(GL_TEXTURE_2D, depthTexture);
	glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, 1024, 1024, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
		 
	glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0);

	// No color output in the bound framebuffer, only depth.
	glDrawBuffer(GL_NONE);

	// Always check that our framebuffer is ok
	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
		return false;
	/***********************************************************/
		// The quad's FBO. Used only for visualizing the shadowmap.
	static const GLfloat g_quad_vertex_buffer_data[] = { 
		-1.0f, -1.0f, 0.0f,
		 1.0f, -1.0f, 0.0f,
		-1.0f,  1.0f, 0.0f,
		-1.0f,  1.0f, 0.0f,
		 1.0f, -1.0f, 0.0f,
		 1.0f,  1.0f, 0.0f,
	};

	GLuint quad_vertexbuffer;
	glGenBuffers(1, &quad_vertexbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW);

	// Create and compile our GLSL program from the shaders
	GLuint quad_programID = LoadShaders( "Passthrough.vertexshader", "SimpleTexture.fragmentshader" );
	GLuint texID = glGetUniformLocation(quad_programID, "texture");
	/**********************************************************/


		// Create and compile our GLSL program from the shaders
	GLuint programID = LoadShaders( "TransformVertexShader.vertexshader", "ColorFragmentShader.fragmentshader" );



	// Get a handle for our "MVP" uniform
	GLuint MatrixID = glGetUniformLocation(programID, "MVP");
	GLuint ViewMatrixID = glGetUniformLocation(programID, "V");
	GLuint ModelMatrixID = glGetUniformLocation(programID, "M");
	GLuint DepthBiasID = glGetUniformLocation(programID, "DepthBiasMVP");
	GLuint ShadowMapID = glGetUniformLocation(programID, "shadowMap");
	
	// Get a handle for our "LightPosition" uniform
	GLuint lightInvDirID = glGetUniformLocation(programID, "LightInvDirection_worldspace");

	//CUBO1
	addBox(2,2,2,0,0,0,1.0);

	//CUBO2
	addBox2(2,2,2,0,6,0,1.0);
	//FLOOR
	initFloor();

	//WALL
	initWall();
	//BALL
	addScene();

	do{
		world->stepSimulation(1/60.f);
		if (glfwGetKey( window, GLFW_KEY_SPACE ) == GLFW_PRESS){
			btRigidBody* ball = addBall(1.0,CamGetPosition().x,CamGetPosition().y,CamGetPosition().z,2.0);
			ball->setLinearVelocity(btVector3((CamGetDirection().x*50),(CamGetDirection().y*50),(CamGetDirection().z*50)));	
		}
		// Render to our framebuffer
		glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
		glViewport(0,0,1024,1024); // Render on the whole framebuffer, complete from the lower left corner to the upper right

		// Clear the screen
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		//////////////////////////////
		// Use our shader
		//SHADOW RENDER
		glUseProgram(depthProgramID);

		glm::vec3 lightInvDir = glm::vec3(0.5f,2,2);

		// Compute the MVP matrix from the light's point of view
		glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20);
		glm::mat4 depthViewMatrix = glm::lookAt(lightInvDir, glm::vec3(0,0,0), glm::vec3(0,1,0));
		// or, for spot light :
		//glm::vec3 lightPos(5, 20, 20);
		//glm::mat4 depthProjectionMatrix = glm::perspective<float>(45.0f, 1.0f, 2.0f, 50.0f);
		//glm::mat4 depthViewMatrix = glm::lookAt(lightPos, lightPos-lightInvDir, glm::vec3(0,1,0));

		glm::mat4 depthModelMatrix = glm::mat4(1.0);
		glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix;

		// Send our transformation to the currently bound shader, 
		// in the "MVP" uniform
		glUniformMatrix4fv(depthMatrixID, 1, GL_FALSE, &depthMVP[0][0]);

		// CUBE1 -------------------------------------------------------------------------
		renderBox(bodies[0],true); //just a cube not really needed
		//CUBE2 --------------------------------------------------------------------------
		renderBox2(bodies[1],true); //just a cube not really needed
		//FLOOR --------------------------------------------------------------------------
		renderPlane(bodies[2],true); //floor 
		//WALL ---------------------------------------------------------------------------
		renderWall(bodies[3],true); //back wall
		//CASTLE -------------------------------------------------------------------------
		renderScene(true); //castle, main scene
		//BALL ---------------------------------------------------------------------------
		int iv;
		for(iv = 4; iv < bodies.size();iv++)
			{
				renderBall(bodies[iv],(iv - 4),true); //"cannon balls" shooted from the camera 
			}
		
		

		
		//////////////////////////////
		//STANDARD RENDER
		// Compute the MVP matrix from keyboard and mouse input
		// Clear the screen
		// Render to the screen
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glViewport(0,0,1024,768); // Render on the whole framebuffer, complete from the lower left corner to the upper right

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		
		// Use our shader
		glUseProgram(programID);

		computeMatricesFromInputs();
		glm::mat4 ProjectionMatrix = getProjectionMatrix();
		glm::mat4 ViewMatrix = getViewMatrix();
		glm::mat4 ModelMatrix = glm::mat4(1.0);
		glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;		
		
				
		glm::mat4 biasMatrix(
			0.5, 0.0, 0.0, 0.0, 
			0.0, 0.5, 0.0, 0.0,
			0.0, 0.0, 0.5, 0.0,
			0.5, 0.5, 0.5, 1.0
		);

		glm::mat4 depthBiasMVP = biasMatrix*depthMVP;

// Send our transformation to the currently bound shader, 
		// in the "MVP" uniform
		glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
		glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]);
		glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);
		glUniformMatrix4fv(DepthBiasID, 1, GL_FALSE, &depthBiasMVP[0][0]);

		glUniform3f(lightInvDirID, lightInvDir.x, lightInvDir.y, lightInvDir.z);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, depthTexture);
		glUniform1i(ShadowMapID, 0);

		// CUBE1 -------------------------------------------------------------------------
		renderBox(bodies[0],false); //just a cube not really needed
		//CUBE2 --------------------------------------------------------------------------
		renderBox2(bodies[1],false); //just a cube not really needed
		//FLOOR --------------------------------------------------------------------------
		renderPlane(bodies[2],false); //floor 
		//WALL ---------------------------------------------------------------------------
		renderWall(bodies[3],false); //back wall
		//CASTLE -------------------------------------------------------------------------
		renderScene(false); //castle, main scene
		//BALL ---------------------------------------------------------------------------
	//	int iv;
		for(iv = 4; iv < bodies.size();iv++)
			{ 
				renderBall(bodies[iv],(iv - 4),false); //"cannon balls" shooted from the camera 
			}
		
	/*--------------------------------------------------*/
	// Optionally render the shadowmap (for debug only)

		// Render only on a corner of the window (or we we won't see the real rendering...)
		glViewport(0,0,512,512);

		// Use our shader
		glUseProgram(quad_programID);

		// Bind our texture in Texture Unit 0
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, depthTexture);
		// Set our "renderedTexture" sampler to user Texture Unit 0
		glUniform1i(texID, 0);

		// 1rst attribute buffer : vertices
		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
		glVertexAttribPointer(
			0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
			3,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		// Draw the triangle !
		// You have to disable GL_COMPARE_R_TO_TEXTURE above in order to see anything !
		//glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles
		glDisableVertexAttribArray(0);

	/*--------------------------------------------------*/
		// Swap buffers
		glfwSwapBuffers(window);
		glfwPollEvents();

	} // Check if the ESC key was pressed or the window was closed
	while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
		   glfwWindowShouldClose(window) == 0 );



	deleteALL();
	glDeleteProgram(programID);
	glDeleteVertexArrays(1, &VertexArrayID);
	// Close OpenGL window and terminate GLFW
	glfwTerminate();

	return 0;
}
Planes::Planes(const char* config_file_name,unsigned int plane_number):plane_number(plane_number)
{
    ConfigFile config_file;

    plane_enabled.resize(plane_number);
    plane_bounce.resize(plane_number);
    plane_center.resize(plane_number);
    plane_normal.resize(plane_number);
    plane_size.resize(plane_number);
    plane_color.resize(plane_number);
    plane_ambient.resize(plane_number);
    plane_diffuse.resize(plane_number);
    plane_specular.resize(plane_number);
    plane_shininess.resize(plane_number);

    for(int plane_index=0;plane_index<plane_number;++plane_index)
    {
	char option_name[128];
	char plane_index_ch='0'+plane_index;

	sprintf(option_name,"planeEnabled_%c",plane_index_ch);
	config_file.addOption(option_name,&plane_enabled[plane_index]);
	sprintf(option_name,"planeBounce_%c",plane_index_ch);
	config_file.addOption(option_name,&plane_bounce[plane_index]);
	sprintf(option_name,"planeCenter_%c_X",plane_index_ch);
	config_file.addOption(option_name,&plane_center[plane_index][0]);
	sprintf(option_name,"planeCenter_%c_Y",plane_index_ch);
	config_file.addOption(option_name,&plane_center[plane_index][1]);
	sprintf(option_name,"planeCenter_%c_Z",plane_index_ch);
	config_file.addOption(option_name,&plane_center[plane_index][2]);
	sprintf(option_name,"planeNormal_%c_X",plane_index_ch);
	config_file.addOption(option_name,&plane_normal[plane_index][0]);
	sprintf(option_name,"planeNormal_%c_Y",plane_index_ch);
	config_file.addOption(option_name,&plane_normal[plane_index][1]);
	sprintf(option_name,"planeNormal_%c_Z",plane_index_ch);
	config_file.addOption(option_name,&plane_normal[plane_index][2]);
	sprintf(option_name,"planeSize_%c",plane_index_ch);
	config_file.addOption(option_name,&plane_size[plane_index]);
	sprintf(option_name,"planeColor_%c_X",plane_index_ch);
	config_file.addOption(option_name,&plane_color[plane_index][0]);
	sprintf(option_name,"planeColor_%c_Y",plane_index_ch);
	config_file.addOption(option_name,&plane_color[plane_index][1]);
	sprintf(option_name,"planeColor_%c_Z",plane_index_ch);
	config_file.addOption(option_name,&plane_color[plane_index][2]);
	sprintf(option_name,"planeAmbient_%c",plane_index_ch);
	config_file.addOption(option_name,&plane_ambient[plane_index]);
	sprintf(option_name,"planeDiffuse_%c",plane_index_ch);
	config_file.addOption(option_name,&plane_diffuse[plane_index]);
	sprintf(option_name,"planeSpecular_%c",plane_index_ch);
	config_file.addOption(option_name,&plane_specular[plane_index]);
	sprintf(option_name,"planeShininess_%c",plane_index_ch);
	config_file.addOption(option_name,&plane_shininess[plane_index]);
    }
    printf("Parsing planes from %s...\n",config_file_name);
    if(config_file.parseOptions(config_file_name)!=0)
	   throw 1;
    config_file.printOptions();
    //build display list for the enabled planes
    displaylist_index=glGenLists(1);
    if(displaylist_index!=0)
    {
    	glNewList(displaylist_index,GL_COMPILE);
    	for(int plane_index=0;plane_index<plane_number;++plane_index)
    	{
    	    if(plane_enabled[plane_index])
    		renderPlane(plane_index);
    	}
    	glEndList();
    }
    else
	   printf("Warning: Failed to create display list for planes.\n");
}