Implement glColorMaterial

This commit is contained in:
Luke Benstead 2018-08-22 09:24:49 +01:00
parent 21f8f9d855
commit b29303fb6c
5 changed files with 101 additions and 35 deletions

View File

@ -737,7 +737,7 @@ static void light(ClipVertex* output, const GLsizei count) {
GLubyte j;
for(j = 0; j < MAX_LIGHTS; ++j) {
if(isLightEnabled(j)) {
calculateLightingContribution(j, ES->xyz, ES->n, to_add);
_glCalculateLightingContribution(j, ES->xyz, ES->n, vertex->bgra, to_add);
total[0] += to_add[0];
total[1] += to_add[1];

View File

@ -8,6 +8,7 @@ static GLfloat SCENE_AMBIENT [] = {0.2, 0.2, 0.2, 1.0};
static GLboolean VIEWER_IN_EYE_COORDINATES = GL_TRUE;
static GLenum COLOR_CONTROL = GL_SINGLE_COLOR;
static GLboolean TWO_SIDED_LIGHTING = GL_FALSE;
static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
static LightSource LIGHTS[MAX_LIGHTS];
static Material MATERIAL;
@ -210,6 +211,34 @@ void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
}
}
void glColorMaterial(GLenum face, GLenum mode) {
if(face != GL_FRONT_AND_BACK) {
_glKosThrowError(GL_INVALID_ENUM, __func__);
_glKosPrintError();
return;
}
GLenum validModes[] = {GL_AMBIENT, GL_DIFFUSE, GL_AMBIENT_AND_DIFFUSE, GL_EMISSION, GL_SPECULAR, 0};
if(_glCheckValidEnum(mode, validModes, __func__) != 0) {
return;
}
COLOR_MATERIAL_MODE = mode;
}
static inline GLboolean isDiffuseColorMaterial() {
return (COLOR_MATERIAL_MODE == GL_DIFFUSE || COLOR_MATERIAL_MODE == GL_AMBIENT_AND_DIFFUSE);
}
static inline GLboolean isAmbientColorMaterial() {
return (COLOR_MATERIAL_MODE == GL_AMBIENT || COLOR_MATERIAL_MODE == GL_AMBIENT_AND_DIFFUSE);
}
static inline GLboolean isSpecularColorMaterial() {
return (COLOR_MATERIAL_MODE == GL_SPECULAR);
}
inline void initVec3(struct vec3f* v, const GLfloat* src) {
memcpy(v, src, sizeof(GLfloat) * 3);
}
@ -240,8 +269,8 @@ static float FPOW(float b, float p) {
return FEXP(FLOG(b) * p);
}
void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) __attribute__((optimize("fast-math")));
void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) {
void _glCalculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, uint8_t* bgra, GLfloat* colour) __attribute__((optimize("fast-math")));
void _glCalculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, uint8_t* bgra, GLfloat* colour) {
LightSource* l = &LIGHTS[light];
struct vec3f L = {
@ -290,15 +319,38 @@ void calculateLightingContribution(const GLint light, const GLfloat* pos, const
GLfloat VdotR = VdotN - NdotL;
GLfloat specularPower = FPOW(VdotR > 0 ? VdotR : 0, MATERIAL.exponent);
colour[0] = l->ambient[0] * MATERIAL.ambient[0];
colour[1] = l->ambient[1] * MATERIAL.ambient[1];
colour[2] = l->ambient[2] * MATERIAL.ambient[2];
colour[3] = MATERIAL.diffuse[3];
GLboolean colorMaterial = _glIsColorMaterialEnabled();
GLfloat mD [] = {
(colorMaterial && isDiffuseColorMaterial()) ? ((GLfloat)bgra[R8IDX]) / 255.0f : MATERIAL.diffuse[0],
(colorMaterial && isDiffuseColorMaterial()) ? ((GLfloat)bgra[G8IDX]) / 255.0f : MATERIAL.diffuse[1],
(colorMaterial && isDiffuseColorMaterial()) ? ((GLfloat)bgra[B8IDX]) / 255.0f : MATERIAL.diffuse[2],
(colorMaterial && isDiffuseColorMaterial()) ? ((GLfloat)bgra[A8IDX]) / 255.0f : MATERIAL.diffuse[3]
};
GLfloat mA [] = {
(colorMaterial && isAmbientColorMaterial()) ? ((GLfloat)bgra[R8IDX]) / 255.0f : MATERIAL.ambient[0],
(colorMaterial && isAmbientColorMaterial()) ? ((GLfloat)bgra[G8IDX]) / 255.0f : MATERIAL.ambient[1],
(colorMaterial && isAmbientColorMaterial()) ? ((GLfloat)bgra[B8IDX]) / 255.0f : MATERIAL.ambient[2],
(colorMaterial && isAmbientColorMaterial()) ? ((GLfloat)bgra[A8IDX]) / 255.0f : MATERIAL.ambient[3]
};
GLfloat mS [] = {
(colorMaterial && isSpecularColorMaterial()) ? ((GLfloat)bgra[R8IDX]) / 255.0f : MATERIAL.specular[0],
(colorMaterial && isSpecularColorMaterial()) ? ((GLfloat)bgra[G8IDX]) / 255.0f : MATERIAL.specular[1],
(colorMaterial && isSpecularColorMaterial()) ? ((GLfloat)bgra[B8IDX]) / 255.0f : MATERIAL.specular[2],
(colorMaterial && isSpecularColorMaterial()) ? ((GLfloat)bgra[A8IDX]) / 255.0f : MATERIAL.specular[3]
};
colour[0] = l->ambient[0] * mA[0];
colour[1] = l->ambient[1] * mA[1];
colour[2] = l->ambient[2] * mA[2];
colour[3] = mD[3];
if(NdotL >= 0) {
colour[0] += (l->diffuse[0] * MATERIAL.diffuse[0] * NdotL + l->specular[0] * MATERIAL.specular[0] * specularPower);
colour[1] += (l->diffuse[1] * MATERIAL.diffuse[1] * NdotL + l->specular[1] * MATERIAL.specular[1] * specularPower);
colour[2] += (l->diffuse[2] * MATERIAL.diffuse[2] * NdotL + l->specular[2] * MATERIAL.specular[2] * specularPower);
colour[0] += (l->diffuse[0] * mD[0] * NdotL + l->specular[0] * mS[0] * specularPower);
colour[1] += (l->diffuse[1] * mD[1] * NdotL + l->specular[1] * mS[1] * specularPower);
colour[2] += (l->diffuse[2] * mD[2] * NdotL + l->specular[2] * mS[2] * specularPower);
}
if(!l->is_directional) {

View File

@ -112,6 +112,8 @@ typedef struct {
GLint size;
} AttribPointer;
GLboolean _glCheckValidEnum(GLint param, GLenum* values, const char* func);
GLuint _glGetEnabledAttributes();
AttribPointer* _glGetVertexAttribPointer();
AttribPointer* _glGetDiffuseAttribPointer();
@ -132,7 +134,8 @@ GLuint _glGetMipmapLevelCount(TextureObject* obj);
GLboolean isLightingEnabled();
GLboolean isLightEnabled(GLubyte light);
void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour);
GLboolean _glIsColorMaterialEnabled();
void _glCalculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, uint8_t* bgra, GLfloat* colour);
unsigned char isClippingEnabled();
void enableClipping(unsigned char v);

View File

@ -25,6 +25,7 @@ pvr_poly_cxt_t* getPVRContext() {
static GLenum CULL_FACE = GL_BACK;
static GLenum FRONT_FACE = GL_CCW;
static GLboolean CULLING_ENABLED = GL_FALSE;
static GLboolean COLOR_MATERIAL_ENABLED = GL_FALSE;
static int _calc_pvr_face_culling() {
if(!CULLING_ENABLED) {
@ -116,6 +117,25 @@ static void _updatePVRBlend(pvr_poly_cxt_t* context) {
}
}
GLboolean _glCheckValidEnum(GLint param, GLenum* values, const char* func) {
GLubyte found = 0;
while(*values != 0) {
if(*values == param) {
found++;
break;
}
values++;
}
if(!found) {
_glKosThrowError(GL_INVALID_ENUM, func);
_glKosPrintError();
return GL_TRUE;
}
return GL_FALSE;
}
static GLboolean TEXTURES_ENABLED [] = {GL_FALSE, GL_FALSE};
void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
@ -207,6 +227,10 @@ GLboolean isLightEnabled(unsigned char light) {
return LIGHT_ENABLED[light & 0xF];
}
GLboolean _glIsColorMaterialEnabled() {
return COLOR_MATERIAL_ENABLED;
}
static GLfloat CLEAR_COLOUR[3];
void initContext() {
@ -264,6 +288,9 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
case GL_FOG:
GL_CONTEXT.gen.fog_type = PVR_FOG_TABLE;
break;
case GL_COLOR_MATERIAL:
COLOR_MATERIAL_ENABLED = GL_TRUE;
break;
case GL_LIGHT0:
case GL_LIGHT1:
case GL_LIGHT2:
@ -308,6 +335,9 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
case GL_FOG:
GL_CONTEXT.gen.fog_type = PVR_FOG_DISABLE;
break;
case GL_COLOR_MATERIAL:
COLOR_MATERIAL_ENABLED = GL_FALSE;
break;
case GL_LIGHT0:
case GL_LIGHT1:
case GL_LIGHT2:
@ -419,6 +449,7 @@ void glPixelStorei(GLenum pname, GLint param) {
;
}
/* Setup the hardware user clip rectangle.
The minimum clip rectangle is a 32x32 area which is dependent on the tile

View File

@ -108,26 +108,6 @@ TextureObject* getBoundTexture() {
return TEXTURE_UNITS[ACTIVE_TEXTURE];
}
GLubyte check_valid_enum(GLint param, GLenum* values, const char* func) {
GLubyte found = 0;
while(*values != 0) {
if(*values == param) {
found++;
break;
}
values++;
}
if(!found) {
_glKosThrowError(GL_INVALID_ENUM, func);
_glKosPrintError();
return 1;
}
return 0;
}
void APIENTRY glActiveTextureARB(GLenum texture) {
TRACE();
@ -195,7 +175,7 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) {
GLenum target_values [] = {GL_TEXTURE_2D, 0};
if(check_valid_enum(target, target_values, __func__) != 0) {
if(_glCheckValidEnum(target, target_values, __func__) != 0) {
return;
}
@ -215,9 +195,9 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
GLubyte failures = 0;
failures += check_valid_enum(target, target_values, __func__);
failures += check_valid_enum(pname, pname_values, __func__);
failures += check_valid_enum(param, param_values, __func__);
failures += _glCheckValidEnum(target, target_values, __func__);
failures += _glCheckValidEnum(pname, pname_values, __func__);
failures += _glCheckValidEnum(param, param_values, __func__);
TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE];