Beispiel #1
0
void Render(float alpha, float elapsedtime)
{
	float tmp[16];
	float texmat[16];
	float view[16];
	float viewinv[16];
	float proj[16];
	float viewproj[16];
	float lightview[16];
	float lightproj[16];
	float lightviewproj[16];

	float globalambient[4]	= { 0.01f, 0.01f, 0.01f, 1.0f };
	float moonlight[]		= { -0.25f, 0.65f, -1, 0 };
	float mooncolor[]		= { 0.6f, 0.6f, 1, 1 };

	float eye[3]			= { 0, 0, 8 };
	float look[3]			= { 0, 0, 0 };
	float up[3]				= { 0, 1, 0 };

	float screensize[2]		= { (float)screenwidth, (float)screenheight };
	float lightclip[2];
	float clipplanes[2];
	float orient[2];

	// setup camera
	cameraangle.smooth(orient, alpha);

	GLMatrixRotationAxis(view, orient[1], 1, 0, 0);
	GLMatrixRotationAxis(tmp, orient[0], 0, 1, 0);
	GLMatrixMultiply(view, view, tmp);

	GLVec3Transform(eye, eye, view);

	GLFitToBox(clipplanes[0], clipplanes[1], eye, look, scenebox);
	GLMatrixPerspectiveFovRH(proj, (60.0f * 3.14159f) / 180.f,  (float)screenwidth / (float)screenheight, clipplanes[0], clipplanes[1]);

	GLMatrixLookAtRH(view, eye, look, up);
	GLMatrixMultiply(viewproj, view, proj);

	// setup moonlight
	GLMatrixInverse(viewinv, view);
	GLVec3Transform(moonlight, moonlight, viewinv);
	GLVec3Normalize(moonlight, moonlight);

	// should be that value in view space (background is fix)
	// but let y stay in world space, so we see shadow
	moonlight[1] = 0.65f;

	GLMatrixViewVector(lightview, moonlight);
	GLFitToBox(lightproj, lightclip, lightview, scenebox);
	GLMatrixMultiply(lightviewproj, lightview, lightproj);

	// render shadow map
	glClearColor(0, 0, 0, 1);

	varianceshadow->SetMatrix("matViewProj", lightviewproj);
	varianceshadow->SetVector("clipPlanes", lightclip);

	shadowmap->Set();
	{
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

		varianceshadow->Begin();
		{
			RenderScene(varianceshadow);
		}
		varianceshadow->End();
	}
	shadowmap->Unset();

	// blur it
	float texelsize[] = { 1.0f / SHADOWMAP_SIZE, 1.0f / SHADOWMAP_SIZE };

	glDepthMask(GL_FALSE);
	glBindTexture(GL_TEXTURE_2D, shadowmap->GetColorAttachment(0));

	boxblur3x3->SetVector("texelSize", texelsize);

	blurredshadow->Set();
	{
		boxblur3x3->Begin();
		{
			screenquad->Draw();
		}
		boxblur3x3->End();
	}
	blurredshadow->Unset();

	glDepthMask(GL_TRUE);

	// STEP 1: z pass
	ambient->SetMatrix("matViewProj", viewproj);
	ambient->SetVector("matAmbient", globalambient);

	framebuffer->Set();
	{
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

		// draw background first
		glDisable(GL_DEPTH_TEST);
		glDepthMask(GL_FALSE);
		glBindTexture(GL_TEXTURE_2D, texture3);

		float scaledx = 1360.0f * (screenheight / 768.0f);
		float scale = screenwidth / scaledx;

		GLMatrixTranslation(tmp, -0.5f, 0, 0);
		GLMatrixScaling(texmat, scale, 1, 1);
		GLMatrixMultiply(texmat, tmp, texmat);

		GLMatrixTranslation(tmp, 0.5f, 0, 0);
		GLMatrixMultiply(texmat, texmat, tmp);

		GLMatrixRotationAxis(tmp, M_PI, 0, 0, 1);
		GLMatrixMultiply(texmat, texmat, tmp);

		basic2D->SetMatrix("matTexture", texmat);
		basic2D->Begin();
		{
			screenquad->Draw();
		}
		basic2D->End();

		glEnable(GL_DEPTH_TEST);
		glDepthMask(GL_TRUE);

		// then fill zbuffer
		ambient->Begin();
		{
			RenderScene(ambient);
		}
		ambient->End();
	}
	framebuffer->Unset();

	// STEP 2: cull lights
	if( lightcull && timeout > DELAY )
	{
		lightcull->SetFloat("alpha", alpha);
		lightcull->SetVector("clipPlanes", clipplanes);
		lightcull->SetVector("screenSize", screensize);
		lightcull->SetMatrix("matProj", proj);
		lightcull->SetMatrix("matView", view);
		lightcull->SetMatrix("matViewProj", viewproj);

		glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, counterbuffer);
		GLuint* counter = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY);
	
		*counter = 0;
		glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);

		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, headbuffer);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, nodebuffer);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, lightbuffer);
		glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, counterbuffer);
		glBindTexture(GL_TEXTURE_2D, framebuffer->GetDepthAttachment());

		lightcull->Begin();
		{
			glDispatchCompute(workgroupsx, workgroupsy, 1);
		}
		lightcull->End();

		glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0);
		glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
		glBindTexture(GL_TEXTURE_2D, 0);
	}

	// STEP 3: add some moonlight with shadow
	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ONE);
	glDepthMask(GL_FALSE);

	framebuffer->Set();

	shadowedlight->SetMatrix("matViewProj", viewproj);
	shadowedlight->SetMatrix("lightViewProj", lightviewproj);
	shadowedlight->SetVector("eyePos", eye);
	shadowedlight->SetVector("lightPos", moonlight);
	shadowedlight->SetVector("lightColor", mooncolor);
	shadowedlight->SetVector("clipPlanes", lightclip);

	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, blurredshadow->GetColorAttachment(0));
	glActiveTexture(GL_TEXTURE0);

	shadowedlight->Begin();
	{
		RenderScene(shadowedlight);
	}
	shadowedlight->End();

	// STEP 4: accumulate lighting
	if( lightaccum && timeout > DELAY )
	{
		lightaccum->SetMatrix("matViewProj", viewproj);
		lightaccum->SetVector("eyePos", eye);
		lightaccum->SetFloat("alpha", alpha);
		lightaccum->SetInt("numTilesX", workgroupsx);

		lightaccum->Begin();
		{
			RenderScene(lightaccum);
		}
		lightaccum->End();
		
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
	}

	framebuffer->Unset();

	glDisable(GL_BLEND);
	glDepthMask(GL_TRUE);

	// STEP 4: gamma correct
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glBindTexture(GL_TEXTURE_2D, framebuffer->GetColorAttachment(0));

	gammacorrect->Begin();
	{
		screenquad->Draw();
	}
	gammacorrect->End();

