⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oglrenderer.cpp

📁 天空绘制
💻 CPP
字号:
//-----------------------------------------------------------------------------
// 
// @doc
//
// @module	OGLRenderer.cpp - OpenGL renderer |
//
// This module contains the support for OpenGL rendering.
//
// Copyright (c) 1999 - Descartes Systems Sciences, Inc.
//
// @end
//
// $History: DcComEngGenConfigurePage.h $
//
//-----------------------------------------------------------------------------

#include "stdafx.h"
#include "OGLRenderer.h"
#include "RenderGlobals.h"
#include "../_CoreLib/Utility.h"
#include "../_CoreLib/Matrix.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//
// Globals used by the renderer
//

HWND COGLRenderer::gs_hWnd;
HDC COGLRenderer::gs_hDC;
HGLRC COGLRenderer::gs_hrc;

//
// Force all render code into own seg
//

#pragma code_seg ("renderer_segment")

//
// Helper macros
//

#ifdef _DEBUG
#define CheckGlError() \
{ \
    GLenum nError = glGetError (); \
    _ASSERT (nError == GL_NO_ERROR); \
}
#else
#define CheckGlError()
#endif

inline void DoSkyCoord (const CSkyDome::_Vertex &sVertex, const TextureMatrix &tm)
{
	CVector2 vTC;
	vTC .m_x = sVertex .vVertex .Dot (tm .vsTexture) + tm .fsTexShift;
	vTC .m_y = sVertex .vVertex .Dot (tm .vtTexture) + tm .ftTexShift;
	glTexCoord2fv (vTC .m_v);
	glVertex3fv (sVertex .vMapVertex .m_v);
}

inline void COGLRenderer::SetColor (const CVector4 &vColor)
{
	if (!(vColor == g_vLastColor))
	{
		glColor4fv (vColor .m_v);
		g_vLastColor = vColor;
	}
}

//-----------------------------------------------------------------------------
//
// @mfunc Draw a cloud layer
//
//		Draw a cloud layer
//
// @rdesc None.
//
//-----------------------------------------------------------------------------

void COGLRenderer::DrawSkyClouds (CSkyClouds *pSkyClouds, 
									const CVector3 &vColor)
{
	int i;

	//
	// Selected the proper texture
	//

	BindTextureIndex (pSkyClouds ->GetTextureIndex ());

	//
	// Create the texture mapping object
	//

	CVector2 vOffset (pSkyClouds ->GetOffset ());
	float fScale = 1.0 / (g_sSkyDome .m_fRadius * 2.0f * pSkyClouds ->GetScale ());
	TextureMatrix tm;
	tm .fsTexShift = .5f + vOffset .m_x;
	tm .ftTexShift = .5f + vOffset .m_y;
	tm .vsTexture = CVector3 (fScale, 0, 0);
	tm .vtTexture = CVector3 (0, fScale, 0);

	//
	// Get a pointer to the vertex list to make things easier
	//

	CSkyDome::_Vertex *pVertex = g_sSkyDome .m_pVertex;
	int nResolution = g_sSkyDome .m_nResolution;

	//
	// Loop through top row of triangles
	//

	SetColor (vColor);
	glBegin (GL_TRIANGLE_FAN);
	DoSkyCoord (pVertex [0], tm);
	for (i = 1; i < nResolution * 4 + 1; i++)
	{
		DoSkyCoord (pVertex [i], tm);
	}
	DoSkyCoord (pVertex [1], tm);
	glEnd ();

	//
	// Loop through squares
	//

	int nDelta = nResolution * 4;
	for (int j = 1; j < nResolution; j++)
	{
		int nStart = nDelta * j + 1;
		int nEnd = nStart + nDelta;
		glBegin (GL_TRIANGLE_STRIP);
		for (i = nStart; i < nEnd; i++)
		{
			DoSkyCoord (pVertex [i - nDelta], tm);
			DoSkyCoord (pVertex [i], tm);
		}
		DoSkyCoord (pVertex [nStart - nDelta], tm);
		DoSkyCoord (pVertex [nStart], tm);
		glEnd ();
	}
}

//-----------------------------------------------------------------------------
//
// @mfunc Draw a sky body
//
//		Draw a sky body to the screen
//
// @rdesc None.
//
//-----------------------------------------------------------------------------

void COGLRenderer::DrawSkyBody (CSkyBody *pSkyBody)
{

	//
	// Distance factor
	//

	static const float fDistanceFactor = 1000.0f;

	//
	// Compute the position of the body
	//

	CVector3 vPos;
	g_sRenderCtx .m_sModelToEye .PreNormalMultiply (pSkyBody ->GetNormal (), vPos);
	vPos *= fDistanceFactor;
	float fScale = fDistanceFactor * 16 * 
		pSkyBody ->GetRadius () / pSkyBody ->GetDistance ();
	CVector3 vXDel (fScale, 0, 0);
	CVector3 vYDel (0, fScale, 0);

	//
	// Draw the body as a billboard
	//

	CVector3 v;
	glBegin (GL_QUADS);
	glTexCoord2f (0, 0);
	v = vPos - vXDel - vYDel;
	glVertex3fv (v .m_v);
	glTexCoord2f (0, 1);
	v = vPos - vXDel + vYDel;
	glVertex3fv (v .m_v);
	glTexCoord2f (1, 1);
	v = vPos + vXDel + vYDel;
	glVertex3fv (v .m_v);
	glTexCoord2f (1, 0);
	v = vPos + vXDel - vYDel;
	glVertex3fv (v .m_v);
	glEnd ();

	//
	// Check for an error
	//

	CheckGlError ();
}

//-----------------------------------------------------------------------------
//
// @mfunc Draw the sky
//
//		Draw the sky to the screen
//
// @rdesc None.
//
//-----------------------------------------------------------------------------

void COGLRenderer::DrawSky ()
{
	CDoubleLink *pStart;
	CDoubleLink *pLink;

	//
	// Initialize opengl.  Turn on blending and disable the z buffer
	//

	glEnable (GL_BLEND);
	glDepthMask (GL_FALSE);

	//
	// Map the sky dome triangles
	//

	g_sSkyDome .MapVertices (g_sRenderCtx .m_sModelToEye);

	//
	// Loop through the clouds in the sky dome and count the
	// number of clouds in the system
	//

	int nClouds = 0;
	pStart = &g_sSkyDome .m_sCloudsList;
	for (pLink = pStart ->GetNext (); 
	pLink != pStart; pLink = pLink ->GetNext ())
	{
		CSkyClouds *pClouds = CSkyClouds::FromLink (pLink);
		if (pClouds ->GetType () == CSkyClouds::Type_Clouds)
			nClouds++;
	}

	//
	// Loop through the clouds in the sky dome and draw the stars
	//

	glBlendFunc (GL_ONE, GL_ONE);
	pStart = &g_sSkyDome .m_sCloudsList;
	for (pLink = pStart ->GetNext (); 
	pLink != pStart; pLink = pLink ->GetNext ())
	{
		CSkyClouds *pClouds = CSkyClouds::FromLink (pLink);
		if (pClouds ->GetType () != CSkyClouds::Type_Stars) 
			continue;
		DrawSkyClouds (pClouds, pClouds ->GetCurrentColor ());
	}

	//
	// Loop through the bodies in the sky dome
	//

	pStart = &g_sSkyDome .m_sBodyList;
	for (pLink = pStart ->GetNext (); 
	pLink != pStart; pLink = pLink ->GetNext ())
	{
		CSkyBody *pBody = CSkyBody::FromLink (pLink);
		switch (pBody ->GetType ())
		{
			case CSkyBody::Type_Sun:
				BindTextureIndex (pBody ->GetTextureIndex ());
				glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
				SetColor (pBody ->GetCurrentColor ());
				DrawSkyBody (pBody);
				break;
			case CSkyBody::Type_Moon:
				BindTextureIndex (pBody ->GetMaskTextureIndex ());
				glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
				SetColor (g_sSkyDome .m_vCurrentSkyColor);
				DrawSkyBody (pBody);
				BindTextureIndex (pBody ->GetTextureIndex ());
				glBlendFunc (GL_ONE, GL_ONE);
				SetColor (pBody ->GetCurrentColor ());
				DrawSkyBody (pBody);
				break;
			case CSkyBody::Type_Flare:
				BindTextureIndex (pBody ->GetTextureIndex ());
				glBlendFunc (GL_ONE, GL_ONE);
				SetColor (pBody ->GetCurrentColor ());
				DrawSkyBody (pBody);
				break;
			default:
				_ASSERT (FALSE);
				break;
		}
	}

	//
	// Compute the basic cloud color
	//

	CVector3 vBlendColor;
	vBlendColor .m_x = 1.0 - g_sSkyDome .m_vCurrentSkyColor .m_x;
	vBlendColor .m_y = 1.0 - g_sSkyDome .m_vCurrentSkyColor .m_y;
	vBlendColor .m_z = 1.0 - g_sSkyDome .m_vCurrentSkyColor .m_z;
	CVector3 vCloudColor (vBlendColor * (1.0f / (float) nClouds));

	//
	// Loop through the clouds in the sky dome rendering the clouds
	//

	glBlendFunc (GL_ONE, GL_ONE);
	pStart = &g_sSkyDome .m_sCloudsList;
	for (pLink = pStart ->GetNext (); 
	pLink != pStart; pLink = pLink ->GetNext ())
	{
		CSkyClouds *pClouds = CSkyClouds::FromLink (pLink);
		if (pClouds ->GetType () != CSkyClouds::Type_Clouds) 
			continue;
		CVector3 vColor;
		DrawSkyClouds (pClouds, pClouds ->GetCurrentColor () * vCloudColor);
	}

	//
	// Restore any changed settings
	//

	glDisable (GL_BLEND);
	glDepthMask (GL_TRUE);
	CheckGlError ();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -