Esempio n. 1
0
    void App::Render(const delta_t dt, const delta_t elapsed)
    {	
		// clear buffer and save matrix state
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// position camera
		mat4 camera;
		cameraFrame.GetCameraMatrix(camera);
		mv.PushMatrix(camera);

			// create point light
			vec4 vLightPos(sin(elapsed) * 10, 5, -8 + (cos(elapsed) * 15), 1);
			vec4 vLightEyePos;
			vec4 vAmbientColor(0.1f, 0.1f, 0.1f, 1);
			vec4 vDiffuseColor(1, 1, 1, 1);
			vec4 vSpecularColor(1, 1, 1, 1);

			// use smoothstep to animate the cube movement
			static float xPos;
			xPos = ((float)sin(elapsed * 3.1) + 1.0f) / 2.0f;
			xPos = (xPos) * (xPos) * (3.0f - 2.0f * (xPos));
			xPos = (-1.5f * xPos) + (1.5f * (1.0f - xPos));

			// copy uniform information to shader 
			GL_DEBUG(glUseProgram(phongShader));
			vLightEyePos = mv.Transform(vLightPos);
			GL_DEBUG(glUniformMatrix3fv(locNM , 1, GL_FALSE, transform.GetNormalMatrix() ));
			GL_DEBUG(glUniformMatrix4fv(locMV , 1, GL_FALSE, transform.GetModelView() ));
			GL_DEBUG(glUniformMatrix4fv(locMVP, 1, GL_FALSE, transform.GetMVP() ));
			GL_DEBUG(glUniform4fv(locAmbient, 1, &vAmbientColor[0]));
			GL_DEBUG(glUniform4fv(locDiffuse, 1, &vDiffuseColor[0]));
			GL_DEBUG(glUniform4fv(locSpecular, 1, &vSpecularColor[0]));
			GL_DEBUG(glUniform3fv(locLightPos, 1, &vLightEyePos[0]));
			GL_DEBUG(glUniform1i(locTexture, 0));

			// render the floor
			glActiveTexture(GL_TEXTURE0);
			glBindTexture(GL_TEXTURE_2D, baseTexture);
			base.Draw();

			// transform modelview to rotate cube
			mv.PushMatrix();
				mat4 cubePos = translate(mat4(), vec3(xPos, -0.5f, -15.f));
				cubePos = rotate(cubePos, 100.0f * (float)sin(elapsed), vec3(1.0f, 0.0f, 0.0f));
				cubePos = rotate(cubePos, 20.0f * (float)elapsed, vec3(0.0f, 1.0f, 0.0f));
				mv.MultMatrix(cubePos);

				// copy uniform information to shader for cube
				vLightEyePos = mv.Transform(vLightPos);
				GL_DEBUG(glUniform3fv(locLightPos, 1, &vLightEyePos[0]));
				GL_DEBUG(glUniformMatrix3fv(locNM , 1, GL_FALSE, transform.GetNormalMatrix() ));
				GL_DEBUG(glUniformMatrix4fv(locMV , 1, GL_FALSE, transform.GetModelView() ));
				GL_DEBUG(glUniformMatrix4fv(locMVP, 1, GL_FALSE, transform.GetMVP() ));
				glBindTexture(GL_TEXTURE_2D, cubeTexture);

				// render geometry
				cube.Draw();
			mv.PopMatrix();

			// draw cube at light position
			mv.PushMatrix();
				cubePos = translate(mat4(), vLightPos.xyz());
				mv.MultMatrix(cubePos);
				vLightEyePos = mv.Transform(vLightPos);
				GL_DEBUG(glUniform3fv(locLightPos, 1, &vLightEyePos[0]));
				GL_DEBUG(glUniformMatrix3fv(locNM , 1, GL_FALSE, transform.GetNormalMatrix() ));
				GL_DEBUG(glUniformMatrix4fv(locMV , 1, GL_FALSE, transform.GetModelView() ));
				GL_DEBUG(glUniformMatrix4fv(locMVP, 1, GL_FALSE, transform.GetMVP() ));
				glBindTexture(GL_TEXTURE_2D, cubeTexture);
				cube.Draw();
			mv.PopMatrix();

			// draw a stationary cube
			mv.PushMatrix();
				cubePos = translate(mat4(), vec3(-5, 0, 0));
				cubePos = rotate(cubePos, 45.0f, vec3(1, 0, 0));
				mv.MultMatrix(cubePos);
				vLightEyePos = mv.Transform(vLightPos);
				GL_DEBUG(glUniform3fv(locLightPos, 1, &vLightEyePos[0]));
				GL_DEBUG(glUniformMatrix3fv(locNM , 1, GL_FALSE, transform.GetNormalMatrix() ));
				GL_DEBUG(glUniformMatrix4fv(locMV , 1, GL_FALSE, transform.GetModelView() ));
				GL_DEBUG(glUniformMatrix4fv(locMVP, 1, GL_FALSE, transform.GetMVP() ));
				glBindTexture(GL_TEXTURE_2D, cubeTexture);
				cube.Draw();
			mv.PopMatrix();

		mv.PopMatrix();

		// update blur frame textures
		blurTimer += (float)dt;
		if (blurTimer > BLUR_FRAME_DELAY)
		{
			// save frame buffer to pbo
			glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
			glReadPixels(0, 0, g_App.GetWidth(), g_App.GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, NULL);
			glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

			// save pixel buffer to texture and increment frame index
			glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
			glActiveTexture(GL_TEXTURE0 + GetBlurFrame0());
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, g_App.GetWidth(), g_App.GetHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
			glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

			// reset iterator variables
			blurTimer = 0;
			AdvanceBlurFrame();
		}

		// use stored blur textures to generate frame
		if (blurEnabled && moveBlur) 
		{
			// render quad to the screen
			mat4 ortho = glm::ortho(0.0f, (float)g_App.GetWidth(), 0.0f, (float)g_App.GetHeight());
			glDisable(GL_DEPTH_TEST);
			glUseProgram(blurShader);
			glUniformMatrix4fv(locBlurMVP, 1, GL_FALSE, value_ptr(ortho));
			glUniform1i(glGetUniformLocation(blurShader, "blurFrame0"), GetBlurFrame0());
			glUniform1i(glGetUniformLocation(blurShader, "blurFrame1"), GetBlurFrame1());
			glUniform1i(glGetUniformLocation(blurShader, "blurFrame2"), GetBlurFrame2());
			glUniform1i(glGetUniformLocation(blurShader, "blurFrame3"), GetBlurFrame3());
			screen.Draw();
			glEnable(GL_DEPTH_TEST);
		}
	}