#ifdef _DEBUG
	// check errors
	GLenum err = glGetError();

	if( err != GL_NO_ERROR )
		std::cout << "Error\n";
#endif

	SwapBuffers(hdc);
	mousedx = mousedy = 0;
}
Beispiel #2
0
void Render(float alpha, float elapsedtime)
{
	float world[16];
	float tmp[16];
	float view[16];
	float proj[16];
	float viewproj[16];
	float eye[3]		= { 0, 0.3f, 8 };
	float look[3]		= { 0, 0.3f, 0 };
	float up[3]			= { 0, 1, 0 };
	float clipplanes[2];
	float orient[2];

	cameraangle.smooth(orient, alpha);

	GLMatrixRotationAxis(view, orient[1], 1, 0, 0);
	GLMatrixRotationAxis(tmp, orient[0], 0, 1, 0);
	GLMatrixMultiply(view, view, tmp);

	GLVec3Transform(eye, eye, view);

	GLFitToBox(clipplanes[0], clipplanes[1], eye, look, scenebox);
	GLMatrixPerspectiveFovRH(proj, (60.0f * 3.14159f) / 180.f,  (float)screenwidth / (float)screenheight, clipplanes[0], clipplanes[1]);

	GLMatrixLookAtRH(view, eye, look, up);
	GLMatrixMultiply(viewproj, view, proj);

	// STEP 1: initialize header pointer buffer
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	glDisable(GL_DEPTH_TEST);
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, headbuffer);

	init->SetInt("screenWidth", screenwidth);
	init->Begin();
	{
		screenquad->Draw();
	}
	init->End();

	// STEP 2: collect transparent fragments into lists
	glBindTexture(GL_TEXTURE_2D, white);
	glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, counterbuffer);

	GLuint* counter = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY);
	*counter = 0;

	glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
	glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);

	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, nodebuffer);
	glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, counterbuffer);

	collect->SetMatrix("matView", view);
	collect->SetMatrix("matProj", proj);
	collect->SetInt("screenWidth", screenwidth);

	collect->Begin();
	{
		GLMatrixIdentity(world);

		for( int i = 0; i < numobjects; ++i )
		{
			const SceneObject& obj = objects[i];

			// scaling * rotation * translation
			GLMatrixScaling(tmp, obj.scale[0], obj.scale[1], obj.scale[2]);
			GLMatrixRotationAxis(world, obj.angle, 0, 1, 0);
			GLMatrixMultiply(world, tmp, world);

			GLMatrixTranslation(tmp, obj.position[0], obj.position[1], obj.position[2]);
			GLMatrixMultiply(world, world, tmp);

			collect->SetMatrix("matWorld", world);
			collect->SetVector("matAmbient", &obj.color.r);
			collect->CommitChanges();

			if( obj.type == 0 )
				box->DrawSubset(0);
			else if( obj.type == 1 )
				dragon->DrawSubset(0);
			else if( obj.type == 2 )
				buddha->DrawSubset(0);
		}
	}
	collect->End();

	glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0);

	// STEP 3: render
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);

	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_SRC_ALPHA);

	render->SetInt("screenWidth", screenwidth);

	render->Begin();
	{
		screenquad->Draw();
	}
	render->End();

	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);

	glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);

#ifdef _DEBUG
	// check errors
	GLenum err = glGetError();

	if( err != GL_NO_ERROR )
		std::cout << "Error\n";
#endif

	SwapBuffers(hdc);
	mousedx = mousedy = 0;
}
//*************************************************************************************************************
void Render(float alpha, float elapsedtime)
{
	OpenGLColor	grcolor(0xffdddddd);
	OpenGLColor	cvcolor(0xff7470ff);
	OpenGLColor	splinecolor(0xff000000);
	OpenGLColor	outsidecolor(0.75f, 0.75f, 0.8f, 1);
	OpenGLColor	insidecolor(1, 0.66f, 0.066f, 1);

	float		world[16];
	float		view[16];
	float		proj[16];
	float		viewproj[16];

	float		pointsize[2]	= { 10.0f / screenwidth, 10.0f / screenheight };
	float		grthickness[2]	= { 1.5f / screenwidth, 1.5f / screenheight };
	float		cvthickness[2]	= { 2.0f / screenwidth, 2.0f / screenheight };
	float		spthickness[2]	= { 3.0f / screenwidth, 3.0f / screenheight };
	float		spviewport[]	= { 0, 0, (float)screenwidth, (float)screenheight };

	float		eye[3]			= { 5, 4, 15 };
	float		look[3]			= { 5, 4, 5 };
	float		up[3]			= { 0, 1, 0 };
	float		lightdir[4]		= { 0, 1, 0, 0 };
	float		fwd[3];
	float		orient[2];

	// play with ortho matrix instead of viewport (line thickness remains constant)
	ConvertToSplineViewport(spviewport[0], spviewport[1]);
	ConvertToSplineViewport(spviewport[2], spviewport[3]);

	GLMatrixIdentity(world);
	GLMatrixOrthoRH(proj, spviewport[0], spviewport[2], spviewport[1], spviewport[3], -1, 1);

	glViewport(0, 0, screenwidth, screenheight);
	glClearColor(1, 1, 1, 1);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glDisable(GL_DEPTH_TEST);

	renderlines->SetMatrix("matViewProj", proj);
	renderlines->SetMatrix("matWorld", world);
	renderlines->SetVector("color", &grcolor.r);
	renderlines->SetVector("lineThickness", grthickness);

	renderlines->Begin();
	{
		supportlines->DrawSubset(0);

		renderlines->SetVector("color", &cvcolor.r);
		renderlines->SetVector("lineThickness", cvthickness);
		renderlines->CommitChanges();

		supportlines->DrawSubset(1);

		if( hascompute )
		{
			renderlines->SetVector("lineThickness", spthickness);
			renderlines->SetVector("color", &splinecolor.r);
			renderlines->CommitChanges();

			curve->DrawSubset(0);
		}
	}
	renderlines->End();

	renderpoints->SetMatrix("matViewProj", proj);
	renderpoints->SetMatrix("matWorld", world);
	renderpoints->SetVector("color", &cvcolor.r);
	renderpoints->SetVector("pointSize", pointsize);

	renderpoints->Begin();
	{
		glBindVertexArray(supportlines->GetVertexLayout());
		glDrawArrays(GL_POINTS, 44, numcontrolvertices);
	}
	renderpoints->End();

	// render surface in a smaller viewport
	if( !fullscreen )
	{
		glEnable(GL_SCISSOR_TEST);
		glScissor(screenwidth - surfvpwidth - 10, screenheight - surfvpheight - 10, surfvpwidth, surfvpheight);
	}

	glClearColor(0.0f, 0.125f, 0.3f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glDisable(GL_SCISSOR_TEST);

	glEnable(GL_DEPTH_TEST);

	if( fullscreen )
		glViewport(0, 0, screenwidth, screenheight);
	else
		glViewport(screenwidth - surfvpwidth - 10, screenheight - surfvpheight - 10, surfvpwidth, surfvpheight);

	cameraangle.smooth(orient, alpha);

	GLVec3Subtract(fwd, look, eye);
	GLMatrixRotationYawPitchRoll(view, orient[0], orient[1], 0);
	GLVec3Transform(fwd, fwd, view);
	GLVec3Subtract(eye, look, fwd);

	GLMatrixPerspectiveRH(proj, M_PI / 3, 4.0f / 3.0f, 0.1f, 50.0f);
	GLMatrixLookAtRH(view, eye, look, up);
	GLMatrixMultiply(viewproj, view, proj);

	if( wireframe )
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

	glDisable(GL_CULL_FACE);

	if( hascompute )
	{
		rendersurface->SetMatrix("matViewProj", viewproj);
		rendersurface->SetMatrix("matWorld", world);
		rendersurface->SetMatrix("matWorldInv", world); // its id
		rendersurface->SetVector("lightDir", lightdir);
		rendersurface->SetVector("eyePos", eye);
		rendersurface->SetVector("outsideColor", &outsidecolor.r);
		rendersurface->SetVector("insideColor", &insidecolor.r);
		rendersurface->SetInt("isWireMode", wireframe);

		rendersurface->Begin();
		{
			surface->DrawSubset(0);
		}
		rendersurface->End();
	}

	glEnable(GL_CULL_FACE);

	if( wireframe )
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	// render text
	if( !fullscreen )
	{
		glViewport(3, 0, 800, 130);

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

		float xzplane[4] = { 0, 1, 0, -0.5f };
		GLMatrixReflect(world, xzplane);

		basic2D->SetMatrix("matTexture", world);
		basic2D->SetInt("sampler0", 0);
		basic2D->Begin();
		{
			glBindTexture(GL_TEXTURE_2D, text1);
			screenquad->Draw();
		}
		basic2D->End();

		glEnable(GL_DEPTH_TEST);
		glDisable(GL_BLEND);
	}

#ifdef _DEBUG
	// check errors
	GLenum err = glGetError();

	if( err != GL_NO_ERROR )
		std::cout << "Error\n";
#endif

	SwapBuffers(hdc);
	mousedx = mousedy = 0;
}