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