Implement glColorMaterial
This commit is contained in:
parent
21f8f9d855
commit
b29303fb6c
|
@ -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];
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
31
GL/state.c
31
GL/state.c
|
@ -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
|
||||
|
|
28
GL/texture.c
28
GL/texture.c
|
@ -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];
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user