示例#1
0
///////////////////////////////////////////////////////////////////////////////////////////////////
// Calculate the tangent basis for a triangle on the surface of a model
// This vector is needed for most normal mapping shaders 
void m3dCalculateTangentBasis(M3DVector3f vTangent, const M3DVector3f vTriangle[3], const M3DVector2f vTexCoords[3], const M3DVector3f N)
{
	M3DVector3f dv2v1, dv3v1;
	float dc2c1t, dc2c1b, dc3c1t, dc3c1b;
	float M;
	
	m3dSubtractVectors3(dv2v1, vTriangle[1], vTriangle[0]);
	m3dSubtractVectors3(dv3v1, vTriangle[2], vTriangle[0]);
	
	dc2c1t = vTexCoords[1][0] - vTexCoords[0][0];
	dc2c1b = vTexCoords[1][1] - vTexCoords[0][1];
	dc3c1t = vTexCoords[2][0] - vTexCoords[0][0];
	dc3c1b = vTexCoords[2][1] - vTexCoords[0][1];
	
	M = (dc2c1t * dc3c1b) - (dc3c1t * dc2c1b);
	M = 1.0f / M;
	
	m3dScaleVector3(dv2v1, dc3c1b);
	m3dScaleVector3(dv3v1, dc2c1b);
	
	m3dSubtractVectors3(vTangent, dv2v1, dv3v1);
	m3dScaleVector3(vTangent, M);  // This potentially changes the direction of the vector
	m3dNormalizeVector3(vTangent);

	M3DVector3f B;
	m3dCrossProduct3(B, N, vTangent);
	m3dCrossProduct3(vTangent, B, N);
	m3dNormalizeVector3(vTangent);
	}
示例#2
0
/////////////////////////////////////////////////////////////////
// Add a triangle to the mesh. This searches the current list for identical
// (well, almost identical - these are floats you know...) verts. If one is found, it
// is added to the index array. If not, it is added to both the index array and the vertex
// array grows by one as well.
void GLTriangleBatch::AddTriangle(M3DVector3f verts[3], M3DVector3f vNorms[3], M3DVector2f vTexCoords[3])
    {
    const  float e = 0.00001f; // How small a difference to equate

    // First thing we do is make sure the normals are unit length!
    // It's almost always a good idea to work with pre-normalized normals
    m3dNormalizeVector3(vNorms[0]);
    m3dNormalizeVector3(vNorms[1]);
    m3dNormalizeVector3(vNorms[2]);


    // Search for match - triangle consists of three verts
    for(GLuint iVertex = 0; iVertex < 3; iVertex++)
        {
        GLuint iMatch = 0;
        for(iMatch = 0; iMatch < nNumVerts; iMatch++)
            {
            // If the vertex positions are the same
            if(m3dCloseEnough(pVerts[iMatch][0], verts[iVertex][0], e) &&
               m3dCloseEnough(pVerts[iMatch][1], verts[iVertex][1], e) &&
               m3dCloseEnough(pVerts[iMatch][2], verts[iVertex][2], e) &&
                   
               // AND the Normal is the same...
               m3dCloseEnough(pNorms[iMatch][0], vNorms[iVertex][0], e) &&
               m3dCloseEnough(pNorms[iMatch][1], vNorms[iVertex][1], e) &&
               m3dCloseEnough(pNorms[iMatch][2], vNorms[iVertex][2], e) &&
                   
                // And Texture is the same...
                m3dCloseEnough(pTexCoords[iMatch][0], vTexCoords[iVertex][0], e) &&
                m3dCloseEnough(pTexCoords[iMatch][1], vTexCoords[iVertex][1], e))
                {
                // Then add the index only
                pIndexes[nNumIndexes] = iMatch;
                nNumIndexes++;
                break;
                }
            }
            
        // No match for this vertex, add to end of list
        if(iMatch == nNumVerts && nNumVerts < nMaxIndexes && nNumIndexes < nMaxIndexes)
            {
            memcpy(pVerts[nNumVerts], verts[iVertex], sizeof(M3DVector3f));
            memcpy(pNorms[nNumVerts], vNorms[iVertex], sizeof(M3DVector3f));
            memcpy(pTexCoords[nNumVerts], vTexCoords[iVertex], sizeof(M3DVector2f));
            pIndexes[nNumIndexes] = nNumVerts;
            nNumIndexes++; 
            nNumVerts++;
            }   
        }
    }
示例#3
0
void normal(float result[], const float A[], const float B[], const float C[]) {
   float C_min_B[3], A_min_B[3];
   m3dSubtractVectors3(C_min_B, C, B);
   m3dSubtractVectors3(A_min_B, A, B);
   m3dCrossProduct3(result, C_min_B, A_min_B);
   m3dNormalizeVector3(result);
}
示例#4
0
文件: main.cpp 项目: diunao/procesory
void draw_icosahedron_smooth(int n_faces, float *vertices, int *faces) {
   float normal[3];
   for(int i = 0; i < n_faces; ++i) {
      for(int j=0 ; j < 3 ; ++j) {
         m3dCopyVector3(normal, vertices + 3 * faces[i * 3 + j]);
         m3dNormalizeVector3(normal);
         draw_trinagle_face(vertices + 3 * faces[3 * i], vertices + 3 * faces[3 * i + 1], vertices + 3 * faces[3 * i + 2], normal, 0.0f, 1.0f, 0.0f);
      }
   }
}
示例#5
0
//----------------------------------------------------
void TriangleFace(M3DVector3f a, M3DVector3f b, M3DVector3f c) {
   M3DVector3f normal, bMa, cMa;
   m3dSubtractVectors3(bMa, b, a);
   m3dSubtractVectors3(cMa, c, a);
   m3dCrossProduct3(normal, bMa, cMa);
   m3dNormalizeVector3(normal);
   glVertexAttrib3fv(GLT_ATTRIBUTE_NORMAL, normal);
   glVertex3fv(a);
   glVertex3fv(b);
   glVertex3fv(c);
}
示例#6
0
文件: main.cpp 项目: wdlove58/WcgCube
void MouseMoveEvent(int x, int y)
{

	if (isStartTrackBall)
	{
		GLfloat theta;
		M3DVector3f p1, p2, n;
		int width = glutGet(GLUT_WINDOW_WIDTH);
		int height = glutGet(GLUT_WINDOW_HEIGHT);

		MousePtToSphereVec(p1, mMouseX, mMouseY, width, height);
		MousePtToSphereVec(p2, x, y, width, height);

		mMouseX = x;
		mMouseY = y;

		m3dNormalizeVector3(p1);
		m3dNormalizeVector3(p2);
		theta = acos(m3dDotProduct3(p1, p2)) ;

		//theta = m3dGetAngleBetweenVectors3(p1, p2);

		m3dCrossProduct3(n, p1, p2);
		m3dNormalizeVector3(n);

		M3DMatrix44f tempRotation;
		m3dLoadIdentity44(tempRotation);
		GLfloat dis = m3dGetDistance3(p1, p2);
		if (dis != 0.0f)
		{
			m3dRotationMatrix44(tempRotation, theta, m3dGetVectorX(n), m3dGetVectorY(n), m3dGetVectorZ(n));
		}
		m3dMatrixMultiply44(mRotation, tempRotation, mRotation);

		glutPostRedisplay();

		
	}
	
}
示例#7
0
//----------------------------------------------------
void drawSmoothTriangles(int n_faces, float *vertices, int *faces) {
    M3DVector3f normal;
    for (int i = 0; i < n_faces; i++) {
		glBegin(GL_TRIANGLES);
    	for(int j=0;j<3;++j) {
			m3dCopyVector3(normal,vertices+3*faces[i*3+j]);
			m3dNormalizeVector3(normal);
    		glVertexAttrib3fv(GLT_ATTRIBUTE_NORMAL, normal);
    		glVertex3fv(vertices+3*faces[i*3+j]);
		}
    glEnd();
    }
}
void Camerak::moveBackward()
{
	
	M3DVector3f temp;
	Vec3 thisMove;
	cam.GetOrigin(temp);
	lastPos.fromM3D(temp);
	cam.GetForwardVector(temp);
	temp[1] = 0;
	m3dNormalizeVector3(temp);
	thisMove.fromM3D(temp);
	thisMove*= movement_rate;
	move-=thisMove;
	
}
示例#9
0
// Ditto above, but for doubles
void m3dGetPlaneEquation(M3DVector4d planeEq, const M3DVector3d p1, const M3DVector3d p2, const M3DVector3d p3)
{
	// Get two vectors... do the cross product
	M3DVector3d v1, v2;

	// V1 = p3 - p1
	v1[0] = p3[0] - p1[0];
	v1[1] = p3[1] - p1[1];
	v1[2] = p3[2] - p1[2];

	// V2 = P2 - p1
	v2[0] = p2[0] - p1[0];
	v2[1] = p2[1] - p1[1];
	v2[2] = p2[2] - p1[2];

	// Unit normal to plane - Not sure which is the best way here
	m3dCrossProduct3(planeEq, v1, v2);
	m3dNormalizeVector3(planeEq);
	// Back substitute to get D
	planeEq[3] = -(planeEq[0] * p3[0] + planeEq[1] * p3[1] + planeEq[2] * p3[2]);
}
示例#10
0
// Draw a cylinder. Much like gluCylinder
void gltMakeCylinder(GLTriangleBatch& cylinderBatch, GLfloat baseRadius, GLfloat topRadius, 
			GLfloat fLength, GLint numSlices, GLint numStacks)
	{	
    float fRadiusStep = (topRadius - baseRadius) / float(numStacks);

	GLfloat fStepSizeSlice = (3.1415926536f * 2.0f) / float(numSlices);

	M3DVector3f vVertex[4];
	M3DVector3f vNormal[4];
	M3DVector2f vTexture[4];

    cylinderBatch.BeginMesh(numSlices * numStacks * 6);

    GLfloat ds = 1.0f / float(numSlices);
	GLfloat dt = 1.0f / float(numStacks);
	GLfloat s;
	GLfloat t;

	for (int i = 0; i < numStacks; i++) 
		{
		if(i == 0)			
			t = 0.0f;
		else
			t = float(i) * dt;

		float tNext;
		if(i == (numStacks - 1))
			tNext = 1.0f;
		else
			tNext = float(i+1) * dt;
	
		float fCurrentRadius = baseRadius + (fRadiusStep * float(i));
		float fNextRadius = baseRadius + (fRadiusStep * float(i+1));
		float theyta;
		float theytaNext;

		float fCurrentZ = float(i) * (fLength / float(numStacks)); 
		float fNextZ = float(i+1) * (fLength / float(numStacks));
		
		float zNormal = 0.0f;
		if(!m3dCloseEnough(baseRadius - topRadius, 0.0f, 0.00001f))
			{
			// Rise over run...
			zNormal = (baseRadius - topRadius);
			}
		
		for (int j = 0; j < numSlices; j++) 
			{		
			if(j == 0)
				s = 0.0f;
			else
				s = float(j) * ds;

			float sNext;
			if(j == (numSlices -1))
				sNext = 1.0f;
			else
				sNext = float(j+1) * ds;

			theyta = fStepSizeSlice * float(j);
			if(j == (numSlices - 1))
				theytaNext = 0.0f;
			else
				theytaNext = fStepSizeSlice * (float(j+1));
				
			// Inner First
			vVertex[1][0] = cos(theyta) * fCurrentRadius;	// X	
			vVertex[1][1] = sin(theyta) * fCurrentRadius;	// Y
			vVertex[1][2] = fCurrentZ;						// Z
			
			vNormal[1][0] = vVertex[1][0];					// Surface Normal, same for everybody
			vNormal[1][1] = vVertex[1][1];
			vNormal[1][2] = zNormal;
			m3dNormalizeVector3(vNormal[1]);
			
			vTexture[1][0] = s;					// Texture Coordinates, I have no idea...
			vTexture[1][1] = t;
	
			// Outer First
			vVertex[0][0] = cos(theyta) * fNextRadius;	// X	
			vVertex[0][1] = sin(theyta) * fNextRadius;	// Y
			vVertex[0][2] = fNextZ;						// Z
			
			if(!m3dCloseEnough(fNextRadius, 0.0f, 0.00001f)) {
				vNormal[0][0] = vVertex[0][0];					// Surface Normal, same for everybody
				vNormal[0][1] = vVertex[0][1];					// For cones, tip is tricky
				vNormal[0][2] = zNormal;
				m3dNormalizeVector3(vNormal[0]);
				}
			else
				memcpy(vNormal[0], vNormal[1], sizeof(M3DVector3f));
		
			
			vTexture[0][0] = s;					// Texture Coordinates, I have no idea...
			vTexture[0][1] = tNext;
			
			// Inner second
			vVertex[3][0] = cos(theytaNext) * fCurrentRadius;	// X	
			vVertex[3][1] = sin(theytaNext) * fCurrentRadius;	// Y
			vVertex[3][2] = fCurrentZ;						// Z
			
			vNormal[3][0] = vVertex[3][0];					// Surface Normal, same for everybody
			vNormal[3][1] = vVertex[3][1];
			vNormal[3][2] = zNormal;
			m3dNormalizeVector3(vNormal[3]);

			vTexture[3][0] = sNext;					// Texture Coordinates, I have no idea...
			vTexture[3][1] = t;

			// Outer second
			vVertex[2][0] = cos(theytaNext) * fNextRadius;	// X	
			vVertex[2][1] = sin(theytaNext) * fNextRadius;	// Y
			vVertex[2][2] = fNextZ;						// Z
			
			if(!m3dCloseEnough(fNextRadius, 0.0f, 0.00001f)) {
				vNormal[2][0] = vVertex[2][0];					// Surface Normal, same for everybody
				vNormal[2][1] = vVertex[2][1];
				vNormal[2][2] = zNormal;
				m3dNormalizeVector3(vNormal[2]);
				}
			else
				memcpy(vNormal[2], vNormal[3], sizeof(M3DVector3f));
				

			vTexture[2][0] = sNext;					// Texture Coordinates, I have no idea...
			vTexture[2][1] = tNext;
		
			cylinderBatch.AddTriangle(vVertex, vNormal, vTexture);			
			
			// Rearrange for next triangle
			memcpy(vVertex[0], vVertex[1], sizeof(M3DVector3f));
			memcpy(vNormal[0], vNormal[1], sizeof(M3DVector3f));
			memcpy(vTexture[0], vTexture[1], sizeof(M3DVector2f));
			
			memcpy(vVertex[1], vVertex[3], sizeof(M3DVector3f));
			memcpy(vNormal[1], vNormal[3], sizeof(M3DVector3f));
			memcpy(vTexture[1], vTexture[3], sizeof(M3DVector2f));
					
			cylinderBatch.AddTriangle(vVertex, vNormal, vTexture);			
			}
        }
	cylinderBatch.End();
	}
