Commit e1a3282f by Nicolas Capens Committed by Nicolas Capens

Implement fixed-function lighting.

BUG=18110152 Change-Id: I14539562fbc4f292c965287972da580c98fb1ba9 Reviewed-on: https://swiftshader-review.googlesource.com/1281Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent f3d2efd8
......@@ -136,6 +136,28 @@ Context::Context(const egl::Config *config, const Context *shareContext) : mConf
mOutOfMemory = false;
mInvalidFramebufferOperation = false;
lighting = false;
for(int i = 0; i < MAX_LIGHTS; i++)
{
light[i].enable = false;
light[i].ambient = {0.0f, 0.0f, 0.0f, 1.0f};
light[i].diffuse = {0.0f, 0.0f, 0.0f, 1.0f};
light[i].specular = {0.0f, 0.0f, 0.0f, 1.0f};
light[i].position = {0.0f, 0.0f, 1.0f, 0.0f};
light[i].direction = {0.0f, 0.0f, -1.0f};
light[i].attenuation = {1.0f, 0.0f, 0.0f};
}
light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
light[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
globalAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
materialAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
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};
mHasBeenCurrent = false;
markAllStateDirty();
......@@ -493,6 +515,56 @@ bool Context::isDitherEnabled() const
return mState.dither;
}
void Context::setLighting(bool enable)
{
lighting = enable;
}
void Context::setLight(int index, bool enable)
{
light[index].enable = enable;
}
void Context::setLightAmbient(int index, float r, float g, float b, float a)
{
light[index].ambient = {r, g, b, a};
}
void Context::setLightDiffuse(int index, float r, float g, float b, float a)
{
light[index].diffuse = {r, g, b, a};
}
void Context::setLightSpecular(int index, float r, float g, float b, float a)
{
light[index].specular = {r, g, b, a};
}
void Context::setLightPosition(int index, float x, float y, float z, float w)
{
light[index].position = {x, y, z, w};
}
void Context::setLightDirection(int index, float x, float y, float z)
{
light[index].direction = {x, y, z};
}
void Context::setLightAttenuationConstant(int index, float constant)
{
light[index].attenuation.constant = constant;
}
void Context::setLightAttenuationLinear(int index, float linear)
{
light[index].attenuation.linear = linear;
}
void Context::setLightAttenuationQuadratic(int index, float quadratic)
{
light[index].attenuation.quadratic = quadratic;
}
void Context::setLineWidth(GLfloat width)
{
mState.lineWidth = width;
......@@ -1076,6 +1148,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
*params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].id();
}
break;
case GL_MAX_LIGHTS: *params = MAX_LIGHTS; break;
default:
return false;
}
......@@ -1171,6 +1244,7 @@ int Context::getQueryParameterNum(GLenum pname)
case GL_COLOR_CLEAR_VALUE:
return 4;
case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
case GL_MAX_LIGHTS:
return 1;
default:
UNREACHABLE();
......@@ -1236,6 +1310,7 @@ bool Context::isQueryParameterInt(GLenum pname)
case GL_MAX_VIEWPORT_DIMS:
case GL_VIEWPORT:
case GL_SCISSOR_BOX:
case GL_MAX_LIGHTS:
return true;
default:
ASSERT(isQueryParameterFloat(pname) || isQueryParameterBool(pname));
......@@ -1520,6 +1595,37 @@ void Context::applyState(GLenum drawMode)
mDitherStateDirty = false;
}
device->setLightingEnable(lighting);
device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha));
for(int i = 0; i < MAX_LIGHTS; i++)
{
device->setLightEnable(i, light[i].enable);
device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha));
device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha));
device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha));
device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic);
if(light[i].position.w != 0.0f)
{
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
{
device->setLightPosition(i, sw::Point(1e10f * light[i].position.x, 1e10f * light[i].position.y, 1e10f * light[i].position.z));
}
}
device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha));
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->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
}
GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
......
......@@ -69,6 +69,7 @@ enum
MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS,
MAX_FRAGMENT_UNIFORM_VECTORS = 224 - 3, // Reserve space for gl_DepthRange
MAX_DRAW_BUFFERS = 1,
MAX_LIGHTS = 8,
IMPLEMENTATION_COLOR_READ_FORMAT = GL_RGB,
IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_SHORT_5_6_5
......@@ -96,6 +97,39 @@ struct Color
float alpha;
};
struct Point
{
float x;
float y;
float z;
float w;
};
struct Vector
{
float x;
float y;
float z;
};
struct Attenuation
{
float constant;
float linear;
float quadratic;
};
struct Light
{
bool enable;
Color ambient;
Color diffuse;
Color specular;
Point position;
Vector direction;
Attenuation attenuation;
};
// Helper structure describing a single vertex attribute
class VertexAttribute
{
......@@ -268,6 +302,16 @@ public:
void setDither(bool enabled);
bool isDitherEnabled() const;
void setLighting(bool enabled);
void setLight(int index, bool enable);
void setLightAmbient(int index, float r, float g, float b, float a);
void setLightDiffuse(int index, float r, float g, float b, float a);
void setLightSpecular(int index, float r, float g, float b, float a);
void setLightPosition(int index, float x, float y, float z, float w);
void setLightDirection(int index, float x, float y, float z);
void setLightAttenuationConstant(int index, float constant);
void setLightAttenuationLinear(int index, float linear);
void setLightAttenuationQuadratic(int index, float quadratic);
void setLineWidth(GLfloat width);
......@@ -406,6 +450,14 @@ private:
VertexDataManager *mVertexDataManager;
IndexDataManager *mIndexDataManager;
bool lighting;
Light light[MAX_LIGHTS];
Color globalAmbient;
Color materialAmbient;
Color materialDiffuse;
Color materialSpecular;
Color materialEmission;
// Recorded errors
bool mInvalidEnum;
bool mInvalidValue;
......
......@@ -1568,16 +1568,40 @@ void GL_APIENTRY glDisable(GLenum cap)
{
switch(cap)
{
case GL_CULL_FACE: context->setCullFace(false); break;
case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
case GL_SCISSOR_TEST: context->setScissorTest(false); break;
case GL_STENCIL_TEST: context->setStencilTest(false); break;
case GL_DEPTH_TEST: context->setDepthTest(false); break;
case GL_BLEND: context->setBlend(false); break;
case GL_DITHER: context->setDither(false); break;
default:
case GL_CULL_FACE: context->setCullFace(false); break;
case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
case GL_SCISSOR_TEST: context->setScissorTest(false); break;
case GL_STENCIL_TEST: context->setStencilTest(false); break;
case GL_DEPTH_TEST: context->setDepthTest(false); break;
case GL_BLEND: context->setBlend(false); break;
case GL_DITHER: context->setDither(false); break;
case GL_LIGHTING: context->setLighting(false); break;
case GL_LIGHT0: context->setLight(0, false); break;
case GL_LIGHT1: context->setLight(1, false); break;
case GL_LIGHT2: context->setLight(2, false); break;
case GL_LIGHT3: context->setLight(3, false); break;
case GL_LIGHT4: context->setLight(4, false); break;
case GL_LIGHT5: context->setLight(5, false); break;
case GL_LIGHT6: context->setLight(6, false); break;
case GL_LIGHT7: context->setLight(7, false); break;
case GL_FOG: UNIMPLEMENTED(); break;
case GL_TEXTURE_2D: UNIMPLEMENTED(); break;
case GL_ALPHA_TEST: UNIMPLEMENTED(); break;
case GL_COLOR_LOGIC_OP: UNIMPLEMENTED(); break;
case GL_POINT_SMOOTH: UNIMPLEMENTED(); break;
case GL_LINE_SMOOTH: UNIMPLEMENTED(); break;
case GL_COLOR_MATERIAL: UNIMPLEMENTED(); break;
case GL_NORMALIZE: UNIMPLEMENTED(); break;
case GL_RESCALE_NORMAL: UNIMPLEMENTED(); break;
case GL_VERTEX_ARRAY: UNIMPLEMENTED(); break;
case GL_NORMAL_ARRAY: UNIMPLEMENTED(); break;
case GL_COLOR_ARRAY: UNIMPLEMENTED(); break;
case GL_TEXTURE_COORD_ARRAY: UNIMPLEMENTED(); break;
case GL_MULTISAMPLE: UNIMPLEMENTED(); break;
case GL_SAMPLE_ALPHA_TO_ONE: UNIMPLEMENTED(); break;
default:
return error(GL_INVALID_ENUM);
}
}
......@@ -1664,16 +1688,40 @@ void GL_APIENTRY glEnable(GLenum cap)
{
switch(cap)
{
case GL_CULL_FACE: context->setCullFace(true); break;
case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
case GL_SCISSOR_TEST: context->setScissorTest(true); break;
case GL_STENCIL_TEST: context->setStencilTest(true); break;
case GL_DEPTH_TEST: context->setDepthTest(true); break;
case GL_BLEND: context->setBlend(true); break;
case GL_DITHER: context->setDither(true); break;
default:
case GL_CULL_FACE: context->setCullFace(true); break;
case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
case GL_SCISSOR_TEST: context->setScissorTest(true); break;
case GL_STENCIL_TEST: context->setStencilTest(true); break;
case GL_DEPTH_TEST: context->setDepthTest(true); break;
case GL_BLEND: context->setBlend(true); break;
case GL_DITHER: context->setDither(true); break;
case GL_LIGHTING: context->setLighting(true); break;
case GL_LIGHT0: context->setLight(0, true); break;
case GL_LIGHT1: context->setLight(1, true); break;
case GL_LIGHT2: context->setLight(2, true); break;
case GL_LIGHT3: context->setLight(3, true); break;
case GL_LIGHT4: context->setLight(4, true); break;
case GL_LIGHT5: context->setLight(5, true); break;
case GL_LIGHT6: context->setLight(6, true); break;
case GL_LIGHT7: context->setLight(7, true); break;
case GL_FOG: UNIMPLEMENTED(); break;
case GL_TEXTURE_2D: UNIMPLEMENTED(); break;
case GL_ALPHA_TEST: UNIMPLEMENTED(); break;
case GL_COLOR_LOGIC_OP: UNIMPLEMENTED(); break;
case GL_POINT_SMOOTH: UNIMPLEMENTED(); break;
case GL_LINE_SMOOTH: UNIMPLEMENTED(); break;
case GL_COLOR_MATERIAL: UNIMPLEMENTED(); break;
case GL_NORMALIZE: UNIMPLEMENTED(); break;
case GL_RESCALE_NORMAL: UNIMPLEMENTED(); break;
case GL_VERTEX_ARRAY: UNIMPLEMENTED(); break;
case GL_NORMAL_ARRAY: UNIMPLEMENTED(); break;
case GL_COLOR_ARRAY: UNIMPLEMENTED(); break;
case GL_TEXTURE_COORD_ARRAY: UNIMPLEMENTED(); break;
case GL_MULTISAMPLE: UNIMPLEMENTED(); break;
case GL_SAMPLE_ALPHA_TO_ONE: UNIMPLEMENTED(); break;
default:
return error(GL_INVALID_ENUM);
}
}
......@@ -2882,7 +2930,42 @@ void GL_APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
void GL_APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
{
UNIMPLEMENTED();
TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
try
{
es1::Context *context = es1::getContext();
if(context)
{
int index = light - GL_LIGHT0;
if(index < 0 || index > es1::MAX_LIGHTS)
{
return error(GL_INVALID_ENUM);
}
switch(pname)
{
case GL_AMBIENT: context->setLightAmbient(index, params[0], params[1], params[2], params[3]); break;
case GL_DIFFUSE: context->setLightDiffuse(index, params[0], params[1], params[2], params[3]); break;
case GL_SPECULAR: context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;
case GL_POSITION: context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;
case GL_SPOT_DIRECTION: context->setLightDirection(index, params[0], params[1], params[2]); break;
case GL_SPOT_EXPONENT: UNIMPLEMENTED(); break;
case GL_SPOT_CUTOFF: UNIMPLEMENTED(); break;
case GL_CONSTANT_ATTENUATION: context->setLightAttenuationConstant(index, params[0]); break;
case GL_LINEAR_ATTENUATION: context->setLightAttenuationLinear(index, params[0]); break;
case GL_QUADRATIC_ATTENUATION: context->setLightAttenuationQuadratic(index, params[0]); break;
default:
return error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
return error(GL_OUT_OF_MEMORY);
}
}
void GL_APIENTRY glLightx(GLenum light, GLenum pname, GLfixed param)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment