#include "common.h" #include "Material.h" #include "Texture.h" #include "glInterface.h" #include "RenderState.h" using namespace std; namespace CHCDemoEngine { RgbaColor RandomColor(float a, float b) { return RgbaColor(a + Random(b), a + Random(b), a + Random(b), 1); } void Technique::Init() { mTexture = NULL; mAlphaTestEnabled = false; mCullFaceEnabled = true; mVertexProgramParameters.Reset(); mFragmentProgramParameters.Reset(); mVertexProgram = NULL; mFragmentProgram = NULL; // if this material can write colors mColorWriteEnabled = true; // if lighting is used mLightingEnabled = true; /// if depth write should be enabled mDepthWriteEnabled = true; /// the render queue bucket this technique is assigned to mRenderQueueBucket = NULL; } Technique::Technique(): mAmbientColor(RgbaColor(0.2f, 0.2f, 0.2f, 1.0f)), mDiffuseColor(RgbaColor(1.0f, 1.0f, 1.0f, 1.0f)), mSpecularColor(RgbaColor(.0f, .0f, .0f, 1.0f)), mEmmisiveColor(RgbaColor(.0f, .0f, .0f, 1.0f)) { Init(); } Technique::Technique(const RgbaColor &color): mDiffuseColor(color), mAmbientColor(color), mSpecularColor(0, 0, 0, 1), mTexture(NULL) { Init(); } void Technique::Render(RenderState *state, SceneEntity *ent) { glMaterialfv(GL_FRONT, GL_AMBIENT, (float *)&mAmbientColor.r); glMaterialfv(GL_FRONT, GL_DIFFUSE, (float *)&mDiffuseColor.r); glMaterialfv(GL_FRONT, GL_EMISSION, (float *)&mEmmisiveColor.r); glMaterialfv(GL_FRONT, GL_SPECULAR, (float *)&mSpecularColor.r); state->SetState(this, ent); } void Technique::SetFragmentProgram(ShaderProgram *p) { if (p->GetProgramType() == ShaderProgram::VERTEX_PROGRAM) cerr << "warning: assigning a vertex program as fragment program!" << endl; mFragmentProgram = p; mFragmentProgramParameters.Reset(); mFragmentProgramParameters.SetProgram(p); } void Technique::SetVertexProgram(ShaderProgram *p) { if (p->GetProgramType() == ShaderProgram::FRAGMENT_PROGRAM) cerr << "warning: assigning a fragment program as vertex program!" << endl; mVertexProgram = p; mVertexProgramParameters.Reset(); mVertexProgramParameters.SetProgram(p); } /***************************************************/ /* class Material implementation */ /***************************************************/ void Material::Render(RenderState *state, SceneEntity *parent) { // set technique if available int idx = min((int)mTechniques.size() - 1 , state->GetRenderTechnique()); mTechniques[idx]->Render(state, parent); } Technique *Material::GetDefaultTechnique() const { return mTechniques[0]; } Technique *Material::GetTechnique(int i) const { return mTechniques[i]; } Material::Material() { Technique *tech = new Technique(); mTechniques.push_back(tech); } Material::~Material() { CLEAR_CONTAINER(mTechniques); } int Material::GetNumTechniques() const { return (int)mTechniques.size(); } void Material::AddTechnique(Technique *tech) { mTechniques.push_back(tech); } }