示例#11
0
// Draw a torus (doughnut)  at z = fZVal... torus is in xy plane
void gltMakeTorus(GLTriangleBatch& torusBatch, GLfloat majorRadius, GLfloat minorRadius, GLint numMajor, GLint numMinor)
	{
    double majorStep = 2.0f*M3D_PI / numMajor;
    double minorStep = 2.0f*M3D_PI / numMinor;
    int i, j;
	
    torusBatch.BeginMesh(numMajor * (numMinor+1) * 6);
    for (i=0; i<numMajor; ++i) 
		{
		double a0 = i * majorStep;
		double a1 = a0 + majorStep;
		GLfloat x0 = (GLfloat) cos(a0);
		GLfloat y0 = (GLfloat) sin(a0);
		GLfloat x1 = (GLfloat) cos(a1);
		GLfloat y1 = (GLfloat) sin(a1);

		M3DVector3f vVertex[4];
		M3DVector3f vNormal[4];
		M3DVector2f vTexture[4];
		
		for (j=0; j<=numMinor; ++j) 
			{
			double b = j * minorStep;
			GLfloat c = (GLfloat) cos(b);
			GLfloat r = minorRadius * c + majorRadius;
			GLfloat z = minorRadius * (GLfloat) sin(b);
			
			// First point
			vTexture[0][0] = (float)(i)/(float)(numMajor);
			vTexture[0][1] = (float)(j)/(float)(numMinor);
			vNormal[0][0] = x0*c;
			vNormal[0][1] = y0*c;
			vNormal[0][2] = z/minorRadius;
			m3dNormalizeVector3(vNormal[0]);
			vVertex[0][0] = x0 * r;
			vVertex[0][1] = y0 * r;
			vVertex[0][2] = z;
			
			// Second point
			vTexture[1][0] = (float)(i+1)/(float)(numMajor);
			vTexture[1][1] = (float)(j)/(float)(numMinor);
			vNormal[1][0] = x1*c;
			vNormal[1][1] = y1*c;
			vNormal[1][2] = z/minorRadius;
			m3dNormalizeVector3(vNormal[1]);
			vVertex[1][0] = x1*r;
			vVertex[1][1] = y1*r;
			vVertex[1][2] = z;

			// Next one over
			b = (j+1) * minorStep;
			c = (GLfloat) cos(b);
			r = minorRadius * c + majorRadius;
			z = minorRadius * (GLfloat) sin(b);
						
			// Third (based on first)
			vTexture[2][0] = (float)(i)/(float)(numMajor);
			vTexture[2][1] = (float)(j+1)/(float)(numMinor);
			vNormal[2][0] = x0*c;
			vNormal[2][1] = y0*c;
			vNormal[2][2] = z/minorRadius;
			m3dNormalizeVector3(vNormal[2]);
			vVertex[2][0] = x0 * r;
			vVertex[2][1] = y0 * r;
			vVertex[2][2] = z;
			
			// Fourth (based on second)
			vTexture[3][0] = (float)(i+1)/(float)(numMajor);
			vTexture[3][1] = (float)(j+1)/(float)(numMinor);
			vNormal[3][0] = x1*c;
			vNormal[3][1] = y1*c;
			vNormal[3][2] = z/minorRadius;
			m3dNormalizeVector3(vNormal[3]);
			vVertex[3][0] = x1*r;
			vVertex[3][1] = y1*r;
			vVertex[3][2] = z;

			torusBatch.AddTriangle(vVertex, vNormal, vTexture);			
			
			// Rearrange for next triangle
			memcpy(vVertex[0], vVertex[1], sizeof(M3DVector3f));
			memcpy(vNormal[0], vNormal[1], sizeof(M3DVector3f));
			memcpy(vTexture[0], vTexture[1], sizeof(M3DVector2f));
			
			memcpy(vVertex[1], vVertex[3], sizeof(M3DVector3f));
			memcpy(vNormal[1], vNormal[3], sizeof(M3DVector3f));
			memcpy(vTexture[1], vTexture[3], sizeof(M3DVector2f));
					
			torusBatch.AddTriangle(vVertex, vNormal, vTexture);			
			}
		}
	torusBatch.End();
	}
