示例#1
0
void CMirror::drawMirrorImage(void (*drawScene)(), const CLighting& lighting)
{
	glClear(GL_STENCIL_BUFFER_BIT);
	if (showMirror)
	{
		// Don't update color or depth.
		glDisable(GL_DEPTH_TEST);
		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
		// Draw 1 into the stencil buffer.
		glEnable(GL_STENCIL_TEST);
		glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
		glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
		// Now render mirror; mirror pixels just get their stencil set to 1. 
		glEnable(GL_CULL_FACE);
		drawMirror(MIRROR_FRONT);
		glDisable(GL_CULL_FACE);
		// Re-enable update of color and depth. 
		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
		glEnable(GL_DEPTH_TEST);
		// Now, only render where stencil is set to 1. 
		glStencilFunc(GL_EQUAL, 1, 0xffffffff);  // draw if ==1 	
		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
		
		glPushMatrix();
		applyReflectionMatrix();
		lighting.init();		// mirror light sources
		drawScene();			// render the reflected scene
 		glPopMatrix();
		glDisable(GL_STENCIL_TEST);
		lighting.init();		// back to the original light sources
	
		// Back face culling will get used to only draw either the front side or the
		// back side of the mirror.  This let's us get a mirror with two distinct
		// appearances.  The front surface is reflective and kind of grayish.
		// The back surface is not reflective and blue.
		
		// Draw "back" of mirror in blue. 
		glColor4f(0.1f, 0.1f, 0.5f, 1.0f);
		glEnable(GL_CULL_FACE);
		glCullFace(GL_FRONT);
		drawMirror(MIRROR_BACK);
		glCullFace(GL_BACK);
		glDisable(GL_CULL_FACE);

		// Draw the mirror with stencil value 3.  
		glEnable(GL_STENCIL_TEST);
		glStencilFunc(GL_ALWAYS, 3, 0xffffffff);
		glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
		// Draw reflective side of mirror.  Use blending to blend in reflection.
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glColor4f(0.9, 0.9, 0.9, 0.3);
		glCullFace(GL_BACK);
   		drawMirror(MIRROR_FRONT);
		glDisable(GL_BLEND);
		drawMirror(MIRROR_BOUNDARY);	
	}
}
示例#2
0
void MirrorDemo::drawScene()
{
	// Clear the backbuffer and depth buffer.
	HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER |
		D3DCLEAR_STENCIL, 0xffeeeeee, 1.0f, 0));

	HR(gd3dDevice->BeginScene());

	HR(mFX->SetTechnique(mhTech));
	HR(mFX->SetValue(mhLightVecW, &mLightVecW, sizeof(D3DXVECTOR3)));
	HR(mFX->SetValue(mhDiffuseLight, &mDiffuseLight, sizeof(D3DXCOLOR)));
	HR(mFX->SetValue(mhAmbientLight, &mAmbientLight, sizeof(D3DXCOLOR)));
	HR(mFX->SetValue(mhSpecularLight, &mSpecularLight, sizeof(D3DXCOLOR)));

	// All objects use the same material.
	HR(mFX->SetValue(mhAmbientMtrl, &mWhiteMtrl.ambient, sizeof(D3DXCOLOR)));
	HR(mFX->SetValue(mhDiffuseMtrl, &mWhiteMtrl.diffuse, sizeof(D3DXCOLOR)));
	HR(mFX->SetValue(mhSpecularMtrl, &mWhiteMtrl.spec, sizeof(D3DXCOLOR)));
	HR(mFX->SetFloat(mhSpecularPower, mWhiteMtrl.specPower));

	drawRoom();
	drawMirror();
	drawTeapot();

	drawReflectedTeapot();

	mGfxStats->display();

	HR(gd3dDevice->EndScene());

	// Present the backbuffer.
	HR(gd3dDevice->Present(0, 0, 0, 0));
}
示例#3
0
void MirrorDemo::drawReflectedTeapot()
{
	HR(gd3dDevice->SetRenderState(D3DRS_STENCILENABLE,    true));
	HR(gd3dDevice->SetRenderState(D3DRS_STENCILFUNC,      D3DCMP_ALWAYS));
	HR(gd3dDevice->SetRenderState(D3DRS_STENCILREF,       0x1));
	HR(gd3dDevice->SetRenderState(D3DRS_STENCILMASK,      0xffffffff));
	HR(gd3dDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff));
	HR(gd3dDevice->SetRenderState(D3DRS_STENCILZFAIL,     D3DSTENCILOP_KEEP));
	HR(gd3dDevice->SetRenderState(D3DRS_STENCILFAIL,      D3DSTENCILOP_KEEP));
	HR(gd3dDevice->SetRenderState(D3DRS_STENCILPASS,      D3DSTENCILOP_REPLACE));

	// Disable writes to the depth and back buffers
	HR(gd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, false));
	HR(gd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true));
	HR(gd3dDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ZERO));
	HR(gd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE));

	// Draw mirror to stencil only.
	drawMirror();

	// Re-enable depth writes
	HR(gd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, true ));

	// Only draw reflected teapot to the pixels where the mirror
	// was drawn to.
	HR(gd3dDevice->SetRenderState(D3DRS_STENCILFUNC,  D3DCMP_EQUAL));
	HR(gd3dDevice->SetRenderState(D3DRS_STENCILPASS,  D3DSTENCILOP_KEEP));

	// Build Reflection transformation.
	D3DXMATRIX R;
	D3DXPLANE plane(0.0f, 0.0f, 1.0f, 0.0f); // xy plane
	D3DXMatrixReflect(&R, &plane);

	// Save the original teapot world matrix.
	D3DXMATRIX oldTeapotWorld = mTeapotWorld;

	// Add reflection transform.
	mTeapotWorld = mTeapotWorld * R;

	// Reflect light vector also.
	D3DXVECTOR3 oldLightVecW = mLightVecW;
	D3DXVec3TransformNormal(&mLightVecW, &mLightVecW, &R);
	HR(mFX->SetValue(mhLightVecW, &mLightVecW, sizeof(D3DXVECTOR3)));

	// Disable depth buffer and render the reflected teapot.
	HR(gd3dDevice->SetRenderState(D3DRS_ZENABLE, false));
	HR(gd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false));

	// Finally, draw the reflected teapot
	HR(gd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW));
	drawTeapot();
	mTeapotWorld = oldTeapotWorld;
	mLightVecW   = oldLightVecW;

	// Restore render states.
	HR(gd3dDevice->SetRenderState(D3DRS_ZENABLE, true));
	HR(gd3dDevice->SetRenderState( D3DRS_STENCILENABLE, false));
	HR(gd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW));
}
示例#4
0
void Application::drawScene() {

	GLenum err;

	glViewport(0, 0, 2048, 2048);
	glBindFramebuffer(GL_FRAMEBUFFER, fbo);

	float back_color[] = { 1, 1, 1, 1 };
	float zero[]       = { 0.0f, 0.0f, 0.0f, -10.0f };
	float one          = 1.0f;
	int   zero_int     = 0;

	glClearBufferfv(GL_COLOR, 0, back_color);
	glClearBufferfv(GL_DEPTH, 0, &one);
	glClearBufferiv(GL_STENCIL, 0, &zero_int);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	glm::mat4* transform_matrices = nullptr;

	GL_ERROR

		// =====================================================================
		// =====================================================================
		// == Rendering the mirror contents 
		// =====================================================================
		// =====================================================================

#define RENDER_MIRROR
#ifdef RENDER_MIRROR
	glEnable(GL_STENCIL_TEST);
	glStencilFunc(GL_ALWAYS, 1, 1);
	glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

	GL_ERROR

	// Do Masking
	//glColorMask(0, 0, 0, 0);
	glEnable(GL_STENCIL_TEST);
	glStencilFunc(GL_ALWAYS, 1, 1);
	glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
	glDepthMask(GL_TRUE);
	glEnable(GL_DEPTH_TEST);

	GL_ERROR

	// Apply the mirror
	glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_transformation_buffer);
	transform_matrices = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 3 * sizeof(glm::mat4), GL_MAP_WRITE_BIT);
	transform_matrices[0] = m_projmat;
	transform_matrices[1] = m_viewmat;
	transform_matrices[2] =
		m_worldmat *
		glm::mat4(
			5.0f, 0.0f, 0.0f, 0.0f,
			0.0f, 5.0f, 0.0f, 0.0f,
			0.0f, 0.0f, 5.0f, 0.0f,
			0.0f, 0.0f, 0.0f, 1.0f
		);
	glUnmapBuffer(GL_UNIFORM_BUFFER);

	drawMirror();

	// Render Mirrored Triangle
	glDepthMask(GL_FALSE);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_GREATER);
	glColorMask(1, 1, 1, 1);
	glStencilFunc(GL_EQUAL, 1, 1);
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

	// Apply the mirror
	glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_transformation_buffer);
	transform_matrices = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 3 * sizeof(glm::mat4), GL_MAP_WRITE_BIT);
	transform_matrices[0] = m_projmat;
	transform_matrices[1] = m_viewmat;
	transform_matrices[2] =
		m_worldmat *
		glm::mat4(
			5.0f, 0.0f, 0.0f, 0.0f,
			0.0f, 5.0f, 0.0f, 0.0f,
			0.0f, 0.0f, -5.0f, 0.0f,
			0.0f, 0.0f, 0.0f, 1.0f
		);
	glUnmapBuffer(GL_UNIFORM_BUFFER);
	drawTriangle();

	GL_ERROR

