Commit 7ba3f425 by Lingfeng Yang Committed by Commit Bot

GLES1: Fog API and rendering

- Update test expectations BUG=angleproject:2306 Change-Id: Ic5aa5f052bcbe9c5adaf0eb0c6c06df66fd1720c Reviewed-on: https://chromium-review.googlesource.com/1082978 Commit-Queue: Lingfeng Yang <lfy@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 060088a5
......@@ -7091,12 +7091,17 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
*numParams = 1;
return true;
case GL_ALPHA_TEST_REF:
case GL_FOG_DENSITY:
case GL_FOG_START:
case GL_FOG_END:
case GL_FOG_MODE:
*type = GL_FLOAT;
*numParams = 1;
return true;
case GL_CURRENT_COLOR:
case GL_CURRENT_TEXTURE_COORDS:
case GL_LIGHT_MODEL_AMBIENT:
case GL_FOG_COLOR:
*type = GL_FLOAT;
*numParams = 4;
return true;
......
......@@ -118,22 +118,44 @@ void Context::enableClientState(ClientVertexArrayType clientState)
void Context::fogf(GLenum pname, GLfloat param)
{
UNIMPLEMENTED();
SetFogParameters(&mGLState.gles1(), pname, &param);
}
void Context::fogfv(GLenum pname, const GLfloat *params)
{
UNIMPLEMENTED();
SetFogParameters(&mGLState.gles1(), pname, params);
}
void Context::fogx(GLenum pname, GLfixed param)
{
UNIMPLEMENTED();
if (GetFogParameterCount(pname) == 1)
{
GLfloat paramf = pname == GL_FOG_MODE ? FixedToEnum(param) : FixedToFloat(param);
fogf(pname, paramf);
}
else
{
UNREACHABLE();
}
}
void Context::fogxv(GLenum pname, const GLfixed *param)
void Context::fogxv(GLenum pname, const GLfixed *params)
{
UNIMPLEMENTED();
int paramCount = GetFogParameterCount(pname);
if (paramCount > 0)
{
GLfloat paramsf[4];
for (int i = 0; i < paramCount; i++)
{
paramsf[i] = pname == GL_FOG_MODE ? FixedToEnum(params[i]) : FixedToFloat(params[i]);
}
fogfv(pname, paramsf);
}
else
{
UNREACHABLE();
}
}
void Context::frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
......
......@@ -86,6 +86,9 @@ ERRMSG(InvalidFence, "Invalid fence object.");
ERRMSG(InvalidFenceState, "Fence must be set.");
ERRMSG(InvalidFillMode, "Invalid fill mode.");
ERRMSG(InvalidFilterTexture, "Texture only supports NEAREST and LINEAR filtering.");
ERRMSG(InvalidFogDensity, "Invalid fog density (must be nonnegative).");
ERRMSG(InvalidFogMode, "Invalid fog mode.");
ERRMSG(InvalidFogParameter, "Invalid fog parameter.");
ERRMSG(InvalidFormat, "Invalid format.");
ERRMSG(InvalidFramebufferTarget, "Invalid framebuffer target.");
ERRMSG(InvalidFramebufferTextureLevel, "Mipmap level must be 0 when attaching a texture.");
......
......@@ -232,6 +232,17 @@ Error GLES1Renderer::prepareForDraw(Context *context, State *glState)
reinterpret_cast<float *>(uniformBuffers.attenuationQuadratics.data()));
}
// Fog
{
const FogParameters &fog = gles1State.fogParameters();
setUniform1i(programObject, mProgramState.fogEnableLoc, glState->getEnableFeature(GL_FOG));
setUniform1i(programObject, mProgramState.fogModeLoc, ToGLenum(fog.mode));
setUniform1f(programObject, mProgramState.fogDensityLoc, fog.density);
setUniform1f(programObject, mProgramState.fogStartLoc, fog.start);
setUniform1f(programObject, mProgramState.fogEndLoc, fog.end);
setUniform4fv(programObject, mProgramState.fogColorLoc, 1, fog.color.data());
}
// Clip planes
{
bool enableClipPlanes = false;
......@@ -502,6 +513,13 @@ Error GLES1Renderer::initializeRendererProgram(Context *context, State *glState)
mProgramState.lightAttenuationQuadraticsLoc =
programObject->getUniformLocation("light_attenuation_quadratics");
mProgramState.fogEnableLoc = programObject->getUniformLocation("enable_fog");
mProgramState.fogModeLoc = programObject->getUniformLocation("fog_mode");
mProgramState.fogDensityLoc = programObject->getUniformLocation("fog_density");
mProgramState.fogStartLoc = programObject->getUniformLocation("fog_start");
mProgramState.fogEndLoc = programObject->getUniformLocation("fog_end");
mProgramState.fogColorLoc = programObject->getUniformLocation("fog_color");
mProgramState.enableClipPlanesLoc = programObject->getUniformLocation("enable_clip_planes");
mProgramState.clipPlaneEnablesLoc = programObject->getUniformLocation("clip_plane_enables");
mProgramState.clipPlanesLoc = programObject->getUniformLocation("clip_planes");
......
......@@ -95,6 +95,12 @@ class GLES1Renderer final : angle::NonCopyable
GLint textureMatrixLoc;
GLint modelviewInvTrLoc;
// Texturing
GLint enableTexture2DLoc;
GLint enableTextureCubeMapLoc;
std::array<GLint, kTexUnitCount> tex2DSamplerLocs;
std::array<GLint, kTexUnitCount> texCubeSamplerLocs;
// Alpha test
GLint enableAlphaTestLoc;
GLint alphaFuncLoc;
......@@ -128,11 +134,13 @@ class GLES1Renderer final : angle::NonCopyable
GLint lightAttenuationLinearsLoc;
GLint lightAttenuationQuadraticsLoc;
// Texturing
GLint enableTexture2DLoc;
GLint enableTextureCubeMapLoc;
std::array<GLint, kTexUnitCount> tex2DSamplerLocs;
std::array<GLint, kTexUnitCount> texCubeSamplerLocs;
// Fog
GLint fogEnableLoc;
GLint fogModeLoc;
GLint fogDensityLoc;
GLint fogStartLoc;
GLint fogEndLoc;
GLint fogColorLoc;
// Clip planes
GLint enableClipPlanesLoc;
......
......@@ -210,6 +210,15 @@ uniform float light_attenuation_consts[kMaxLights];
uniform float light_attenuation_linears[kMaxLights];
uniform float light_attenuation_quadratics[kMaxLights];
// Fog /////////////////////////////////////////////////////////////////////////
uniform bool enable_fog;
uniform int fog_mode;
uniform float fog_density;
uniform float fog_start;
uniform float fog_end;
uniform vec4 fog_color;
// User clip plane /////////////////////////////////////////////////////////////
uniform bool enable_clip_planes;
......@@ -436,6 +445,28 @@ bool doClipPlaneTest() {
return res;
}
vec4 doFog(vec4 currentFragment) {
float eyeDist = -pos_varying.z / pos_varying.w;
float f = 1.0;
switch (fog_mode) {
case kExp:
f = exp(-fog_density * eyeDist);
break;
case kExp2:
f = exp(-(pow(fog_density * eyeDist, 2.0)));
break;
case kLinear:
f = (fog_end - eyeDist) / (fog_end - fog_start);
break;
default:
break;
}
vec4 result = f * currentFragment + (1.0 - f) * fog_color;
return result;
}
)";
constexpr char kGLES1DrawFShaderMain[] = R"(
......@@ -466,6 +497,10 @@ void main()
currentFragment = doLighting(currentFragment);
}
if (enable_fog) {
currentFragment = doFog(currentFragment);
}
if (enable_alpha_test && !doAlphaTest(currentFragment))
{
discard;
......
......@@ -384,4 +384,14 @@ void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
equation[3] = mClipPlanes[plane].equation[3];
}
FogParameters &GLES1State::fogParameters()
{
return mFog;
}
const FogParameters &GLES1State::fogParameters() const
{
return mFog;
}
} // namespace gl
......@@ -180,6 +180,9 @@ class GLES1State final : angle::NonCopyable
void setClipPlane(unsigned int plane, const GLfloat *equation);
void getClipPlane(unsigned int plane, GLfloat *equation) const;
FogParameters &fogParameters();
const FogParameters &fogParameters() const;
private:
friend class State;
friend class GLES1Renderer;
......
......@@ -809,6 +809,9 @@ void State::setEnableFeature(GLenum feature, bool enabled)
case GL_CLIP_PLANE5:
mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled = enabled;
break;
case GL_FOG:
mGLES1State.mFogEnabled = enabled;
break;
default:
UNREACHABLE();
}
......@@ -902,6 +905,9 @@ bool State::getEnableFeature(GLenum feature) const
case GL_CLIP_PLANE4:
case GL_CLIP_PLANE5:
return mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled;
case GL_FOG:
return mGLES1State.mFogEnabled;
break;
default:
UNREACHABLE();
return false;
......@@ -2023,6 +2029,13 @@ void State::getFloatv(GLenum pname, GLfloat *params)
case GL_LIGHT_MODEL_AMBIENT:
GetLightModelParameters(&mGLES1State, pname, params);
break;
case GL_FOG_MODE:
case GL_FOG_DENSITY:
case GL_FOG_START:
case GL_FOG_END:
case GL_FOG_COLOR:
GetFogParameters(&mGLES1State, pname, params);
break;
default:
UNREACHABLE();
break;
......
......@@ -1978,7 +1978,6 @@ unsigned int GetLightModelParameterCount(GLenum pname)
case GL_LIGHT_MODEL_TWO_SIDE:
return 1;
default:
UNREACHABLE();
return 0;
}
}
......@@ -2001,7 +2000,6 @@ unsigned int GetLightParameterCount(LightParameter pname)
case LightParameter::QuadraticAttenuation:
return 1;
default:
UNREACHABLE();
return 0;
}
}
......@@ -2018,11 +2016,81 @@ unsigned int GetMaterialParameterCount(MaterialParameter pname)
case MaterialParameter::Shininess:
return 1;
default:
UNREACHABLE();
return 0;
}
}
void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params)
{
FogParameters &fog = state->fogParameters();
switch (pname)
{
case GL_FOG_MODE:
fog.mode = FromGLenum<FogMode>(static_cast<GLenum>(params[0]));
break;
case GL_FOG_DENSITY:
fog.density = params[0];
break;
case GL_FOG_START:
fog.start = params[0];
break;
case GL_FOG_END:
fog.end = params[0];
break;
case GL_FOG_COLOR:
fog.color = ColorF::fromData(params);
break;
default:
return;
}
}
void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params)
{
const FogParameters &fog = state->fogParameters();
switch (pname)
{
case GL_FOG_MODE:
params[0] = static_cast<GLfloat>(ToGLenum(fog.mode));
break;
case GL_FOG_DENSITY:
params[0] = fog.density;
break;
case GL_FOG_START:
params[0] = fog.start;
break;
case GL_FOG_END:
params[0] = fog.end;
break;
case GL_FOG_COLOR:
fog.color.writeData(params);
break;
default:
return;
}
}
unsigned int GetFogParameterCount(GLenum pname)
{
switch (pname)
{
case GL_FOG_MODE:
case GL_FOG_DENSITY:
case GL_FOG_START:
case GL_FOG_END:
return 1;
case GL_FOG_COLOR:
return 4;
default:
return 0;
}
}
GLenum FixedToEnum(GLfixed val)
{
return static_cast<GLenum>(val);
}
} // namespace gl
namespace egl
......
......@@ -175,6 +175,12 @@ unsigned int GetLightModelParameterCount(GLenum pname);
unsigned int GetLightParameterCount(LightParameter pname);
unsigned int GetMaterialParameterCount(MaterialParameter pname);
void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params);
void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params);
unsigned int GetFogParameterCount(GLenum pname);
GLenum FixedToEnum(GLfixed val);
} // namespace gl
namespace egl
......
......@@ -329,6 +329,45 @@ bool ValidateClipPlaneCommon(Context *context, GLenum plane)
return true;
}
bool ValidateFogCommon(Context *context, GLenum pname, const GLfloat *params)
{
ANGLE_VALIDATE_IS_GLES1(context);
switch (pname)
{
case GL_FOG_MODE:
{
GLenum modeParam = static_cast<GLenum>(params[0]);
switch (modeParam)
{
case GL_EXP:
case GL_EXP2:
case GL_LINEAR:
return true;
default:
ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFogMode);
return false;
}
}
break;
case GL_FOG_START:
case GL_FOG_END:
case GL_FOG_COLOR:
break;
case GL_FOG_DENSITY:
if (params[0] < 0.0f)
{
ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFogDensity);
return false;
}
break;
default:
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFogParameter);
return false;
}
return true;
}
} // namespace gl
namespace gl
......@@ -426,26 +465,31 @@ bool ValidateEnableClientState(Context *context, ClientVertexArrayType arrayType
bool ValidateFogf(Context *context, GLenum pname, GLfloat param)
{
UNIMPLEMENTED();
return true;
return ValidateFogCommon(context, pname, &param);
}
bool ValidateFogfv(Context *context, GLenum pname, const GLfloat *params)
{
UNIMPLEMENTED();
return true;
return ValidateFogCommon(context, pname, params);
}
bool ValidateFogx(Context *context, GLenum pname, GLfixed param)
{
UNIMPLEMENTED();
return true;
GLfloat asFloat = FixedToFloat(param);
return ValidateFogCommon(context, pname, &asFloat);
}
bool ValidateFogxv(Context *context, GLenum pname, const GLfixed *param)
bool ValidateFogxv(Context *context, GLenum pname, const GLfixed *params)
{
UNIMPLEMENTED();
return true;
unsigned int paramCount = GetFogParameterCount(pname);
GLfloat paramsf[4] = {};
for (unsigned int i = 0; i < paramCount; i++)
{
paramsf[i] = FixedToFloat(params[i]);
}
return ValidateFogCommon(context, pname, paramsf);
}
bool ValidateFrustumf(Context *context,
......
......@@ -817,6 +817,7 @@ bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
case GL_CLIP_PLANE3:
case GL_CLIP_PLANE4:
case GL_CLIP_PLANE5:
case GL_FOG:
return context->getClientVersion() < Version(2, 0);
case GL_POINT_SIZE_ARRAY_OES:
return context->getClientVersion() < Version(2, 0) &&
......
......@@ -56,6 +56,7 @@
'<(angle_path)/src/tests/gl_tests/gles1/CurrentColorTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/CurrentNormalTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/CurrentTextureCoordsTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/FogTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/MaterialsTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/MatrixBuiltinsTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/MatrixLoadTest.cpp',
......
//
// 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.
//
// FogTest.cpp: Tests basic usage of glFog.
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "random_utils.h"
#include <stdint.h>
using namespace angle;
class FogTest : public ANGLETest
{
protected:
FogTest()
{
setWindowWidth(32);
setWindowHeight(32);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
setConfigDepthBits(24);
}
};
// Initial state check.
TEST_P(FogTest, InitialState)
{
EXPECT_GL_FALSE(glIsEnabled(GL_FOG));
EXPECT_GL_NO_ERROR();
GLint fogMode;
glGetIntegerv(GL_FOG_MODE, &fogMode);
EXPECT_GL_NO_ERROR();
EXPECT_GLENUM_EQ(GL_EXP, fogMode);
GLfloat fogModeAsFloat;
glGetFloatv(GL_FOG_MODE, &fogModeAsFloat);
EXPECT_GL_NO_ERROR();
EXPECT_GLENUM_EQ(GL_EXP, fogModeAsFloat);
GLfloat fogStart;
GLfloat fogEnd;
GLfloat fogDensity;
glGetFloatv(GL_FOG_START, &fogStart);
EXPECT_GL_NO_ERROR();
glGetFloatv(GL_FOG_END, &fogEnd);
EXPECT_GL_NO_ERROR();
glGetFloatv(GL_FOG_DENSITY, &fogDensity);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(0.0f, fogStart);
EXPECT_EQ(1.0f, fogEnd);
EXPECT_EQ(1.0f, fogDensity);
const GLColor32F kInitialFogColor(0.0f, 0.0f, 0.0f, 0.0f);
GLColor32F initialFogColor;
glGetFloatv(GL_FOG_COLOR, &initialFogColor.R);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(kInitialFogColor, initialFogColor);
}
// Negative test for parameter names.
TEST_P(FogTest, NegativeParameter)
{
glFogfv(0, nullptr);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
// Negative test for parameter values.
TEST_P(FogTest, NegativeValues)
{
glFogf(GL_FOG_MODE, 0.0f);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glFogf(GL_FOG_DENSITY, -1.0f);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}
// Checks that fog state can be set.
TEST_P(FogTest, Set)
{
GLfloat fogValue[4] = {};
glFogf(GL_FOG_MODE, GL_EXP2);
EXPECT_GL_NO_ERROR();
glGetFloatv(GL_FOG_MODE, fogValue);
EXPECT_GL_NO_ERROR();
EXPECT_GLENUM_EQ(GL_EXP2, fogValue[0]);
glFogf(GL_FOG_DENSITY, 2.0f);
EXPECT_GL_NO_ERROR();
glGetFloatv(GL_FOG_DENSITY, fogValue);
EXPECT_GL_NO_ERROR();
EXPECT_GLENUM_EQ(2.0f, fogValue[0]);
glFogf(GL_FOG_START, 2.0f);
EXPECT_GL_NO_ERROR();
glGetFloatv(GL_FOG_START, fogValue);
EXPECT_GL_NO_ERROR();
EXPECT_GLENUM_EQ(2.0f, fogValue[0]);
glFogf(GL_FOG_END, 2.0f);
EXPECT_GL_NO_ERROR();
glGetFloatv(GL_FOG_END, fogValue);
EXPECT_GL_NO_ERROR();
EXPECT_GLENUM_EQ(2.0f, fogValue[0]);
const GLColor32F testColor(0.1f, 0.2f, 0.3f, 0.4f);
glFogfv(GL_FOG_COLOR, &testColor.R);
EXPECT_GL_NO_ERROR();
glGetFloatv(GL_FOG_COLOR, fogValue);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(0.1f, fogValue[0]);
EXPECT_EQ(0.2f, fogValue[1]);
EXPECT_EQ(0.3f, fogValue[2]);
EXPECT_EQ(0.4f, fogValue[3]);
}
ANGLE_INSTANTIATE_TEST(FogTest, ES1_D3D11(), ES1_OPENGL(), ES1_OPENGLES());
......@@ -228,7 +228,6 @@ TEST_P(GLES1ConformanceTest, Dither)
TEST_P(GLES1ConformanceTest, DivZero)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, DivZeroExec());
}
......@@ -239,13 +238,11 @@ TEST_P(GLES1ConformanceTest, EmitMat)
TEST_P(GLES1ConformanceTest, FogExp)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, FogExpExec());
}
TEST_P(GLES1ConformanceTest, FogLin)
{
ANGLE_SKIP_TEST_IF(true);
ASSERT_NE(CONFORMANCE_TEST_ERROR, FogLinExec());
}
......
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