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

📄 renderer.cpp

📁 3D数学基础:图形与游戏开发书籍源码,里面有很多实用的代码,对做3D的同志很有意义
💻 CPP
📖 第 1 页 / 共 5 页
字号:
void	Renderer::setRGB(unsigned int rgb) {

	// Mask off alpha value in the input color, if any alpha
	// was specified.

	rgb &= 0x00ffffff;

	// Set RGB portion, leaving alpha portion unchanged

	constantARGB = (constantARGB & 0xff000000) | rgb;
}

//---------------------------------------------------------------------------
// Renderer::setARGB
//
// Sets the global constant color and opacity simulataneously

void	Renderer::setARGB(unsigned argb) {

	// Set const alpha value using floating point function

	setOpacity(GET_A(argb) / 255.0f);

	// Slam value

	constantARGB = argb;
}

//---------------------------------------------------------------------------
// Renderer::setOpacity
//
// Sets the global constant alpha value.  This is used for 2D primitives,
// and for 3D primitives than do not specify a color in the vertex.  For any 3D
// primitives that specify a color in the vertex (such as those using
// RenderVertexL) the alpha comes directly from the vertex.

void	Renderer::setOpacity(float a) {

	// Sanity check range

	assert(a >= 0.0f);
	assert(a <= 1.0f);

	// Snap to nearest value of 255

	int	newAlpha = (int)floor(a * 255.0f + .5f);

	// Check if value not changing

	if (newAlpha == GET_A(constantARGB)) {
		return;
	}

	// Remember value in floating point and in the
	// alpha bits of the global constant color

	constantOpacity = (float)newAlpha / 255.0f;
	constantARGB = (newAlpha << 24) | (constantARGB & 0x00ffffff);

	// Set the alpha values in the D3D Material

	d3dMaterial.Diffuse.a = constantOpacity;
	d3dMaterial.Ambient.a = constantOpacity;
	d3dMaterial.Specular.a = constantOpacity;

	// Tell D3D

	if (pD3DDevice == NULL) {
		assert(false);
		return;
	}
	HRESULT result = pD3DDevice->SetMaterial(&d3dMaterial);
	assert(SUCCEEDED(result));
}

//---------------------------------------------------------------------------
// Renderer::setFogEnable
//
// Enable of disable fog.

void	Renderer::setFogEnable(bool flag) {

	// Check if state changing

	if (fogEnable != flag) {

		// Remember new state

		fogEnable = flag;

		// Set state to D3D

		setD3DRenderState(D3DRS_FOGENABLE, flag);
	}

}

//---------------------------------------------------------------------------
// Renderer::setFogColor
//
// Sets the fog color.  That is, the color that objects fade towards as they
// are fogged out.

void	Renderer::setFogColor(unsigned rgb) {

	// Mask off alpha value in the input color, if any alpha
	// was specified.

	rgb &= 0x00ffffff;

	// Check if state changing

	if (fogColor != rgb) {

		// Remember new state

		fogColor = rgb;

		// Set state to D3D

		setD3DRenderState(D3DRS_FOGCOLOR, rgb);
	}
}

//---------------------------------------------------------------------------
// Renderer::setFogDistance
//
// Sets the fog distances:
//
//	nearFog		The distance where the fog effect starts.  Objects
//			within this distance receive no fog effect.
//	farFog		The distance where objects are completely fogged
//			out.

void	Renderer::setFogDistance(float nearFog, float farFog) {

	// Check if near value changing

	if (nearFog != fogNear) {

		// Yes - remember new value

		fogNear = nearFog;

		// Update to D3D

		setD3DRenderState(D3DRS_FOGSTART, *(DWORD*)(&nearFog));
	}

	// Check if far value changing

	if (farFog != fogFar) {

		// Yes - remember new value

		fogFar = farFog;

		// Update to D3D

		setD3DRenderState(D3DRS_FOGEND, *(DWORD*)(&farFog));

		// Re-compute the clip matrix.  We pre-compute
		// the far value in clip coordinates for outcode
		// testing.  This value is computed in this function.

		computeClipMatrix();
	}
}

