www.pudn.com > tomohide_fur.03.13.02.zip > FurTexture.cpp


//----------------------------------------------------------------------------- 
// File: FurTexture.cpp 
// 
// Copyright (C) 2001-2002 Tomohide Kano. All rights reserved. 
//----------------------------------------------------------------------------- 
 
#include  
#include  
#include "extensions.h" 
#include "FurTexture.h" 
 
const float INV_RAND_MAX = 1.0 / (RAND_MAX + 1); 
inline float rnd(float max=1.0) { return max * INV_RAND_MAX * rand(); } 
inline float rnd(float min, float max) { return min + (max - min) * INV_RAND_MAX * rand(); } 
 
 
//----------------------------------------------------------------------------- 
// FurTexture 
//----------------------------------------------------------------------------- 
FurTexture::FurTexture() 
{ 
	m_Size		= 0; 
	m_NumLayers	= 0; 
	m_Textures	= NULL; 
} 
 
 
//----------------------------------------------------------------------------- 
// ~FurTexture 
//----------------------------------------------------------------------------- 
FurTexture::~FurTexture() 
{ 
	glDeleteTextures(m_NumLayers, m_Textures); 
	delete [] m_Textures; 
} 
 
 
//----------------------------------------------------------------------------- 
// Init 
//----------------------------------------------------------------------------- 
bool FurTexture::Init(GLuint seed, GLuint size, GLuint num) 
{ 
	srand(seed); 
	m_Size      = size; 
	m_NumLayers = num; 
 
	D3DXCOLOR *data = new D3DXCOLOR[m_NumLayers*m_Size*m_Size]; 
	#define DATA(layer, x, y) data[m_Size*m_Size*(layer) + m_Size*(y) + (x)] 
 
	for (GLuint x = 0; x < m_Size; x++) 
	for (GLuint y = 0; y < m_Size; y++) 
	{ 
		GLuint layer; 
		D3DXCOLOR color; 
		float t; 
 
		// hair color 
		color.r = rnd(1.0, 1.0); 
		color.g = rnd(0.6, 0.8); 
		color.b = rnd(0.2, 0.5); 
		if (rnd() < 0.15) color *= rnd(0.2, 0.4); 
		else              color *= rnd(0.7, 1.0); 
 
		for (layer = 0; layer < m_NumLayers; layer++) 
		{ 
			// lower layer is darker 
			t = max(0, 1 - 2 * float(layer) / (m_NumLayers-1)); 
			DATA(layer, x, y) = color * float(1 - 0.7 * pow(t, 1.5)); 
		} 
 
		// length of the hair 
		GLuint length = 1 + GLuint(m_NumLayers * pow(rnd(), 3)); 
		length = min(m_NumLayers, length); 
 
		for (layer = 0; layer < length; layer++) 
		{ 
			// tip of the hair is semi-transparent 
			t = max(0, -1 + 2 * float(layer+1) / length); 
			DATA(layer, x, y).a = 1 - 0.85 * pow(t, 2); 
		} 
	} 
 
	m_Textures = new GLuint[m_NumLayers]; 
	glGenTextures(m_NumLayers, m_Textures); 
 
	for (GLuint layer = 0; layer < m_NumLayers; layer++) 
	{ 
		DWORD *pixels = new DWORD[m_Size*m_Size]; 
		DWORD *p = pixels; 
		D3DXCOLOR *pColor = &DATA(layer, 0, 0); 
		for(GLuint i=0; i max_aniso) aniso = max_aniso; 
 
	for (GLuint layer = 0; layer < m_NumLayers; layer++) 
	{ 
		glBindTexture(GL_TEXTURE_2D, m_Textures[layer]); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso); 
	} 
} 
 
 
/////////////////////////////////////////////////////////////////////////////// 
 
//----------------------------------------------------------------------------- 
// BuildFurLightingTexture 
//----------------------------------------------------------------------------- 
void BuildFurLightingTexture() 
{ 
	#define CLAMP(x) max(0, min(1, (x))) 
 
	// texture size (as small as possible in order to minimize cache miss rate) 
	int s_size = 16; 
	int t_size = 32; 
	int r_size = 16; 
 
	// exponents for diffuse and specular 
	float diff_power = 6; 
	float spec_power = 32; 
 
	GLubyte *pixels = new GLubyte[2*s_size*t_size*r_size]; 
	GLubyte *p = pixels; 
 
	for(int k=0; k