void VCoronaManager::RenderCorona (VCoronaCandidate& coronaCandidate, VTextureObject*& pTexture)
{
#ifdef SUPPORTS_CORONAS
  VCoronaComponent *pCorona = coronaCandidate.m_pCorona;
  VisRenderContext_cl* pContext = VisRenderContext_cl::GetCurrentContext();
  VisLightSource_cl* pLight = (VisLightSource_cl*)pCorona->GetOwner();

  hkvVec3 vLightPos(hkvNoInitialization);
  pLight->GetVirtualPosition(vLightPos, pContext);
  hkvVec3 vEyePos(hkvNoInitialization);
  pContext->GetCamera()->GetPosition(vEyePos);
  hkvVec3 vDir = pContext->GetCamera()->GetDirection();

  // Corona texture
  VTextureObject *pTex = pCorona->GetCoronaTexture();
  if (pTex == NULL)
    return;

  if (pTexture != pTex)
  {
    pTexture = pTex;
    Vision::RenderLoopHelper.BindMeshTexture(pTexture,0);
  }

  // Get light color
  VColorRef color = pLight->GetColor();
  hkvVec3 vDist = vLightPos - vEyePos;
  float fEyeDist = vDir.dot(vDist);

  //determine if camera is in light cone if the light is directional
  float fDirectionalDampening = 1.0f;
  if ( pLight->GetType() == VIS_LIGHT_SPOTLIGHT && pCorona->GetOnlyVisibleInSpotLight() )
  {
    fDirectionalDampening = 0.0f;
    float fConeAngle = pLight->GetProjectionAngle();
    float fConeLength = pLight->GetRadius();
    hkvVec3 fConeDirection = pLight->GetDirection();
    fConeDirection.normalize();

    hkvVec3 vLightEyeDist = vEyePos - vLightPos;

    //#2 check if the camera is inside the angle of the cone
    float cosinusAngle = (vLightEyeDist/vLightEyeDist.getLength()).dot(fConeDirection);
    float fDegree = hkvMath::acosDeg(cosinusAngle);
    float normRadius = fDegree / (fConeAngle/2.0f);

    if (normRadius < 1.0f)
    {
      //hardcoded falloff. For better performance, we avoid sampling the projection texture here.
      const float fEpsilon = 64.0f/256.0f;
      const float fQuadFactor = 1.0f/fEpsilon - 1.0f;
      fDirectionalDampening = 1.0f / (1.0f + fQuadFactor*normRadius*normRadius);

      // scale the function so that the value is exactly 0.0 at the edge and 1.0 in the center
      fDirectionalDampening = (fDirectionalDampening - fEpsilon) / (1.0f - fEpsilon);  
    }
  }
  // Fog params
  float fFogDampening = 1.0f;
  if (pLight->GetType() != VIS_LIGHT_DIRECTED && Vision::World.IsLinearDepthFogEnabled())
  {  
    const VFogParameters &fog = Vision::World.GetFogParameters();
    float fFogStart = fog.fDepthStart;
    float fFogEnd = fog.fDepthEnd;

    float fFogFactor = (fFogEnd > fFogStart) ? ((fEyeDist - fFogStart) / (fFogEnd - fFogStart)) : 0.f;
    fFogDampening = 1.0f - hkvMath::clamp(fFogFactor, 0.0f, 1.0f);
  }

  // Get corona rotation
  float fRotation = 0.0f;
  hkvVec4 vRotation(1.0f, 0.0f, 0.0f, 1.0f);
  if (pCorona->CoronaFlags & VIS_CORONASCALE_ROTATING)
  { 
    fRotation = hkvMath::mod (fEyeDist * 0.5f, 360.f);

    vRotation.x = hkvMath::cosDeg (fRotation);
    vRotation.y = -hkvMath::sinDeg (fRotation);
    vRotation.z = -vRotation.y;
    vRotation.w = vRotation.x;
  }

  // Texture dimensions
  int iSizeX, iSizeY, depth;
  pTex->GetTextureDimensions(iSizeX, iSizeY, depth);

  hkvVec4 vScale(0.0f, 0.0f, 0.0f, 0.0f);

  int iMainWidth, iMainHeight, iWidth, iHeight;
  pContext->GetSize(iWidth, iHeight);
  VisRenderContext_cl::GetMainRenderContext()->GetSize(iMainWidth, iMainHeight);

  // Preserve texture aspect ratio
  int iTexHeight = pTex->GetTextureHeight();
  int iTexWidth = pTex->GetTextureWidth();

  // Perspective scaling
  // This scaling ensures roughly the same size on 720p as the old implementation.
  vScale.z = iTexWidth * pCorona->CoronaScaling * 0.25f;
  vScale.w = iTexHeight * pCorona->CoronaScaling * 0.25f;

  // Screen-space scaling
  // This scaling ensures roughly the same size on 720p as the old implementation.
  const float fScaleFactor = pCorona->CoronaScaling * iMainHeight / 11.0f;
  vScale.x = ((float)iTexWidth / 128.0f) * fScaleFactor * (float(iWidth) / float(iMainWidth));
  vScale.y = ((float)iTexHeight / 128.0f) * fScaleFactor * (float(iHeight) / float(iMainHeight));
  vScale.x *= 2.0f / iWidth;
  vScale.y *= 2.0f / iHeight;
  
  // Scale by visibility
  if (pCorona->CoronaFlags & VIS_CORONASCALE_VISIBLEAREA)
  {
    vScale.x *= coronaCandidate.m_fCurrentVisibility;
    vScale.y *= coronaCandidate.m_fCurrentVisibility;
    vScale.z *= coronaCandidate.m_fCurrentVisibility;
    vScale.w *= coronaCandidate.m_fCurrentVisibility;
  }

  VCompiledShaderPass* pShader = m_spCoronaTechnique->GetShader(0);
  VShaderConstantBuffer *pVertexConstBuffer = pShader->GetConstantBuffer(VSS_VertexShader);
  // xyz = worldspace position, w = 1.0 if VIS_CORONASCALE_DISTANCE is true, otherwise zero.
  pVertexConstBuffer->SetSingleParameterF("coronaPosition", vLightPos.x, vLightPos.y, vLightPos.z, (pCorona->CoronaFlags & VIS_CORONASCALE_DISTANCE) ? 1.0f : 0.0f);
  // xyz = light color, w = corona visibility.
  pVertexConstBuffer->SetSingleParameterF("coronaColor", color.r/255.0f, color.g/255.0f, color.b/255.0f, coronaCandidate.m_fCurrentVisibility * fFogDampening * fDirectionalDampening);
  // xyzw = 2x2 rotation matrix. float2x2 is not supported in shader model 2, so a float4 is used and multiplication is done manually in the shader.
  pVertexConstBuffer->SetSingleParameterF("coronaRotation", vRotation.x, vRotation.y, vRotation.z, vRotation.w);
  // xy = screen-space scaling. zw = view-space scaling.
  pVertexConstBuffer->SetSingleParameterF("coronaScale", vScale.x, vScale.y, vScale.z, vScale.w);
    
  Vision::RenderLoopHelper.RenderMeshes(pShader, VisMeshBuffer_cl::MB_PRIMTYPE_TRILIST, 0, 2, 6);
#endif
}