//---------------------------------------------------------------------------
// Renderer::setAmbientLightColor
//
// Sets the ambient light color.  When lighting is enabled, this is the
// light color that is always present, even when no other light is
// shining on the object.
//
// Usually, it is a relatively dark greyscale value, such as (64,64,64)
//
// See Section 15.4 for more on lighting.

void	Renderer::setAmbientLightColor(unsigned rgb) {

	// Mask off alpha value in the input color, if any alpha
	// was specified.

	rgb &= 0x00ffffff;

	// Check if state changing

	if (ambientLightColor != rgb) {

		// Remember new state

		ambientLightColor = rgb;

		// Set state to D3D

		setD3DRenderState(D3DRS_AMBIENT, rgb);
	}
}

//---------------------------------------------------------------------------
// Renderer::setDirectionalLightVector
//
// Controls the direction of the directional light.  The input vector
// is a unit vector in inertial space which points in the direction that
// the light is "facing."  In other words, it points away from the light,
// not towards the light.  (This is the opposite of the l vector.)  E.g.
// at high noon, you could use (0, -1, 0) for the sun.
//
// See Section 15.4 for more on lighting.

void	Renderer::setDirectionalLightVector(const Vector3 &v) {

	// Sanity check - the input vector should be normalized

	assert(fabs(vectorMag(v) - 1.0f) < .001f);

	// Check if state changing

	if (directionalLightVector != v) {

		// Remember new state

		directionalLightVector = v;

		// Set light vector in D3D light struct

		d3dDirectionalLight.Direction.x = directionalLightVector.x;
		d3dDirectionalLight.Direction.y = directionalLightVector.y;
		d3dDirectionalLight.Direction.z = directionalLightVector.z;

		// Set it to D3D

		setD3DDirectionalLight();
	}
}

//---------------------------------------------------------------------------
// Renderer::setDirectionalLightColor
//
// Controls the color of the directional light.
//
// See Section 15.4 for more on lighting.

void	Renderer::setDirectionalLightColor(unsigned rgb) {

	// Mask off alpha value in the input color, if any alpha
	// was specified.

	rgb &= 0x00ffffff;

	// Check if state changing

	if (directionalLightColor != rgb) {

		// Remember new state

		directionalLightColor = rgb;

		// Put color into diffuse and specular channels of
		// D3D light struct

		d3dDirectionalLight.Diffuse.r = GET_R(directionalLightColor) / 255.0f;
		d3dDirectionalLight.Diffuse.g = GET_G(directionalLightColor) / 255.0f;
		d3dDirectionalLight.Diffuse.b = GET_B(directionalLightColor) / 255.0f;
		d3dDirectionalLight.Specular = d3dDirectionalLight.Diffuse;

		// Set it to D3D

		setD3DDirectionalLight();
	}
}

//---------------------------------------------------------------------------
// Renderer::setLightEnable
//
// Enable/disable lighting calculations for 3D primitives that do not
// specify a color explicitly.  (i.e. primitives using RenderVertex vertices.)
// This has no effect on 2D primitives or prelit primites.
//
// When lighting is enabled, the current lighting context (ambient light,
// directional light vector, etc.) is used in conjunction with the
// vertex normal to compute a lighting value.
//
// When lighting is disabled, the primitive is drawn "unlit" - i.e. fully
// bright, as if the result of the lighting equation was a white color.
// 
// In either case, the opacity comes from the global constant opacity.

void	Renderer::setLightEnable(bool flag) {

	// Remember new state

	lightEnable = flag;

	// Note: we not apply this state directly to D3D.
	// For some reason, D3D allows you to "enable" lighting,
	// even if your vertices are already prelit and don't
	// have a normal.  Sort of stupid.  So we must manually
	// control the lighting flag on a per-primitive basis
}

//---------------------------------------------------------------------------
// Renderer::setBackfaceMode
//
// Controls culling of primitives based on clockwise/counterclockwise
// enumeration of vertices in screen space.
//
// eBackfaceModeCCW	Polygons with vertices enumerated counter-clockwise
//			are culled.  This is the default, since we normally
//			list our vertices clockwise around the polygon.
//
// eBackfaceModeCW	Polygons with vertices enumerated clockwise are
//			culled.  This can be useful if we have "mirrored"
//			an object, or the view, since the faces are flipped
//			inside out.
//
// eBackfaceModeDisable	No polygons are culled based on vertex order.

void	Renderer::setBackfaceMode(EBackfaceMode mode) {

	// Check if state changing

	if (backfaceMode != mode) {

		// Remember new state

		backfaceMode = mode;

		// Map our enum to D3D enum

		D3DCULL c;
		switch (mode) {
			default:
				assert(false);
			case eBackfaceModeCCW:
				c = D3DCULL_CCW;
				break;
			case eBackfaceModeCW:
				c = D3DCULL_CW;
				break;
			case eBackfaceModeDisable:
				c = D3DCULL_NONE;
				break;
		}

		// Set state to D3D

		setD3DRenderState(D3DRS_CULLMODE, c);
	}

}

//---------------------------------------------------------------------------
// Renderer::selectTexture
//
// Select a texture into the rendering context.  The texture is selected
// by handle

void	Renderer::selectTexture(int handle) {

	// Sanity check handle validity

	if (handle < 1 || handle >= nextTextureSlot) {
		assert(false);
		return;
	}

	// Check if state is changing

	if (handle != currentTextureHandle) {

		// Get shortcut to structure

		TextureCacheEntry *t = &textureCacheList[handle];

		// Make sure texture exists

		if (t->d3dTexture == NULL) {
			assert(false);
			return;
		}

		// Remember new state

		currentTextureHandle = handle;

		// Select it in D3D

		assert(pD3DDevice != NULL);
		HRESULT result = pD3DDevice->SetTexture(0, t->d3dTexture);
		assert(SUCCEEDED(result));
	}
}

//---------------------------------------------------------------------------
// Renderer::selectTexture
//
// Select a texture into the rendering context using a TextureReference.
// This interface can be more conveinent to use in the very common
// case where the texture is in a file - your upper level code doesn't
// have to keep track of the filename and the handle seperately - 
// they are stored together.
//
// This function can be called on a texture that is not yet cached.
// in this case, the texture is "demand cached."  However, for best
// performance, you should always cache all textures for before rendering

void	Renderer::selectTexture(TextureReference &texture) {

	// First, make sure the texture is cached in the graphics system,
	// and the handle is correct.  Notice that if the texture is
	// already cached, then this should return very quickly.

	cacheTexture(texture);
	
	// Now, the handle is correct, and we can select the texture by
	// handle.

	selectTexture(texture.handle);
}

//---------------------------------------------------------------------------
// Renderer::setTextureClamp
//
// Enable/disbale texture clamping.  When textures are clamped, UV values
// outside the 0...1 range are clamped, effectively "streaking" the outer
// pixel borders outward.  When textures are not clamp, they are "tiled,"
// using only the fractional portion of the UV coordinates and discarding
// the numbers to the left of the decimal point.

void	Renderer::setTextureClamp(bool flag) {
	HRESULT result;

	// Safety check - make sure we have a device

	if (pD3DDevice == NULL) {
		assert(false);
		return;
	}

	// Check if state changing

	if (textureClamp != flag) {

		// Remember new state

		textureClamp = flag;

		// Figure out D3D addressing mode to use

		D3DTEXTUREADDRESS m = flag ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP;

		// Set state to D3D for both U and V

		result = pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESSU, m);
		assert(SUCCEEDED(result));
		result = pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESSV, m);

⌨️ 快捷键说明

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