Commit 1478afaf by Lingfeng Yang Committed by Commit Bot

GLES1: Lighting and materials (renderer)

- Update test expectations - Add gles1 sample app that shows simple lighting. BUG=angleproject:2306 Change-Id: I545dcf860374abd9d628b0d554153cb634098f6d Reviewed-on: https://chromium-review.googlesource.com/1065501 Commit-Queue: Lingfeng Yang <lfy@google.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent d0febe7a
......@@ -185,6 +185,12 @@ angle_sample("gles1_simple_texture_2d") {
]
}
angle_sample("gles1_simple_lighting") {
sources = [
"gles1/SimpleLighting.cpp",
]
}
group("all") {
testonly = true
deps = [
......
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Based on Hello_Triangle.c from
// Book: OpenGL(R) ES 2.0 Programming Guide
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
// ISBN-10: 0321502795
// ISBN-13: 9780321502797
// Publisher: Addison-Wesley Professional
// URLs: http://safari.informit.com/9780321563835
// http://www.opengles-book.com
#include "SampleApplication.h"
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <algorithm>
class SimpleLightingSample : public SampleApplication
{
public:
SimpleLightingSample(EGLint displayType)
: SampleApplication("SimpleLightingSample", 1280, 720, 1, 0, displayType)
{
}
virtual bool initialize()
{
glClearColor(0.4f, 0.3f, 0.2f, 1.0f);
mRotDeg = 0.0f;
return true;
}
virtual void destroy() {}
virtual void draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(0.2f, 0.6f, 0.8f, 1.0f);
GLfloat mat_ambient[] = {0.7f, 0.4f, 0.2f, 1.0f};
GLfloat mat_specular[] = {0.5f, 0.5f, 0.5f, 1.0f};
GLfloat mat_diffuse[] = {0.3f, 0.4f, 0.6f, 1.0f};
GLfloat lightpos[] = {0.0f, 1.0f, 0.0f, 0.0f};
GLfloat normals[] = {
-0.4f, 0.4f, -0.4f, -0.4f, -0.4f, -0.4f, 0.2f, 0.0f, -0.4f,
-0.4f, 0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.2f, 0.0f, 0.4f,
};
GLfloat vertices[] = {
-0.5f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.3f, -0.5f, -0.5f, 0.3f, 0.5f, 0.0f, 0.3f,
};
GLuint indices[] = {
0, 1, 2, 3, 4, 5,
0, 4, 3, 4, 0, 1,
4, 1, 2, 2, 5, 4,
5, 2, 3, 3, 2, 0,
};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
glPushMatrix();
glTranslatef(-0.6f + i * 0.6f, -0.6f + j * 0.6f, 0.0f);
glRotatef(mRotDeg + (10.0f * (3.0f * i + j)), 0.0f, 1.0f, 0.0f);
glRotatef(20.0f + (20.0f * (3.0f * i + j)), 1.0f, 0.0f, 0.0f);
GLfloat scale = 0.5;
glScalef(scale, scale, scale);
glDrawElements(GL_TRIANGLES, 3 * 8, GL_UNSIGNED_INT, indices);
glPopMatrix();
}
}
mRotDeg += 0.03f;
}
private:
float mRotDeg;
};
int main(int argc, char **argv)
{
EGLint displayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
if (argc > 1)
{
displayType = GetDisplayTypeFromArg(argv[1]);
}
SimpleLightingSample app(displayType);
return app.run();
}
......@@ -85,27 +85,18 @@ Error GLES1Renderer::prepareForDraw(Context *context, State *glState)
}
}
// Matrices
{
angle::Mat4 proj = gles1State.mProjectionMatrices.back();
if (mProgramState.projMatrixLoc != -1)
{
programObject->setUniformMatrix4fv(mProgramState.projMatrixLoc, 1, GL_FALSE,
proj.data());
}
setUniformMatrix4fv(programObject, mProgramState.projMatrixLoc, 1, GL_FALSE, proj.data());
angle::Mat4 modelview = gles1State.mModelviewMatrices.back();
if (mProgramState.modelviewMatrixLoc != -1)
{
programObject->setUniformMatrix4fv(mProgramState.modelviewMatrixLoc, 1, GL_FALSE,
modelview.data());
}
setUniformMatrix4fv(programObject, mProgramState.modelviewMatrixLoc, 1, GL_FALSE,
modelview.data());
angle::Mat4 modelviewInvTr = modelview.transpose().inverse();
if (mProgramState.modelviewInvTrLoc != -1)
{
programObject->setUniformMatrix4fv(mProgramState.modelviewInvTrLoc, 1, GL_FALSE,
modelviewInvTr.data());
}
setUniformMatrix4fv(programObject, mProgramState.modelviewInvTrLoc, 1, GL_FALSE,
modelviewInvTr.data());
Mat4Uniform *textureMatrixBuffer = uniformBuffers.textureMatrices.data();
......@@ -115,13 +106,11 @@ Error GLES1Renderer::prepareForDraw(Context *context, State *glState)
memcpy(textureMatrixBuffer + i, textureMatrix.data(), sizeof(Mat4Uniform));
}
if (mProgramState.textureMatrixLoc != -1)
{
programObject->setUniformMatrix4fv(mProgramState.textureMatrixLoc, 4, GL_FALSE,
(float *)uniformBuffers.textureMatrices.data());
}
setUniformMatrix4fv(programObject, mProgramState.textureMatrixLoc, kTexUnitCount, GL_FALSE,
(float *)uniformBuffers.textureMatrices.data());
}
// Texturing
{
std::array<GLint, kTexUnitCount> &tex2DEnables = uniformBuffers.tex2DEnables;
std::array<GLint, kTexUnitCount> &texCubeEnables = uniformBuffers.texCubeEnables;
......@@ -151,23 +140,87 @@ Error GLES1Renderer::prepareForDraw(Context *context, State *glState)
!texCubeEnables[i] && (gles1State.isTextureTargetEnabled(i, TextureType::_2D));
}
if (mProgramState.enableTexture2DLoc != -1)
{
programObject->setUniform1iv(mProgramState.enableTexture2DLoc, kTexUnitCount,
tex2DEnables.data());
}
if (mProgramState.enableTextureCubeMapLoc != -1)
{
programObject->setUniform1iv(mProgramState.enableTextureCubeMapLoc, kTexUnitCount,
texCubeEnables.data());
}
GLint flatShading = gles1State.mShadeModel == ShadingModel::Flat;
setUniform1iv(programObject, mProgramState.enableTexture2DLoc, kTexUnitCount,
tex2DEnables.data());
setUniform1iv(programObject, mProgramState.enableTextureCubeMapLoc, kTexUnitCount,
texCubeEnables.data());
}
if (mProgramState.shadeModelFlatLoc != -1)
// Shading, materials, and lighting
{
setUniform1i(programObject, mProgramState.shadeModelFlatLoc,
gles1State.mShadeModel == ShadingModel::Flat);
setUniform1i(programObject, mProgramState.enableLightingLoc,
glState->getEnableFeature(GL_LIGHTING));
setUniform1i(programObject, mProgramState.enableRescaleNormalLoc,
glState->getEnableFeature(GL_RESCALE_NORMAL));
setUniform1i(programObject, mProgramState.enableNormalizeLoc,
glState->getEnableFeature(GL_NORMALIZE));
setUniform1i(programObject, mProgramState.enableColorMaterialLoc,
glState->getEnableFeature(GL_COLOR_MATERIAL));
const auto &material = gles1State.mMaterial;
setUniform4fv(programObject, mProgramState.materialAmbientLoc, 1, material.ambient.data());
setUniform4fv(programObject, mProgramState.materialDiffuseLoc, 1, material.diffuse.data());
setUniform4fv(programObject, mProgramState.materialSpecularLoc, 1,
material.specular.data());
setUniform4fv(programObject, mProgramState.materialEmissiveLoc, 1,
material.emissive.data());
setUniform1f(programObject, mProgramState.materialSpecularExponentLoc,
material.specularExponent);
const auto &lightModel = gles1State.mLightModel;
setUniform4fv(programObject, mProgramState.lightModelSceneAmbientLoc, 1,
lightModel.color.data());
// TODO (lfy@google.com): Implement two-sided lighting model
// gl->uniform1i(mProgramState.lightModelTwoSidedLoc, lightModel.twoSided);
for (int i = 0; i < kLightCount; i++)
{
programObject->setUniform1iv(mProgramState.shadeModelFlatLoc, 1, &flatShading);
const auto &light = gles1State.mLights[i];
uniformBuffers.lightEnables[i] = light.enabled;
memcpy(uniformBuffers.lightAmbients.data() + i, light.ambient.data(),
sizeof(Vec4Uniform));
memcpy(uniformBuffers.lightDiffuses.data() + i, light.diffuse.data(),
sizeof(Vec4Uniform));
memcpy(uniformBuffers.lightSpeculars.data() + i, light.specular.data(),
sizeof(Vec4Uniform));
memcpy(uniformBuffers.lightPositions.data() + i, light.position.data(),
sizeof(Vec4Uniform));
memcpy(uniformBuffers.lightDirections.data() + i, light.direction.data(),
sizeof(Vec3Uniform));
uniformBuffers.spotlightExponents[i] = light.spotlightExponent;
uniformBuffers.spotlightCutoffAngles[i] = light.spotlightCutoffAngle;
uniformBuffers.attenuationConsts[i] = light.attenuationConst;
uniformBuffers.attenuationLinears[i] = light.attenuationLinear;
uniformBuffers.attenuationQuadratics[i] = light.attenuationQuadratic;
}
setUniform1iv(programObject, mProgramState.lightEnablesLoc, kLightCount,
uniformBuffers.lightEnables.data());
setUniform4fv(programObject, mProgramState.lightAmbientsLoc, kLightCount,
(GLfloat *)uniformBuffers.lightAmbients.data());
setUniform4fv(programObject, mProgramState.lightDiffusesLoc, kLightCount,
(GLfloat *)uniformBuffers.lightDiffuses.data());
setUniform4fv(programObject, mProgramState.lightSpecularsLoc, kLightCount,
(GLfloat *)uniformBuffers.lightSpeculars.data());
setUniform4fv(programObject, mProgramState.lightPositionsLoc, kLightCount,
(GLfloat *)uniformBuffers.lightPositions.data());
setUniform3fv(programObject, mProgramState.lightDirectionsLoc, kLightCount,
(GLfloat *)uniformBuffers.lightDirections.data());
setUniform1fv(programObject, mProgramState.lightSpotlightExponentsLoc, kLightCount,
(GLfloat *)uniformBuffers.spotlightExponents.data());
setUniform1fv(programObject, mProgramState.lightSpotlightCutoffAnglesLoc, kLightCount,
(GLfloat *)uniformBuffers.spotlightCutoffAngles.data());
setUniform1fv(programObject, mProgramState.lightAttenuationConstsLoc, kLightCount,
(GLfloat *)uniformBuffers.attenuationConsts.data());
setUniform1fv(programObject, mProgramState.lightAttenuationLinearsLoc, kLightCount,
(GLfloat *)uniformBuffers.attenuationLinears.data());
setUniform1fv(programObject, mProgramState.lightAttenuationQuadraticsLoc, kLightCount,
(GLfloat *)uniformBuffers.attenuationQuadratics.data());
}
// None of those are changes in sampler, so there is no need to set the GL_PROGRAM dirty.
......@@ -377,28 +430,53 @@ Error GLES1Renderer::initializeRendererProgram(Context *context, State *glState)
programObject->getUniformLocation(sscube.str().c_str());
}
mProgramState.shadeModelFlatLoc = programObject->getUniformLocation("shade_model_flat");
mProgramState.enableTexture2DLoc = programObject->getUniformLocation("enable_texture_2d");
mProgramState.enableTextureCubeMapLoc =
programObject->getUniformLocation("enable_texture_cube_map");
mProgramState.shadeModelFlatLoc = programObject->getUniformLocation("shade_model_flat");
mProgramState.enableLightingLoc = programObject->getUniformLocation("enable_lighting");
mProgramState.enableRescaleNormalLoc =
programObject->getUniformLocation("enable_rescale_normal");
mProgramState.enableNormalizeLoc = programObject->getUniformLocation("enable_normalize");
mProgramState.enableColorMaterialLoc =
programObject->getUniformLocation("enable_color_material");
mProgramState.materialAmbientLoc = programObject->getUniformLocation("material_ambient");
mProgramState.materialDiffuseLoc = programObject->getUniformLocation("material_diffuse");
mProgramState.materialSpecularLoc = programObject->getUniformLocation("material_specular");
mProgramState.materialEmissiveLoc = programObject->getUniformLocation("material_emissive");
mProgramState.materialSpecularExponentLoc =
programObject->getUniformLocation("material_specular_exponent");
mProgramState.lightModelSceneAmbientLoc =
programObject->getUniformLocation("light_model_scene_ambient");
mProgramState.lightModelTwoSidedLoc =
programObject->getUniformLocation("light_model_two_sided");
mProgramState.lightEnablesLoc = programObject->getUniformLocation("light_enables");
mProgramState.lightAmbientsLoc = programObject->getUniformLocation("light_ambients");
mProgramState.lightDiffusesLoc = programObject->getUniformLocation("light_diffuses");
mProgramState.lightSpecularsLoc = programObject->getUniformLocation("light_speculars");
mProgramState.lightPositionsLoc = programObject->getUniformLocation("light_positions");
mProgramState.lightDirectionsLoc = programObject->getUniformLocation("light_directions");
mProgramState.lightSpotlightExponentsLoc =
programObject->getUniformLocation("light_spotlight_exponents");
mProgramState.lightSpotlightCutoffAnglesLoc =
programObject->getUniformLocation("light_spotlight_cutoff_angles");
mProgramState.lightAttenuationConstsLoc =
programObject->getUniformLocation("light_attenuation_consts");
mProgramState.lightAttenuationLinearsLoc =
programObject->getUniformLocation("light_attenuation_linears");
mProgramState.lightAttenuationQuadraticsLoc =
programObject->getUniformLocation("light_attenuation_quadratics");
glState->setProgram(context, programObject);
for (int i = 0; i < kTexUnitCount; i++)
{
if (mProgramState.tex2DSamplerLocs[i] != -1)
{
GLint val = i;
programObject->setUniform1iv(mProgramState.tex2DSamplerLocs[i], 1, &val);
}
if (mProgramState.texCubeSamplerLocs[i] != -1)
{
GLint val = i + kTexUnitCount;
programObject->setUniform1iv(mProgramState.texCubeSamplerLocs[i], 1, &val);
}
setUniform1i(programObject, mProgramState.tex2DSamplerLocs[i], i);
setUniform1i(programObject, mProgramState.texCubeSamplerLocs[i], i + kTexUnitCount);
}
glState->setObjectDirty(GL_PROGRAM);
......@@ -407,4 +485,69 @@ Error GLES1Renderer::initializeRendererProgram(Context *context, State *glState)
return NoError();
}
void GLES1Renderer::setUniform1i(Program *programObject, GLint loc, GLint value)
{
if (loc == -1)
return;
programObject->setUniform1iv(loc, 1, &value);
}
void GLES1Renderer::setUniform1iv(Program *programObject,
GLint loc,
GLint count,
const GLint *value)
{
if (loc == -1)
return;
programObject->setUniform1iv(loc, count, value);
}
void GLES1Renderer::setUniformMatrix4fv(Program *programObject,
GLint loc,
GLint count,
GLboolean transpose,
const GLfloat *value)
{
if (loc == -1)
return;
programObject->setUniformMatrix4fv(loc, count, transpose, value);
}
void GLES1Renderer::setUniform4fv(Program *programObject,
GLint loc,
GLint count,
const GLfloat *value)
{
if (loc == -1)
return;
programObject->setUniform4fv(loc, count, value);
}
void GLES1Renderer::setUniform3fv(Program *programObject,
GLint loc,
GLint count,
const GLfloat *value)
{
if (loc == -1)
return;
programObject->setUniform3fv(loc, count, value);
}
void GLES1Renderer::setUniform1f(Program *programObject, GLint loc, GLfloat value)
{
if (loc == -1)
return;
programObject->setUniform1fv(loc, 1, &value);
}
void GLES1Renderer::setUniform1fv(Program *programObject,
GLint loc,
GLint count,
const GLfloat *value)
{
if (loc == -1)
return;
programObject->setUniform1fv(loc, count, value);
}
} // namespace gl
......@@ -43,6 +43,8 @@ class GLES1Renderer final : angle::NonCopyable
private:
using Mat4Uniform = float[16];
using Vec4Uniform = float[4];
using Vec3Uniform = float[3];
Shader *getShader(GLuint handle) const;
Program *getProgram(GLuint handle) const;
......@@ -59,7 +61,20 @@ class GLES1Renderer final : angle::NonCopyable
GLuint *programOut);
Error initializeRendererProgram(Context *context, State *glState);
void setUniform1i(Program *programObject, GLint loc, GLint value);
void setUniform1iv(Program *programObject, GLint loc, GLint count, const GLint *value);
void setUniformMatrix4fv(Program *programObject,
GLint loc,
GLint count,
GLboolean transpose,
const GLfloat *value);
void setUniform4fv(Program *programObject, GLint loc, GLint count, const GLfloat *value);
void setUniform3fv(Program *programObject, GLint loc, GLint count, const GLfloat *value);
void setUniform1f(Program *programObject, GLint loc, GLfloat value);
void setUniform1fv(Program *programObject, GLint loc, GLint count, const GLfloat *value);
static constexpr int kTexUnitCount = 4;
static constexpr int kLightCount = 8;
static constexpr int kVertexAttribIndex = 0;
static constexpr int kNormalAttribIndex = 1;
......@@ -79,13 +94,39 @@ class GLES1Renderer final : angle::NonCopyable
GLint textureMatrixLoc;
GLint modelviewInvTrLoc;
std::array<GLint, kTexUnitCount> tex2DSamplerLocs;
std::array<GLint, kTexUnitCount> texCubeSamplerLocs;
// Shading, materials, and lighting
GLint shadeModelFlatLoc;
GLint enableLightingLoc;
GLint enableRescaleNormalLoc;
GLint enableNormalizeLoc;
GLint enableColorMaterialLoc;
GLint materialAmbientLoc;
GLint materialDiffuseLoc;
GLint materialSpecularLoc;
GLint materialEmissiveLoc;
GLint materialSpecularExponentLoc;
GLint lightModelSceneAmbientLoc;
GLint lightModelTwoSidedLoc;
GLint lightEnablesLoc;
GLint lightAmbientsLoc;
GLint lightDiffusesLoc;
GLint lightSpecularsLoc;
GLint lightPositionsLoc;
GLint lightDirectionsLoc;
GLint lightSpotlightExponentsLoc;
GLint lightSpotlightCutoffAnglesLoc;
GLint lightAttenuationConstsLoc;
GLint lightAttenuationLinearsLoc;
GLint lightAttenuationQuadraticsLoc;
// Texturing
GLint enableTexture2DLoc;
GLint enableTextureCubeMapLoc;
std::array<GLint, kTexUnitCount> tex2DSamplerLocs;
std::array<GLint, kTexUnitCount> texCubeSamplerLocs;
};
struct GLES1UniformBuffers
......@@ -93,6 +134,19 @@ class GLES1Renderer final : angle::NonCopyable
std::array<Mat4Uniform, kTexUnitCount> textureMatrices;
std::array<GLint, kTexUnitCount> tex2DEnables;
std::array<GLint, kTexUnitCount> texCubeEnables;
// Lighting
std::array<GLint, kLightCount> lightEnables;
std::array<Vec4Uniform, kLightCount> lightAmbients;
std::array<Vec4Uniform, kLightCount> lightDiffuses;
std::array<Vec4Uniform, kLightCount> lightSpeculars;
std::array<Vec4Uniform, kLightCount> lightPositions;
std::array<Vec3Uniform, kLightCount> lightDirections;
std::array<GLfloat, kLightCount> spotlightExponents;
std::array<GLfloat, kLightCount> spotlightCutoffAngles;
std::array<GLfloat, kLightCount> attenuationConsts;
std::array<GLfloat, kLightCount> attenuationLinears;
std::array<GLfloat, kLightCount> attenuationQuadratics;
};
GLES1UniformBuffers mUniformBuffers;
......
......@@ -25,6 +25,9 @@ uniform mat4 modelview;
uniform mat4 modelview_invtr;
uniform mat4 texture_matrix[4];
uniform bool enable_rescale_normal;
uniform bool enable_normalize;
out vec4 pos_varying;
out vec3 normal_varying;
out vec4 color_varying;
......@@ -41,6 +44,20 @@ void main()
mat3 mvInvTr3 = mat3(modelview_invtr);
normal_varying = mvInvTr3 * normal;
if (enable_rescale_normal) {
float rescale = 1.0;
vec3 rescaleVec = vec3(mvInvTr3[2]);
float len = length(rescaleVec);
if (len > 0.0) {
rescale = 1.0 / len;
}
normal_varying *= rescale;
}
if (enable_normalize) {
normal_varying = normalize(normal_varying);
}
color_varying = color;
color_varying_flat = color;
pointsize_varying = pointsize;
......@@ -145,10 +162,6 @@ uniform samplerCube tex_cube_sampler2;
uniform sampler2D tex_sampler3;
uniform samplerCube tex_cube_sampler3;
// Global enables, alpha func, logic op ////////////////////////////////////////
uniform bool shade_model_flat;
// Vertex attributes////////////////////////////////////////////////////////////
in vec4 pos_varying;
......@@ -161,6 +174,33 @@ in vec4 texcoord1_varying;
in vec4 texcoord2_varying;
in vec4 texcoord3_varying;
// Shading: flat shading, lighting, and materials///////////////////////////////
uniform bool shade_model_flat;
uniform bool enable_lighting;
uniform bool enable_color_material;
uniform vec4 material_ambient;
uniform vec4 material_diffuse;
uniform vec4 material_specular;
uniform vec4 material_emissive;
uniform float material_specular_exponent;
uniform vec4 light_model_scene_ambient;
uniform bool light_model_two_sided;
uniform bool light_enables[kMaxLights];
uniform vec4 light_ambients[kMaxLights];
uniform vec4 light_diffuses[kMaxLights];
uniform vec4 light_speculars[kMaxLights];
uniform vec4 light_positions[kMaxLights];
uniform vec3 light_directions[kMaxLights];
uniform float light_spotlight_exponents[kMaxLights];
uniform float light_spotlight_cutoff_angles[kMaxLights];
uniform float light_attenuation_consts[kMaxLights];
uniform float light_attenuation_linears[kMaxLights];
uniform float light_attenuation_quadratics[kMaxLights];
// Outgoing fragment////////////////////////////////////////////////////////////
out vec4 frag_color;
......@@ -237,6 +277,100 @@ vec4 getColor(int unit, vec4 vertexColor)
return getTextureColor(unit);
}
float posDot(vec3 a, vec3 b) {
return max(dot(a, b), 0.0);
}
vec4 doLighting(vec4 currentFragment) {
vec4 materialAmbientActual = material_ambient;
vec4 materialDiffuseActual = material_diffuse;
if (enable_color_material || enable_texture_2d[0] || enable_texture_cube_map[0]) {
materialAmbientActual = currentFragment;
materialDiffuseActual = currentFragment;
}
vec4 lightingResult = material_emissive +
materialAmbientActual * light_model_scene_ambient;
for (int i = 0; i < kMaxLights; i++) {
if (!light_enables[i]) continue;
vec4 lightAmbient = light_ambients[i];
vec4 lightDiffuse = light_diffuses[i];
vec4 lightSpecular = light_speculars[i];
vec4 lightPos = light_positions[i];
vec3 lightDir = light_directions[i];
float attConst = light_attenuation_consts[i];
float attLinear = light_attenuation_linears[i];
float attQuadratic = light_attenuation_quadratics[i];
float spotAngle = light_spotlight_cutoff_angles[i];
float spotExponent = light_spotlight_exponents[i];
vec3 toLight;
if (lightPos.w == 0.0) {
toLight = lightPos.xyz;
} else {
toLight = (lightPos.xyz / lightPos.w - pos_varying.xyz);
}
float lightDist = length(toLight);
vec3 h = normalize(toLight) + vec3(0.0, 0.0, 1.0);
float ndotL = posDot(normal_varying, normalize(toLight));
float ndoth = posDot(normal_varying, normalize(h));
float specAtt;
if (ndotL != 0.0) {
specAtt = 1.0;
} else {
specAtt = 0.0;
}
float att;
if (lightPos.w != 0.0) {
float attDenom = (attConst + attLinear * lightDist +
attQuadratic * lightDist * lightDist);
att = 1.0 / attDenom;
} else {
att = 1.0;
}
float spot;
float spotAngleCos = cos(radians(spotAngle));
vec3 toSurfaceDir = -normalize(toLight);
float spotDot = posDot(toSurfaceDir, normalize(lightDir));
if (spotAngle == 180.0 || lightPos.w == 0.0) {
spot = 1.0;
} else {
if (spotDot < spotAngleCos) {
spot = 0.0;
} else {
spot = pow(spotDot, spotExponent);
}
}
vec4 contrib = materialAmbientActual * lightAmbient;
contrib += ndotL * materialDiffuseActual * lightDiffuse;
if (ndoth > 0.0 && material_specular_exponent > 0.0) {
contrib += specAtt * pow(ndoth, material_specular_exponent) *
material_specular * lightSpecular;
} else {
if (ndoth > 0.0) {
contrib += specAtt * material_specular * lightSpecular;
}
}
contrib *= att * spot;
lightingResult += contrib;
}
return lightingResult;
}
)";
constexpr char kGLES1DrawFShaderMain[] = R"(
......@@ -257,6 +391,10 @@ void main()
// Unit 0 only for now
currentFragment = getColor(0, vertex_color);
if (enable_lighting) {
currentFragment = doLighting(currentFragment);
}
frag_color = currentFragment;
}
)";
......@@ -137,19 +137,16 @@ class GLES1ConformanceTest : public ANGLETest
TEST_P(GLES1ConformanceTest, AmbLight)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, AmbLightExec());
}
TEST_P(GLES1ConformanceTest, AmbMat)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, AmbMatExec());
}
TEST_P(GLES1ConformanceTest, AmbScene)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, AmbSceneExec());
}
......@@ -161,13 +158,11 @@ TEST_P(GLES1ConformanceTest, APFunc)
TEST_P(GLES1ConformanceTest, AtnConst)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, AtnConstExec());
}
TEST_P(GLES1ConformanceTest, AtnPos)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, AtnPosExec());
}
......@@ -193,7 +188,6 @@ TEST_P(GLES1ConformanceTest, Blend)
TEST_P(GLES1ConformanceTest, Clip)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, ClipExec());
}
......@@ -210,25 +204,21 @@ TEST_P(GLES1ConformanceTest, CopyTex)
TEST_P(GLES1ConformanceTest, DifLight)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, DifLightExec());
}
TEST_P(GLES1ConformanceTest, DifMat)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, DifMatExec());
}
TEST_P(GLES1ConformanceTest, DifMatNorm)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, DifMatNormExec());
}
TEST_P(GLES1ConformanceTest, DifMatPos)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, DifMatPosExec());
}
......@@ -245,7 +235,6 @@ TEST_P(GLES1ConformanceTest, DivZero)
TEST_P(GLES1ConformanceTest, EmitMat)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, EmitMatExec());
}
......@@ -380,31 +369,26 @@ TEST_P(GLES1ConformanceTest, SPCorner)
TEST_P(GLES1ConformanceTest, SpecExp)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SpecExpExec());
}
TEST_P(GLES1ConformanceTest, SpecExpNorm)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SpecExpNormExec());
}
TEST_P(GLES1ConformanceTest, SpecLight)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SpecLightExec());
}
TEST_P(GLES1ConformanceTest, SpecMat)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SpecMatExec());
}
TEST_P(GLES1ConformanceTest, SpecNorm)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SpecNormExec());
}
......@@ -420,19 +404,16 @@ TEST_P(GLES1ConformanceTest, SPOp)
TEST_P(GLES1ConformanceTest, SpotPos)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SpotPosExec());
}
TEST_P(GLES1ConformanceTest, SpotExpPos)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SpotExpPosExec());
}
TEST_P(GLES1ConformanceTest, SpotExpDir)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, SpotExpDirExec());
}
......@@ -487,7 +468,6 @@ TEST_P(GLES1ConformanceTest, XFormMix)
TEST_P(GLES1ConformanceTest, XFormNormal)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, XFormNormalExec());
}
......
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