From e96d379796b386141587b83066d7f02165dc705b Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 12 May 2018 14:05:54 +0100 Subject: [PATCH] Stub out lighting functionality --- experimental/draw.c | 16 ++++ experimental/flush.c | 1 + experimental/lighting.c | 139 +++++++++++++++++++++++++++++++ experimental/private.h | 32 +++++++ experimental/state.c | 41 +++++++++ gl-light.c | 179 ---------------------------------------- include/gl.h | 10 +++ 7 files changed, 239 insertions(+), 179 deletions(-) diff --git a/experimental/draw.c b/experimental/draw.c index ec3e590..9faf048 100644 --- a/experimental/draw.c +++ b/experimental/draw.c @@ -162,6 +162,8 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ const GLubyte* indices_as_bytes = (GLubyte*) indices; + GLboolean lighting_enabled = isLightingEnabled(); + for(GLuint i = first; i < count; ++i) { pvr_vertex_t* vertex = (pvr_vertex_t*) dst; vertex->u = vertex->v = 0.0f; @@ -193,6 +195,20 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ _parseFloats(normal, nptr + (idx * nstride), NORMAL_POINTER.size, NORMAL_POINTER.type); } + if(lighting_enabled) { + GLfloat contribution[4]; + uint32 to_add; + + for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { + if(isLightEnabled(i)) { + calculateLightingContribution(i, &vertex->x, normal, contribution); + to_add = PVR_PACK_COLOR(contribution[0], contribution[1], contribution[2], contribution[3]); + + /* FIXME: Add the colour to argb */ + } + } + } + ++dst; } } diff --git a/experimental/flush.c b/experimental/flush.c index 967725e..1d2d1af 100644 --- a/experimental/flush.c +++ b/experimental/flush.c @@ -66,6 +66,7 @@ void APIENTRY glKosInit() { initAttributePointers(); initContext(); + initLights(); _glKosInitMatrix(); _glKosInitTextures(); diff --git a/experimental/lighting.c b/experimental/lighting.c index e69de29..56eedb3 100644 --- a/experimental/lighting.c +++ b/experimental/lighting.c @@ -0,0 +1,139 @@ +#include "private.h" + +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 LightSource LIGHTS[MAX_LIGHTS]; +static Material MATERIAL; + +void initLights() { + static GLfloat ONE [] = {1.0f, 1.0f, 1.0f, 1.0f}; + static GLfloat ZERO [] = {0.0f, 0.0f, 0.0f, 1.0f}; + static GLfloat PARTIAL [] = {0.2f, 0.2f, 0.2f, 1.0f}; + static GLfloat MOSTLY [] = {0.8f, 0.8f, 0.8f, 1.0f}; + + memcpy(MATERIAL.ambient, PARTIAL, sizeof(GLfloat) * 4); + memcpy(MATERIAL.diffuse, MOSTLY, sizeof(GLfloat) * 4); + memcpy(MATERIAL.specular, ZERO, sizeof(GLfloat) * 4); + memcpy(MATERIAL.emissive, ZERO, sizeof(GLfloat) * 4); + MATERIAL.exponent = 0.0f; + MATERIAL.ambient_color_index = 0.0f; + MATERIAL.diffuse_color_index = 1.0f; + MATERIAL.specular_color_index = 1.0f; + + for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { + memcpy(LIGHTS[i].ambient, ZERO, sizeof(GLfloat) * 4); + memcpy(LIGHTS[i].diffuse, ONE, sizeof(GLfloat) * 4); + memcpy(LIGHTS[i].specular, ONE, sizeof(GLfloat) * 4); + + if(i > 0) { + memcpy(LIGHTS[i].diffuse, ZERO, sizeof(GLfloat) * 4); + memcpy(LIGHTS[i].specular, ZERO, sizeof(GLfloat) * 4); + } + + LIGHTS[i].position[0] = LIGHTS[i].position[1] = LIGHTS[i].position[3] = 0.0f; + LIGHTS[i].position[2] = 1.0f; + + LIGHTS[i].spot_direction[0] = LIGHTS[i].spot_direction[1] = 0.0f; + LIGHTS[i].spot_direction[2] = -1.0f; + + LIGHTS[i].spot_exponent = 0.0f; + LIGHTS[i].spot_cutoff = 180.0f; + + LIGHTS[i].constant_attenuation = 1.0f; + LIGHTS[i].linear_attenuation = 0.0f; + LIGHTS[i].quadratic_attenuation = 0.0f; + } +} + +void APIENTRY glLightModelf(GLenum pname, const GLfloat param) { + glLightModelfv(pname, ¶m); +} + +void APIENTRY glLightModeli(GLenum pname, const GLint param) { + glLightModeliv(pname, ¶m); +} + +void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params) { + switch(pname) { + case GL_LIGHT_MODEL_AMBIENT: + memcpy(SCENE_AMBIENT, params, sizeof(GLfloat) * 4); + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + VIEWER_IN_EYE_COORDINATES = (*params) ? GL_TRUE : GL_FALSE; + break; + case GL_LIGHT_MODEL_TWO_SIDE: + /* Not implemented */ + default: + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + } +} + +void APIENTRY glLightModeliv(GLenum pname, const GLint* params) { + switch(pname) { + case GL_LIGHT_MODEL_COLOR_CONTROL: + COLOR_CONTROL = *params; + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + VIEWER_IN_EYE_COORDINATES = (*params) ? GL_TRUE : GL_FALSE; + break; + default: + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + } +} + +void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) { + GLubyte idx = light & 0xF; + + if(idx >= MAX_LIGHTS) { + return; + } + + switch(pname) { + case GL_AMBIENT: + memcpy(LIGHTS[idx].ambient, params, sizeof(GLfloat) * 4); + break; + case GL_DIFFUSE: + memcpy(LIGHTS[idx].diffuse, params, sizeof(GLfloat) * 4); + break; + case GL_SPECULAR: + memcpy(LIGHTS[idx].specular, params, sizeof(GLfloat) * 4); + break; + case GL_POSITION: + memcpy(LIGHTS[idx].position, params, sizeof(GLfloat) * 4); + break; + case GL_SPOT_CUTOFF: + case GL_SPOT_DIRECTION: + case GL_SPOT_EXPONENT: + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: + default: + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + } +} + +void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param) { + +} + +void APIENTRY glMateriali(GLenum face, GLenum pname, const GLint param) { + +} + +void APIENTRY glMaterialf(GLenum face, GLenum pname, const GLfloat param) { + +} + +void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { + +} + +void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) { + +} diff --git a/experimental/private.h b/experimental/private.h index bf74698..fc7366d 100644 --- a/experimental/private.h +++ b/experimental/private.h @@ -41,10 +41,37 @@ typedef struct { GLvoid *data; } TextureObject; +typedef struct { + GLfloat ambient[4]; + GLfloat diffuse[4]; + GLfloat specular[4]; + GLfloat emissive[4]; + GLfloat exponent; + GLfloat ambient_color_index; + GLfloat diffuse_color_index; + GLfloat specular_color_index; +} Material; + +typedef struct { + GLfloat ambient[4]; + GLfloat diffuse[4]; + GLfloat specular[4]; + GLfloat position[4]; + GLfloat spot_direction[3]; + GLfloat spot_exponent; + GLfloat spot_cutoff; + GLfloat constant_attenuation; + GLfloat linear_attenuation; + GLfloat quadratic_attenuation; +} LightSource; + + PolyList *activePolyList(); void initAttributePointers(); void initContext(); +void initLights(); + pvr_poly_cxt_t* getPVRContext(); GLubyte _glKosInitTextures(); void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject* tx1); @@ -53,8 +80,13 @@ TextureObject* getTexture1(); TextureObject* getBoundTexture(); GLboolean isBlendingEnabled(); +GLboolean isLightingEnabled(); +GLboolean isLightEnabled(GLubyte light); +void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour); + #define PVR_VERTEX_BUF_SIZE 2560 * 256 #define MAX_TEXTURE_UNITS 2 +#define MAX_LIGHTS 8 #define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) diff --git a/experimental/state.c b/experimental/state.c index 7f39d95..c201e8a 100644 --- a/experimental/state.c +++ b/experimental/state.c @@ -150,6 +150,16 @@ void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject *tx1) { } } +static GLboolean LIGHTING_ENABLED = GL_FALSE; +static GLboolean LIGHT_ENABLED[MAX_LIGHTS]; + +GLboolean isLightingEnabled() { + return LIGHTING_ENABLED; +} + +GLboolean isLightEnabled(unsigned char light) { + return LIGHT_ENABLED[light & 0xF]; +} static GLfloat CLEAR_COLOUR[3]; @@ -176,6 +186,11 @@ void initContext() { glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); + + glDisable(GL_LIGHTING); + for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { + glDisable(GL_LIGHT0 + i); + } } GLAPI void APIENTRY glEnable(GLenum cap) { @@ -198,6 +213,19 @@ GLAPI void APIENTRY glEnable(GLenum cap) { case GL_SCISSOR_TEST: { GL_CONTEXT.gen.clip_mode = PVR_USERCLIP_INSIDE; } break; + case GL_LIGHTING: { + LIGHTING_ENABLED = GL_TRUE; + } break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + LIGHT_ENABLED[cap & 0xF] = GL_TRUE; + break; default: break; } @@ -223,6 +251,19 @@ GLAPI void APIENTRY glDisable(GLenum cap) { case GL_SCISSOR_TEST: { GL_CONTEXT.gen.clip_mode = PVR_USERCLIP_DISABLE; } break; + case GL_LIGHTING: { + LIGHTING_ENABLED = GL_FALSE; + } break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + LIGHT_ENABLED[cap & 0xF] = GL_FALSE; + break; default: break; } diff --git a/gl-light.c b/gl-light.c index 30e565f..4a1fa55 100644 --- a/gl-light.c +++ b/gl-light.c @@ -107,18 +107,6 @@ void glNormal3fv(const GLfloat *xyz) { GL_VERTEX_NORMAL[2] = xyz[2]; } -void glLightModelfv(GLenum pname, const GLfloat *params) { - if(pname != GL_LIGHT_MODEL_AMBIENT) { - _glKosThrowError(GL_INVALID_ENUM, "glLightModelfv"); - return; - } - - GL_GLOBAL_AMBIENT[0] = params[0]; - GL_GLOBAL_AMBIENT[1] = params[1]; - GL_GLOBAL_AMBIENT[2] = params[2]; - GL_GLOBAL_AMBIENT[3] = params[3]; -} - /* Misc Lighting Functions ************************************/ static inline void glCopyRGBA(const rgba *src, rgba *dst) { *dst = *src; @@ -132,173 +120,6 @@ static inline void glCopy3f(const float *src, float *dst) { memcpy(dst, src, 0xC); } -/* GL Light Parameters ******************************************************/ - -void glLightfv(GLenum light, GLenum pname, const GLfloat *params) { - if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) return; - - switch(pname) { - case GL_AMBIENT: - glCopyRGBA((rgba *)params, (rgba *)&GL_LIGHTS[light & 0xF].Ka); - break; - - case GL_DIFFUSE: - glCopyRGBA((rgba *)params, (rgba *)&GL_LIGHTS[light & 0xF].Kd); - break; - - case GL_SPECULAR: - glCopyRGBA((rgba *)params, (rgba *)&GL_LIGHTS[light & 0xF].Ks); - break; - - case GL_POSITION: - glCopy4f(params, &GL_LIGHTS[light & 0xF].Pos[0]); - break; - - case GL_SPOT_DIRECTION: - glCopy3f(params, &GL_LIGHTS[light & 0xF].Dir[0]); - break; - - case GL_SPOT_EXPONENT: - GL_LIGHTS[light & 0xF].Exponent = *params; - break; - - case GL_SPOT_CUTOFF: - if(*params >= 0.0f && *params <= 180.0f) - GL_LIGHTS[light & 0xF].CutOff = LCOS(*params); - - break; - - case GL_CONSTANT_ATTENUATION: - if(*params >= 0) - GL_LIGHTS[light & 0xF].Kc = *params; - else - GL_LIGHTS[light & 0xF].Kc = 0; - - break; - - case GL_LINEAR_ATTENUATION: - if(*params >= 0) - GL_LIGHTS[light & 0xF].Kl = *params; - else - GL_LIGHTS[light & 0xF].Kl = 0; - - break; - - case GL_QUADRATIC_ATTENUATION: - if(*params >= 0) - GL_LIGHTS[light & 0xF].Kq = *params; - else - GL_LIGHTS[light & 0xF].Kq = 0; - - break; - - case GL_AMBIENT_AND_DIFFUSE: - glCopyRGBA((rgba *)params, (rgba *)&GL_LIGHTS[light & 0xF].Ka); - glCopyRGBA((rgba *)params, (rgba *)&GL_LIGHTS[light & 0xF].Kd); - break; - } -} - -void glLightf(GLenum light, GLenum pname, GLfloat param) { - if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) return; - - switch(pname) { - case GL_CONSTANT_ATTENUATION: - if(param >= 0) - GL_LIGHTS[light & 0xF].Kc = param; - else - GL_LIGHTS[light & 0xF].Kc = 0; - - break; - - case GL_LINEAR_ATTENUATION: - if(param >= 0) - GL_LIGHTS[light & 0xF].Kl = param; - else - GL_LIGHTS[light & 0xF].Kl = 0; - - break; - - case GL_QUADRATIC_ATTENUATION: - if(param >= 0) - GL_LIGHTS[light & 0xF].Kq = param; - else - GL_LIGHTS[light & 0xF].Kq = 0; - - break; - - case GL_SPOT_CUTOFF: - if(param >= 0.0f && param <= 180.0f) - GL_LIGHTS[light & 0xF].CutOff = LCOS(param); - - break; - - case GL_SPOT_EXPONENT: - GL_LIGHTS[light & 0xF].Exponent = param; - break; - } -} - -/* GL Material Parameters **************************************************/ - -void glMateriali(GLenum face, GLenum pname, const GLint param) { - //if(face!=GL_FRONT_AND_BACK) return; - - if(pname == GL_SHININESS) { - if(param < 0) - GL_MATERIAL.Shine = 0; - else if(param > 128) - GL_MATERIAL.Shine = 128; - else - GL_MATERIAL.Shine = param; - } -} - -void glMaterialf(GLenum face, GLenum pname, const GLfloat param) { - //if(face!=GL_FRONT_AND_BACK) return; - - if(pname == GL_SHININESS) { - if(param < 0) - GL_MATERIAL.Shine = 0; - else if(param > 128.0) - GL_MATERIAL.Shine = 128.0; - else - GL_MATERIAL.Shine = param; - } -} - -void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { - //if(face!=GL_FRONT_AND_BACK) return; - - switch(pname) { - case GL_AMBIENT: - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Ka[0]); - break; - - case GL_DIFFUSE: - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Kd[0]); - break; - - case GL_SPECULAR: - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Ks[0]); - break; - - case GL_EMISSION: - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Ke[0]); - break; - - case GL_SHININESS: - glMaterialf(GL_FRONT_AND_BACK, pname, *params); - break; - - case GL_AMBIENT_AND_DIFFUSE: - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Ka[0]); - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Kd[0]); - break; - } - -} - /* Vertex Lighting **********************************************************/ /* Fast POW Implementation - Less accurate, but much faster than math.h */ diff --git a/include/gl.h b/include/gl.h index 0d87dbe..60f5a09 100644 --- a/include/gl.h +++ b/include/gl.h @@ -235,6 +235,11 @@ __BEGIN_DECLS #define GL_LIGHT14 0x400E #define GL_LIGHT15 0x400F +/* EXT_separate_specular_color.txt */ +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA + /* Client state caps */ #define GL_VERTEX_ARRAY 0x8074 #define GL_NORMAL_ARRAY 0x8075 @@ -620,7 +625,12 @@ GLAPI void APIENTRY glFogfv(GLenum pname, const GLfloat *params); /* Set Individual Light Parameters */ GLAPI void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param); + +GLAPI void APIENTRY glLightModelf(GLenum pname, const GLfloat param); +GLAPI void APIENTRY glLightModeli(GLenum pname, const GLint param); GLAPI void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glLightModeliv(GLenum pname, const GLint *params); + /* Set Global Material Parameters */ GLAPI void APIENTRY glMateriali(GLenum face, GLenum pname, const GLint param);