Implement materials and lights.
Bug 22124687
Change-Id: Ic8a458962e370f372c2e97052c9c86f9b5c6dede
Reviewed-on: https://swiftshader-review.googlesource.com/3511
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp
index 0217cce..7096c32 100644
--- a/src/OpenGL/libGLES_CM/Context.cpp
+++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -30,6 +30,8 @@
#include <EGL/eglext.h>
+#include <algorithm>
+
#undef near
#undef far
@@ -180,6 +182,7 @@
materialDiffuse = {0.8f, 0.8f, 0.8f, 1.0f};
materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f};
materialEmission = {0.0f, 0.0f, 0.0f, 1.0f};
+ materialShininess = 0.0f;
matrixMode = GL_MODELVIEW;
@@ -601,6 +604,51 @@
light[index].attenuation.quadratic = quadratic;
}
+void Context::setGlobalAmbient(float red, float green, float blue, float alpha)
+{
+ globalAmbient.red = red;
+ globalAmbient.green = green;
+ globalAmbient.blue = blue;
+ globalAmbient.alpha = alpha;
+}
+
+void Context::setMaterialAmbient(float red, float green, float blue, float alpha)
+{
+ materialAmbient.red = red;
+ materialAmbient.green = green;
+ materialAmbient.blue = blue;
+ materialAmbient.alpha = alpha;
+}
+
+void Context::setMaterialDiffuse(float red, float green, float blue, float alpha)
+{
+ materialDiffuse.red = red;
+ materialDiffuse.green = green;
+ materialDiffuse.blue = blue;
+ materialDiffuse.alpha = alpha;
+}
+
+void Context::setMaterialSpecular(float red, float green, float blue, float alpha)
+{
+ materialSpecular.red = red;
+ materialSpecular.green = green;
+ materialSpecular.blue = blue;
+ materialSpecular.alpha = alpha;
+}
+
+void Context::setMaterialEmission(float red, float green, float blue, float alpha)
+{
+ materialEmission.red = red;
+ materialEmission.green = green;
+ materialEmission.blue = blue;
+ materialEmission.alpha = alpha;
+}
+
+void Context::setMaterialShininess(float shininess)
+{
+ materialShininess = shininess;
+}
+
void Context::setFog(bool enable)
{
device->setFogEnable(enable);
@@ -1732,9 +1780,11 @@
{
device->setLightPosition(i, sw::Point(light[i].position.x / light[i].position.w, light[i].position.y / light[i].position.w, light[i].position.z / light[i].position.w));
}
- else // Hack: set the position far way
+ else // Directional light
{
- device->setLightPosition(i, sw::Point(1e10f * light[i].position.x, 1e10f * light[i].position.y, 1e10f * light[i].position.z));
+ // Hack: set the position far way
+ float max = std::max(std::max(abs(light[i].position.x), abs(light[i].position.y)), abs(light[i].position.z));
+ device->setLightPosition(i, sw::Point(1e10f * (light[i].position.x / max), 1e10f * (light[i].position.y / max), 1e10f * (light[i].position.z / max)));
}
}
@@ -1742,6 +1792,7 @@
device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha));
device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha));
device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha));
+ device->setMaterialShininess(materialShininess);
device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
diff --git a/src/OpenGL/libGLES_CM/Context.h b/src/OpenGL/libGLES_CM/Context.h
index 644e6e8..71831e7 100644
--- a/src/OpenGL/libGLES_CM/Context.h
+++ b/src/OpenGL/libGLES_CM/Context.h
@@ -334,6 +334,13 @@
void setLightAttenuationConstant(int index, float constant);
void setLightAttenuationLinear(int index, float linear);
void setLightAttenuationQuadratic(int index, float quadratic);
+
+ void setGlobalAmbient(float red, float green, float blue, float alpha);
+ void setMaterialAmbient(float red, float green, float blue, float alpha);
+ void setMaterialDiffuse(float red, float green, float blue, float alpha);
+ void setMaterialSpecular(float red, float green, float blue, float alpha);
+ void setMaterialEmission(float red, float green, float blue, float alpha);
+ void setMaterialShininess(float shininess);
void setFog(bool enabled);
void setFogMode(GLenum mode);
@@ -508,6 +515,7 @@
Color materialDiffuse;
Color materialSpecular;
Color materialEmission;
+ GLfloat materialShininess;
// Recorded errors
bool mInvalidEnum;
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cpp b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
index b5fcdd6..749fced 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.cpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
@@ -2432,7 +2432,24 @@
void LightModelfv(GLenum pname, const GLfloat *params)
{
- UNIMPLEMENTED();
+ TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
+
+ es1::Context *context = es1::getContext();
+
+ if(context)
+ {
+ switch(pname)
+ {
+ case GL_LIGHT_MODEL_AMBIENT:
+ context->setGlobalAmbient(params[0], params[1], params[2], params[3]);
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ UNIMPLEMENTED();
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+ }
}
void LightModelx(GLenum pname, GLfixed param)
@@ -2447,7 +2464,30 @@
void Lightf(GLenum light, GLenum pname, GLfloat param)
{
- UNIMPLEMENTED();
+ TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param);
+
+ int index = light - GL_LIGHT0;
+
+ if(index < 0 || index >= es1::MAX_LIGHTS)
+ {
+ return error(GL_INVALID_ENUM);
+ }
+
+ es1::Context *context = es1::getContext();
+
+ if(context)
+ {
+ switch(pname)
+ {
+ case GL_SPOT_EXPONENT: UNIMPLEMENTED(); break;
+ case GL_SPOT_CUTOFF: UNIMPLEMENTED(); break;
+ case GL_CONSTANT_ATTENUATION: context->setLightAttenuationConstant(index, param); break;
+ case GL_LINEAR_ATTENUATION: context->setLightAttenuationLinear(index, param); break;
+ case GL_QUADRATIC_ATTENUATION: context->setLightAttenuationQuadratic(index, param); break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+ }
}
void Lightfv(GLenum light, GLenum pname, const GLfloat *params)
@@ -2551,12 +2591,66 @@
void Materialf(GLenum face, GLenum pname, GLfloat param)
{
- UNIMPLEMENTED();
+ TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param);
+
+ if(face != GL_FRONT_AND_BACK)
+ {
+ return error(GL_INVALID_ENUM);
+ }
+
+ es1::Context *context = es1::getContext();
+
+ if(context)
+ {
+ switch(pname)
+ {
+ case GL_SHININESS:
+ context->setMaterialShininess(param);
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+ }
}
void Materialfv(GLenum face, GLenum pname, const GLfloat *params)
{
- UNIMPLEMENTED();
+ TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname);
+
+ if(face != GL_FRONT_AND_BACK)
+ {
+ return error(GL_INVALID_ENUM);
+ }
+
+ es1::Context *context = es1::getContext();
+
+ if(context)
+ {
+ switch(pname)
+ {
+ case GL_AMBIENT:
+ context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
+ break;
+ case GL_DIFFUSE:
+ context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
+ context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
+ break;
+ case GL_SPECULAR:
+ context->setMaterialSpecular(params[0], params[1], params[2], params[3]);
+ break;
+ case GL_EMISSION:
+ context->setMaterialEmission(params[0], params[1], params[2], params[3]);
+ break;
+ case GL_SHININESS:
+ context->setMaterialShininess(params[0]);
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+ }
}
void Materialx(GLenum face, GLenum pname, GLfixed param)