#include "SceneCache.h"
namespace
{
const float ANGLE_TO_RADIAN = 3.1415926f / 180.f;
const GLfloat BLACK_COLOR[] = {0.0f, 0.0f, 0.0f, 1.0f};
const GLfloat GREEN_COLOR[] = {0.0f, 1.0f, 0.0f, 1.0f};
const GLfloat WHITE_COLOR[] = {1.0f, 1.0f, 1.0f, 1.0f};
const GLfloat WIREFRAME_COLOR[] = {0.5f, 0.5f, 0.5f, 1.0f};
const int TRIANGLE_VERTEX_COUNT = 3;
const int VERTEX_STRIDE = 4;
const int NORMAL_STRIDE = 3;
const int UV_STRIDE = 2;
const GLfloat DEFAULT_LIGHT_POSITION[] = {0.0f, 0.0f, 0.0f, 1.0f};
const GLfloat DEFAULT_DIRECTION_LIGHT_POSITION[] = {0.0f, 0.0f, 1.0f, 0.0f};
const GLfloat DEFAULT_SPOT_LIGHT_DIRECTION[] = {0.0f, 0.0f, -1.0f};
const GLfloat DEFAULT_LIGHT_COLOR[] = {1.0f, 1.0f, 1.0f, 1.0f};
const GLfloat DEFAULT_LIGHT_SPOT_CUTOFF = 180.0f;
FbxDouble3 GetMaterialProperty(const FbxSurfaceMaterial * pMaterial,
const char * pPropertyName,
const char * pFactorPropertyName,
GLuint & pTextureName)
{
FbxDouble3 lResult(0, 0, 0);
const FbxProperty lProperty = pMaterial->FindProperty(pPropertyName);
const FbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName);
if (lProperty.IsValid() && lFactorProperty.IsValid())
{
lResult = lProperty.Get<FbxDouble3>();
double lFactor = lFactorProperty.Get<FbxDouble>();
if (lFactor != 1)
{
lResult[0] *= lFactor;
lResult[1] *= lFactor;
lResult[2] *= lFactor;
}
}
if (lProperty.IsValid())
{
const int lTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>();
if (lTextureCount)
{
const FbxFileTexture* lTexture = lProperty.GetSrcObject<FbxFileTexture>();
if (lTexture && lTexture->GetUserDataPtr())
{
pTextureName = *(static_cast<GLuint *>(lTexture->GetUserDataPtr()));
}
}
}
return lResult;
}
}
VBOMesh::VBOMesh() : mHasNormal(false), mHasUV(false), mAllByControlPoint(true)
{
for (int lVBOIndex = 0; lVBOIndex < VBO_COUNT; ++lVBOIndex)
{
mVBONames[lVBOIndex] = 0;
}
}
VBOMesh::~VBOMesh()
{
glDeleteBuffers(VBO_COUNT, mVBONames);
for(int i=0; i < mSubMeshes.GetCount(); i++)
{
delete mSubMeshes[i];
}
mSubMeshes.Clear();
}
bool VBOMesh::Initialize(const FbxMesh *pMesh)
{
if (!pMesh->GetNode())
return false;
const int lPolygonCount = pMesh->GetPolygonCount();
FbxLayerElementArrayTemplate<int>* lMaterialIndice = NULL;
FbxGeometryElement::EMappingMode lMaterialMappingMode = FbxGeometryElement::eNone;
if (pMesh->GetElementMaterial())
{
lMaterialIndice = &pMesh->GetElementMaterial()->GetIndexArray();
lMaterialMappingMode = pMesh->GetElementMaterial()->GetMappingMode();
if (lMaterialIndice && lMaterialMappingMode == FbxGeometryElement::eByPolygon)
{
FBX_ASSERT(lMaterialIndice->GetCount() == lPolygonCount);
if (lMaterialIndice->GetCount() == lPolygonCount)
{
for (int lPolygonIndex = 0; lPolygonIndex < lPolygonCount; ++lPolygonIndex)
{
const int lMaterialIndex = lMaterialIndice->GetAt(lPolygonIndex);
if (mSubMeshes.GetCount() < lMaterialIndex + 1)
{
mSubMeshes.Resize(lMaterialIndex + 1);
}
if (mSubMeshes[lMaterialIndex] == NULL)
{
mSubMeshes[lMaterialIndex] = new SubMesh;
}
mSubMeshes[lMaterialIndex]->TriangleCount += 1;
}
for (int i = 0; i < mSubMeshes.GetCount(); i++)
{
if (mSubMeshes[i] == NULL)
mSubMeshes[i] = new SubMesh;
}
const int lMaterialCount = mSubMeshes.GetCount();
int lOffset = 0;
for (int lIndex = 0; lIndex < lMaterialCount; ++lIndex)
{
mSubMeshes[lIndex]->IndexOffset = lOffset;
lOffset += mSubMeshes[lIndex]->TriangleCount * 3;
mSubMeshes[lIndex]->TriangleCount = 0;
}
FBX_ASSERT(lOffset == lPolygonCount * 3);
}
}
}
if (mSubMeshes.GetCount() == 0)
{
mSubMeshes.Resize(1);
mSubMeshes[0] = new SubMesh();
}
mHasNormal = pMesh->GetElementNormalCount() > 0;
mHasUV = pMesh->GetElementUVCount() > 0;
FbxGeometryElement::EMappingMode lNormalMappingMode = FbxGeometryElement::eNone;
FbxGeometryElement::EMappingMode lUVMappingMode = FbxGeometryElement::eNone;
if (mHasNormal)
{
lNormalMappingMode = pMesh->GetElementNormal(0)->GetMappingMode();
if (lNormalMappingMode == FbxGeometryElement::eNone)
{
mHasNormal = false;
}
if (mHasNormal && lNormalMappingMode != FbxGeometryElement::eByControlPoint)
{
mAllByControlPoint = false;
}
}
if (mHasUV)
{
lUVMappingMode = pMesh->GetElementUV(0)->GetMappingMode();
if (lUVMappingMode == FbxGeometryElement::eNone)
{
mHasUV = false;
}
if (mHasUV && lUVMappingMode != FbxGeometryElement::eByControlPoint)
{
mAllByControlPoint = false;
}
}
int lPolygonVertexCount = pMesh->GetControlPointsCount();
if (!mAllByControlPoint)
{
lPolygonVertexCount = lPolygonCount * TRIANGLE_VERTEX_COUNT;
}
float * lVertices = new float[lPolygonVertexCount * VERTEX_STRIDE];
unsigned int * lIndices = new unsigned int[lPolygonCount * TRIANGLE_VERTEX_COUNT];
float * lNormals = NULL;
if (mHasNormal)
{
lNormals = new float[lPolygonVertexCount * NORMAL_STRIDE];
}
float * lUVs = NULL;
FbxStringList lUVNames;
pMesh->GetUVSetNames(lUVNames);
const char * lUVName = NULL;
if (mHasUV && lUVNames.GetCount())
{
lUVs = new float[lPolygonVertexCount * UV_STRIDE];
lUVName = lUVNames[0];
}
const FbxVector4 * lControlPoints = pMesh->GetControlPoints();
FbxVector4 lCurrentVertex;
FbxVector4 lCurrentNormal;
FbxVector2 lCurrentUV;
if (mAllByControlPoint)
{
const FbxGeometryElementNormal * lNormalElement = NULL;
const FbxGeometryElementUV * lUVElement = NULL;
if (mHasNormal)
{
lNormalElement = pMesh->GetElementNormal(0);
}
if (mHasUV)
{
lUVElement = pMesh->GetElementUV(0);
}
for (int lIndex = 0; lIndex < lPolygonVertexCount; ++lIndex)
{
lCurrentVertex = lControlPoints[lIndex];
lVertices[lIndex * VERTEX_STRIDE] = static_cast<float>(lCurrentVertex[0]);
lVertices[lIndex * VERTEX_STRIDE + 1] = static_cast<float>(lCurrentVertex[1]);
lVertices[lIndex * VERTEX_STRIDE + 2] = static_cast<float>(lCurrentVertex[2]);
lVertices[lIndex * VERTEX_STRIDE + 3] = 1;
if (mHasNormal)
{
int lNormalIndex = lIndex;
if (lNormalElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
{
lNormalIndex = lNormalElement->GetIndexArray().GetAt(lIndex);
}
lCurrentNormal = lNormalElement->GetDirectArray().GetAt(lNormalIndex);
lNormals[lIndex * NORMAL_STRIDE] = static_cast<float>(lCurrentNormal[0]);
lNormals[lIndex * NORMAL_STRIDE + 1] = static_cast<float>(lCurrentNormal[1]);
lNormals[lIndex * NORMAL_STRIDE + 2] = static_cast<float>(lCurrentNormal[2]);
}
if (mHasUV)
{
int lUVIndex = lIndex;
if (lUVElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
{
lUVIndex = lUVElement->GetIndexArray().GetAt(lIndex);
}
lCurrentUV = lUVElement->GetDirectArray().GetAt(lUVIndex);
lUVs[lIndex * UV_STRIDE] = static_cast<float>(lCurrentUV[0]);
lUVs[lIndex * UV_STRIDE + 1] = static_cast<float>(lCurrentUV[1]);
}
}
}
int lVertexCount = 0;
for (int lPolygonIndex = 0; lPolygonIndex < lPolygonCount; ++lPolygonIndex)
{
int lMaterialIndex = 0;
if (lMaterialIndice && lMaterialMappingMode == FbxGeometryElement::eByPolygon)
{
lMaterialIndex = lMaterialIndice->GetAt(lPolygonIndex);
}
const int lIndexOffset = mSubMeshes[lMaterialIndex]->IndexOffset +
mSubMeshes[lMaterialIndex]->TriangleCount * 3;
for (int lVerticeIndex = 0; lVerticeIndex < TRIANGLE_VERTEX_COUNT; ++lVerticeIndex)
{
const int lControlPointIndex = pMesh->GetPolygonVertex(lPolygonIndex, lVerticeIndex);
if (mAllByControlPoint)
{
lIndices[lIndexOffset + lVerticeIndex] = static_cast<unsigned int>(lControlPointIndex);
}
else
{
lIndices[lIndexOffset + lVerticeIndex] = static_cast<unsigned int>(lVertexCount);
lCurrentVertex = lControlPoints[lControlPointIndex];
lVertices[lVertexCount * VERTEX_STRIDE] = static_cast<float>(lCurrentVertex[0]);
lVertices[lVertexCount * VERTEX_STRIDE + 1] = static_cast<float>(lCurrentVertex[1]);
lVertices[lVertexCount * VERTEX_STRIDE + 2] = static_cast<float>(lCurrentVertex[2]);
lVertices[lVertexCount * VERTEX_STRIDE + 3] = 1;
if (mHasNormal)
{
pMesh->GetPolygonVertexNormal(lPolygonIndex, lVerticeIndex, lCurrentNormal);
lNormals[lVertexCount * NORMAL_STRIDE] = static_cast<float>(lCurrentNormal[0]);
lNormals[lVertexCount * NORMAL_STRIDE + 1] = static_cast<float>(lCurrentNormal[1]);
lNormals[lVertexCount * NORMAL_STRIDE + 2] = static_cast<float>(lCurrentNormal[2]);
}
if (mHasUV)
{
bool lUnmappedUV;
pMesh->GetPolygonVertexUV(lPolygonIndex, lVerticeIndex, lUVName, lCurrentUV, lUnmappedUV);
lUVs[lVertexCount * UV_STRIDE] = static_cast<float>(lCurrentUV[0]);
lUVs[lVertexCount * UV_STRIDE + 1] = static_cast<float>(lCurrentUV[1]);
}
}
++lVertexCount;
}
mSubMeshes[lMaterialIndex]->TriangleCount += 1;
}
glGenBuffers(VBO_COUNT, mVBONames);
glBindBuffer(GL_ARRAY_BUFFER, mVBONames[VERTEX_VBO]);
glBufferData(GL_ARRAY_BUFFER, lPolygonVertexCount * VERTEX_STRIDE * sizeof(float), lVertices, GL_STATIC_DRAW);
delete [] lVertices;
if (mHasNormal)
{
glBindBuffer(GL_ARRAY_BUFFER, mVBONames[NORMAL_VBO]);
glBufferData(GL_ARRAY_BUFFER, lPolygonVertexCount * NORMAL_STRIDE * sizeof(float), lNormals, GL_STATIC_DRAW);
delete [] lNormals;
}
if (mHasUV)
{
glBindBuffer(GL_ARRAY_BUFFER, mVBONames[UV_VBO]);
glBufferData(GL_ARRAY_BUFFER, lPolygonVertexCount * UV_STRIDE * sizeof(float), lUVs, GL_STATIC_DRAW);
delete [] lUVs;
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mVBONames[INDEX_VBO]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, lPolygonCount * TRIANGLE_VERTEX_COUNT * sizeof(unsigned int), lIndices, GL_STATIC_DRAW);
delete [] lIndices;
return true;
}
void VBOMesh::UpdateVertexPosition(const FbxMesh * pMesh, const FbxVector4 * pVertices) const
{
float * lVertices = NULL;
int lVertexCount = 0;
if (mAllByControlPoint)
{
lVertexCount = pMesh->GetControlPointsCount();
lVertices = new float[lVertexCount * VERTEX_STRIDE];
for (int lIndex = 0; lIndex < lVertexCount; ++lIndex)
{
lVertices[lIndex * VERTEX_STRIDE] = static_cast<float>(pVertices[lIndex][0]);
lVertices[lIndex * VERTEX_STRIDE + 1] = static_cast<float>(pVertices[lIndex][1]);
lVertices[lIndex * VERTEX_STRIDE + 2] = static_cast<float>(pVertices[lIndex][2]);
lVertices[lIndex * VERTEX_STRIDE + 3] = 1;
}
}
else
{
const int lPolygonCount = pMesh->GetPolygonCount();
lVertexCount = lPolygonCount * TRIANGLE_VERTEX_COUNT;
lVertices = new float[lVertexCount * VERTEX_STRIDE];
int lVertexCount = 0;
for (int lPolygonIndex = 0; lPolygonIndex < lPolygonCount; ++lPolygonIndex)
{
for (int lVerticeIndex = 0; lVerticeIndex < TRIANGLE_VERTEX_COUNT; ++lVerticeIndex)
{
const int lControlPointIndex = pMesh->GetPolygonVertex(lPolygonIndex, lVerticeIndex);
lVertices[lVertexCount * VERTEX_STRIDE] = static_cast<float>(pVertices[lControlPointIndex][0]);
lVertices[lVertexCount * VERTEX_STRIDE + 1] = static_cast<float>(pVertices[lControlPointIndex][1]);
lVertices[lVertexCount * VERTEX_STRIDE + 2] = static_cast<float>(pVertices[lControlPointIndex][2]);
lVertices[lVertexCount * VERTEX_STRIDE + 3] = 1;
++lVertexCount;
}
}
}
if (lVertices)
{
glBindBuffer(GL_ARRAY_BUFFER, mVBONames[VERTEX_VBO]);
glBufferData(GL_ARRAY_BUFFER, lVertexCount * VERTEX_STRIDE * sizeof(float), lVertices, GL_STATIC_DRAW);
delete [] lVertices;
}
}
void VBOMesh::Draw(int pMaterialIndex, ShadingMode pShadingMode) const
{
GLsizei lOffset = mSubMeshes[pMaterialIndex]->IndexOffset * sizeof(unsigned int);
if ( pShadingMode == SHADING_MODE_SHADED)
{
const GLsizei lElementCount = mSubMeshes[pMaterialIndex]->TriangleCount * 3;
glDrawElements(GL_TRIANGLES, lElementCount, GL_UNSIGNED_INT, reinterpret_cast<const GLvoid *>(lOffset));
}
else
{
for (int lIndex = 0; lIndex < mSubMeshes[pMaterialIndex]->TriangleCount; ++lIndex)
{
glDrawElements(GL_LINE_LOOP, TRIANGLE_VERTEX_COUNT, GL_UNSIGNED_INT, reinterpret_cast<const GLvoid *>(lOffset));
lOffset += sizeof(unsigned int) * TRIANGLE_VERTEX_COUNT;
}
}
}
void VBOMesh::BeginDraw(ShadingMode pShadingMode) const
{
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
glPushAttrib(GL_ENABLE_BIT);
glPushAttrib(GL_CURRENT_BIT);
glPushAttrib(GL_LIGHTING_BIT);
glPushAttrib(GL_TEXTURE_BIT);
glBindBuffer(GL_ARRAY_BUFFER, mVBONames[VERTEX_VBO]);
glVertexPointer(VERTEX_STRIDE, GL_FLOAT, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
if (mHasNormal && pShadingMode == SHADING_MODE_SHADED)
{
glBindBuffer(GL_ARRAY_BUFFER, mVBONames[NORMAL_VBO]);
glNormalPointer(GL_FLOAT, 0, 0);
glEnableClientState(GL_NORMAL_ARRAY);
}
if (mHasUV && pShadingMode == SHADING_MODE_SHADED)
{
glBindBuffer(GL_ARRAY_BUFFER, mVBONames[UV_VBO]);
glTexCoordPointer(UV_STRIDE, GL_FLOAT, 0, 0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mVBONames[INDEX_VBO]);
if (pShadingMode == SHADING_MODE_SHADED)
{
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glEnable(GL_NORMALIZE);
}
else
{
glColor4fv(WIREFRAME_COLOR);
}
}
void VBOMesh::EndDraw() const
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glPopAttrib();
glPopAttrib();
glPopAttrib();
glPopAttrib();
glPopClientAttrib();
}
MaterialCache::MaterialCache() : mShinness(0)
{
}
MaterialCache::~MaterialCache()
{
}
bool MaterialCache::Initialize(const FbxSurfaceMaterial * pMaterial)
{
const FbxDouble3 lEmissive = GetMaterialProperty(pMaterial,
FbxSurfaceMaterial::sEmissive, FbxSurfaceMaterial::sEmissiveFactor, mEmissive.mTextureName);
mEmissive.mColor[0] = static_cast<GLfloat>(lEmissive[0]);
mEmissive.mColor[1] = static_cast<GLfloat>(lEmissive[1]);
mEmissive.mColor[2] = static_cast<GLfloat>(lEmissive[2]);
const FbxDouble3 lAmbient = GetMaterialProperty(pMaterial,
FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor, mAmbient.mTextureName);
mAmbient.mColor[0] = static_cast<GLfloat>(lAmbient[0]);
mAmbient.mColor[1] = static_cast<GLfloat>(lAmbient[1]);
mAmbient.mColor[2] = static_cast<GLfloat>(lAmbient[2]);
const FbxDouble3 lDiffuse = GetMaterialProperty(pMaterial,
FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor, mDiffuse.mTextureName);
mDiffuse.mColor[0] = static_cast<GLfloat>(lDiffuse[0]);
mDiffuse.mColor[1] = static_cast<GLfloat>(lDiffuse[1]);
mDiffuse.mColor[2] = static_cast<GLfloat>(lDiffuse[2]);
const FbxDouble3 lSpecular = GetMaterialProperty(pMaterial,
FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor, mSpecular.mTextureName);
mSpecular.mColor[0] = static_cast<GLfloat>(lSpecular[0]);
mSpecular.mColor[1] = static_cast<GLfloat>(lSpecular[1]);
mSpecular.mColor[2] = static_cast<GLfloat>(lSpecular[2]);
FbxProperty lShininessProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sShininess);
if (lShininessProperty.IsValid())
{
double lShininess = lShininessProperty.Get<FbxDouble>();
mShinness = static_cast<GLfloat>(lShininess);
}
return true;
}
void MaterialCache::SetCurrentMaterial() const
{
glMaterialfv(GL_FRONT, GL_EMISSION, mEmissive.mColor);
glMaterialfv(GL_FRONT, GL_AMBIENT, mAmbient.mColor);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mDiffuse.mColor);
glMaterialfv(GL_FRONT, GL_SPECULAR, mSpecular.mColor);
glMaterialf(GL_FRONT, GL_SHININESS, mShinness);
glBindTexture(GL_TEXTURE_2D, mDiffuse.mTextureName);
}
void MaterialCache::SetDefaultMaterial()
{
glMaterialfv(GL_FRONT, GL_EMISSION, BLACK_COLOR);
glMaterialfv(GL_FRONT, GL_AMBIENT, BLACK_COLOR);
glMaterialfv(GL_FRONT, GL_DIFFUSE, GREEN_COLOR);
glMaterialfv(GL_FRONT, GL_SPECULAR, BLACK_COLOR);
glMaterialf(GL_FRONT, GL_SHININESS, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
int LightCache::sLightCount = 0;
LightCache::LightCache() : mType(FbxLight::ePoint)
{
mLightIndex = GL_LIGHT0 + sLightCount++;
}
LightCache::~LightCache()
{
glDisable(mLightIndex);
--sLightCount;
}
bool LightCache::Initialize(const FbxLight * pLight, FbxAnimLayer * pAnimLayer)
{
mType = pLight->LightType.Get();
FbxPropertyT<FbxDouble3> lColorProperty = pLight->Color;
FbxDouble3 lLightColor = lColorProperty.Get();
mColorRed.mValue = static_cast<float>(lLightColor[0]);
mColorGreen.mValue = static_cast<float>(lLightColor[1]);
mColorBlue.mValue = static_cast<float>(lLightColor[2]);
mColorRed.mAnimCurve = lColorProperty.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COLOR_RED);
mColorGreen.mAnimCurve = lColorProperty.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COLOR_GREEN);
mColorBlue.mAnimCurve = lColorProperty.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COLOR_BLUE);
if (mType == FbxLight::eSpot)
{
FbxPropertyT<FbxDouble> lConeAngleProperty = pLight->InnerAngle;
mConeAngle.mValue = static_cast<GLfloat>(lConeAngleProperty.Get());
mConeAngle.mAnimCurve = lConeAngleProperty.GetCurve(pAnimLayer);
}
return true;
}
void LightCache::SetLight(const FbxTime & pTime) const
{
const GLfloat lLightColor[4] = {mColorRed.Get(pTime), mColorGreen.Get(pTime), mColorBlue.Get(pTime), 1.0f};
const GLfloat lConeAngle = mConeAngle.Get(pTime);
glColor3fv(lLightColor);
glPushAttrib(GL_ENABLE_BIT);
glPushAttrib(GL_POLYGON_BIT);
glDisable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
if (mType == FbxLight::eSpot)
{
glPushMatrix();
glScalef(1.0f, 1.0f, -1.0f);
const double lRadians = ANGLE_TO_RADIAN * lConeAngle;
const double lHeight = 15.0;
const double lBase = lHeight * tan(lRadians / 2);
GLUquadricObj * lQuadObj = gluNewQuadric();
gluCylinder(lQuadObj, 0.0, lBase, lHeight, 18, 1);
gluDeleteQuadric(lQuadObj);
glPopMatrix();
}
else
{
GLUquadricObj * lQuadObj = gluNewQuadric();
gluSphere(lQuadObj, 1.0, 10, 10);
gluDeleteQuadric(lQuadObj);
}
glPopAttrib();
glPopAttrib();
if (mType == FbxLight::eDirectional)
{
glLightfv(mLightIndex, GL_POSITION, DEFAULT_DIRECTION_LIGHT_POSITION);
}
else
{
glLightfv(mLightIndex, GL_POSITION, DEFAULT_LIGHT_POSITION);
}
glLightfv(mLightIndex, GL_DIFFUSE, lLightColor);
glLightfv(mLightIndex, GL_SPECULAR, lLightColor);
if (mType == FbxLight::eSpot && lConeAngle != 0.0)
{
glLightfv(mLightIndex, GL_SPOT_DIRECTION, DEFAULT_SPOT_LIGHT_DIRECTION);
if (lConeAngle != 0.0f)
{
glLightf(mLightIndex, GL_SPOT_CUTOFF, lConeAngle/2);
}
}
glEnable(mLightIndex);
}
void LightCache::IntializeEnvironment(const FbxColor & pAmbientLight)
{
glLightfv(GL_LIGHT0, GL_POSITION, DEFAULT_DIRECTION_LIGHT_POSITION);
glLightfv(GL_LIGHT0, GL_DIFFUSE, DEFAULT_LIGHT_COLOR);
glLightfv(GL_LIGHT0, GL_SPECULAR, DEFAULT_LIGHT_COLOR);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, DEFAULT_LIGHT_SPOT_CUTOFF);
glEnable(GL_LIGHT0);
GLfloat lAmbientLight[] = {static_cast<GLfloat>(pAmbientLight[0]), static_cast<GLfloat>(pAmbientLight[1]),
static_cast<GLfloat>(pAmbientLight[2]), 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lAmbientLight);
}