#endif
	// ===================================================================
	// ===================================================================
	// Render main triangle
	// ===================================================================
	// ===================================================================

	glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_transformation_buffer);
	transform_matrices = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 3 * sizeof(glm::mat4), GL_MAP_WRITE_BIT);
	transform_matrices[0] = m_projmat;
	transform_matrices[1] = m_viewmat;
	transform_matrices[2] =
		m_worldmat *
		glm::mat4(
			5.0f, 0.0f, 0.0f, 0.0f,
			0.0f, 5.0f, 0.0f, 0.0f,
			0.0f, 0.0f, 5.0f, 0.0f,
			0.0f, 0.0f, 0.0f, 1.0f
		);
	glUnmapBuffer(GL_UNIFORM_BUFFER);
	glDepthFunc(GL_LESS);
	glEnable(GL_DEPTH_TEST);
	glDepthMask(GL_TRUE);
	glDisable(GL_STENCIL_TEST);
	drawTriangle();

	GL_ERROR

	glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_transformation_buffer);
	transform_matrices = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 3 * sizeof(glm::mat4), GL_MAP_WRITE_BIT);
	transform_matrices[0] = m_projmat;
	transform_matrices[1] = m_viewmat;
	transform_matrices[2] =	m_worldmat;
	glUnmapBuffer(GL_UNIFORM_BUFFER);

	GL_ERROR
}