示例#12
0
///////////////////////////////////////////////////////////////////////////////
// Render a frame. The owning framework is responsible for buffer swaps,
// flushes, etc.
void RenderScene(void)
{
    static CStopWatch animationTimer;
    float yRot = animationTimer.GetElapsedSeconds() * 60.0f;
    
    M3DVector3f vCameraPos;
    M3DVector3f vCameraForward;
    M3DVector3f vMirrorPos;
    M3DVector3f vMirrorForward;
    cameraFrame.GetOrigin(vCameraPos);
    cameraFrame.GetForwardVector(vCameraForward);
    
    // Set position of mirror frame (camera)
    vMirrorPos[0] = 0.0;
    vMirrorPos[1] = 0.1f;
    vMirrorPos[2] = -6.0f; // view pos is actually behind mirror
    mirrorFrame.SetOrigin(vMirrorPos);
    
    // Calculate direction of mirror frame (camera)
    // Because the position of the mirror is known relative to the origin
    // find the direction vector by adding the mirror offset to the vector
    // of the viewer-origin
    vMirrorForward[0] = vCameraPos[0];
    vMirrorForward[1] = vCameraPos[1];
    vMirrorForward[2] = (vCameraPos[2] + 5);
    m3dNormalizeVector3(vMirrorForward);
    mirrorFrame.SetForwardVector(vMirrorForward);
    
    // first render from the mirrors perspective
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboName);
    glDrawBuffers(1, fboBuffs);
    glViewport(0, 0, mirrorTexWidth, mirrorTexHeight);
    
    // Draw scene from the perspective of the mirror camera
    modelViewMatrix.PushMatrix();
    M3DMatrix44f mMirrorView;
    mirrorFrame.GetCameraMatrix(mMirrorView);
    modelViewMatrix.MultMatrix(mMirrorView);
    
    // Flip the mirror camera horizontally for the reflection
    modelViewMatrix.Scale(-1.0f, 1.0f, 1.0f);
    
    glBindTexture(GL_TEXTURE_2D, textures[0]); // Marble
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE, transformPipeline.GetModelViewProjectionMatrix(), vWhite, 0);
    floorBatch.Draw();
    DrawWorld(yRot);
    
    // Now draw a cylinder representing the viewer
    M3DVector4f vLightTransformed;
    modelViewMatrix.GetMatrix(mMirrorView);
    m3dTransformVector4(vLightTransformed, vLightPos, mMirrorView);
    modelViewMatrix.Translate(vCameraPos[0],vCameraPos[1]-0.8f,vCameraPos[2]-1.0f);
    modelViewMatrix.Rotate(-90.0f, 1.0f, 0.0f, 0.0f);
    
    shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF,
                                 modelViewMatrix.GetMatrix(),
                                 transformPipeline.GetProjectionMatrix(),
                                 vLightTransformed, vBlue, 0);
    cylinderBatch.Draw();
    modelViewMatrix.PopMatrix();
    
    // Reset FBO. Draw world again from the real cameras perspective
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glDrawBuffers(1, windowBuff);
    glViewport(0, 0, screenWidth, screenHeight);
    modelViewMatrix.PushMatrix();
    M3DMatrix44f mCamera;
    cameraFrame.GetCameraMatrix(mCamera);
    modelViewMatrix.MultMatrix(mCamera);
    
    glBindTexture(GL_TEXTURE_2D, textures[0]); // Marble
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE, transformPipeline.GetModelViewProjectionMatrix(), vWhite, 0);
    
    floorBatch.Draw();
    DrawWorld(yRot);
    
    // Now draw the mirror surfaces
    modelViewMatrix.PushMatrix();
    modelViewMatrix.Translate(0.0f, -0.4f, -5.0f);
    if(vCameraPos[2] > -5.0)
    {
        glBindTexture(GL_TEXTURE_2D, mirrorTexture); // Reflection
        shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE, transformPipeline.GetModelViewProjectionMatrix(), 0);
    }
    else
    {
        // If the camera is behind the mirror, just draw black
        shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
    }
    mirrorBatch.Draw();
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vGrey);
    mirrorBorderBatch.Draw();
    modelViewMatrix.PopMatrix();
    modelViewMatrix.PopMatrix();
    
    // Do the buffer Swap
    glutSwapBuffers();
    
    // Do it again
    glutPostRedisplay();
}
示例#13
0
void Display()
{
    static CStopWatch timer;
    GLfloat yRot = timer.GetElapsedSeconds() * 60.0;

    M3DVector3f vCameraPosition;
    M3DVector3f vCameraForward;
    M3DVector3f vMirrorPosition;
    M3DVector3f vMirrorForward;
    void movingCylinder();

    cameraFrame.GetOrigin(vCameraPosition);
    cameraFrame.GetForwardVector(vCameraForward);

    vMirrorPosition[0] = 0.0f;
    vMirrorPosition[1] = 0.1f;
    vMirrorPosition[2] = -20.0f;
    mirrorFrame.SetOrigin(vMirrorPosition);

    vMirrorForward[0] = vCameraPosition[0];
    vMirrorForward[1] = vCameraPosition[1];
    vMirrorForward[2] = (vCameraPosition[2] + 20);
    m3dNormalizeVector3(vMirrorForward);
    mirrorFrame.SetForwardVector(vMirrorForward);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER,fboName);
    glDrawBuffers(1,fboBuffers);
    glViewport(0,0,mirrorWidth,mirrorHeight);

    modelViewMatrix.PushMatrix();
    M3DMatrix44f mMirrorView;
    mirrorFrame.GetCameraMatrix(mMirrorView);
    modelViewMatrix.MultMatrix(mMirrorView);
    modelViewMatrix.Scale(-1.0f,1.0f,1.0f);
    glBindTexture(GL_TEXTURE_2D,textures[0]);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE,
                                 transformPipeline.GetModelViewProjectionMatrix(),
                                 vWhite,0);
    floorBatch.Draw();

    drawSun();
    drawTorus(yRot);
    modelViewMatrix.PopMatrix();

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);
    glDrawBuffers(1,windowBuffer);
    glViewport(0,0,mirrorWidth,mirrorHeight);

    modelViewMatrix.PushMatrix();
    M3DMatrix44f mCamera;
    cameraFrame.GetCameraMatrix(mCamera);
    modelViewMatrix.MultMatrix(mCamera);

    modelViewMatrix.PushMatrix();
    glBindTexture(GL_TEXTURE_2D,mirrorTexture);
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE,
                                 transformPipeline.GetModelViewProjectionMatrix(),0);
    mirrorFrontBatch.Draw();
    modelViewMatrix.PopMatrix();
    modelViewMatrix.PushMatrix();
    glBindTexture(GL_TEXTURE_2D,textures[0]);
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE,
                                 transformPipeline.GetModelViewProjectionMatrix(),
                                 vWhite,0);
    floorBatch.Draw();

    drawSun();
    drawTorus(yRot);
    modelViewMatrix.PopMatrix();
    modelViewMatrix.PopMatrix();


    //control to moving cylinder
    movingCylinder();

    glutSwapBuffers();
    glutPostRedisplay();
}