static inline void validate_light(ogles_context_t* c) { // if colorMaterial is enabled, we get the color from the vertex if (!c->lighting.colorMaterial.enable) { material_t& material = c->lighting.front; uint32_t en = c->lighting.enabledLights; while (en) { const int i = 31 - gglClz(en); en &= ~(1<<i); light_t& l = c->lighting.lights[i]; vmul3(l.implicitAmbient.v, material.ambient.v, l.ambient.v); vmul3(l.implicitDiffuse.v, material.diffuse.v, l.diffuse.v); vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v); // this is just a flag to tell if we have a specular component l.implicitSpecular.v[3] = l.implicitSpecular.r | l.implicitSpecular.g | l.implicitSpecular.b; l.rConstAttenuation = (l.attenuation[1] | l.attenuation[2])==0; if (l.rConstAttenuation) l.rConstAttenuation = gglRecipFast(l.attenuation[0]); } // emission and ambient for the whole scene vmla3( c->lighting.implicitSceneEmissionAndAmbient.v, c->lighting.lightModel.ambient.v, material.ambient.v, material.emission.v); c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a; } validate_light_mvi(c); }
void lightVertexMaterial(ogles_context_t* c, vertex_t* v) { // fetch the material color const GLvoid* cp = c->arrays.color.element( v->index & vertex_cache_t::INDEX_MASK); c->arrays.color.fetch(c, v->color.v, cp); // acquire the color-material from the vertex material_t& material = c->lighting.front; material.ambient = material.diffuse = v->color; // implicit arguments need to be computed per/vertex uint32_t en = c->lighting.enabledLights; while (en) { const int i = 31 - gglClz(en); en &= ~(1<<i); light_t& l = c->lighting.lights[i]; vmul3(l.implicitAmbient.v, material.ambient.v, l.ambient.v); vmul3(l.implicitDiffuse.v, material.diffuse.v, l.diffuse.v); vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v); // this is just a flag to tell if we have a specular component l.implicitSpecular.v[3] = l.implicitSpecular.r | l.implicitSpecular.g | l.implicitSpecular.b; } // emission and ambient for the whole scene vmla3( c->lighting.implicitSceneEmissionAndAmbient.v, c->lighting.lightModel.ambient.v, material.ambient.v, material.emission.v); c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a; // now we can light our vertex as usual lightVertex(c, v); }
static void compute_lighting (GLcontext *g, GL_float color[4], GL_float position[4], GL_float normal[3], GL_material *material) { GL_float projpos[4]; GL_float primary[4]; GL_float secondary[4]; GL_float ambient[3]; GL_float diffuse[3] = { 0.0f, 0.0f, 0.0f }; GL_float specular[3] = { 0.0f, 0.0f, 0.0f }; GL_float temp[3]; GL_float E[3]; int i; /* projected position */ if (position[3] == 0.0f) { if (position[3] < 0.0f) vscale3(projpos, position, -1.0f); else vcopy3(projpos, position); vnorm3(projpos, projpos); } else { GL_float scale = 1.0f / position[3]; vscale3(projpos, position, scale); } /* global ambient */ vinit3_col(ambient, g->lighting.lightmodelambient); /* eye vector */ if (g->lighting.lightmodellocalviewer) { vscale3(E, projpos, -1.0f); vnorm3(E, E); } else { vinit3(E, 0.0f, 0.0f, 1.0f); } /* lights */ for (i = 0; i < g->lighting.maxlights; i++) { GLlight *light = &g->lighting.light[i]; if (light->enable) { GL_float lightpos[4]; GL_float L[3], H[3]; GL_float kd, ks; GL_float atten = 1.0f; GL_float dist, distsq; /* light position */ vinit_vec(lightpos, light->position); /* light vector */ if (lightpos[3] == 0.0f) { if (lightpos[3] < 0.0f) vscale3(L, lightpos, -1.0f); else vcopy3(L, lightpos); vnorm3(L, L); if (position[3] == 0.0f) { vsub3(L, L, projpos); vnorm3(L, L); } } else { if (position[3] == 0.0f) vscale3(L, projpos, -1.0f); else { GL_float scale = 1.0f / lightpos[3]; vscale3(L, lightpos, scale); vsub3(L, L, projpos); distsq = vdot3(L, L); dist = sqrt(distsq); scale = 1.0f / dist; vscale(L, L, scale); } } /* halfangle vector */ vadd3(H, L, E); vnorm3(H, H); /* diffuse reflection coefficient */ kd = vdot3(normal, L); kd = max(kd, 0.0f); /* specular reflection coefficient */ ks = vdot3(normal, H); ks = max(ks, 0.0f); ks = (kd > 0.0f) * pow(ks, material->shininess); /* attenuation */ if (lightpos[3] != 0.0f) { GL_float ac = light->constantattenuation; GL_float al = light->linearattenuation; GL_float aq = light->quadraticattenuation; if (position[3] != 0.0f) atten /= (ac + al * dist + aq * distsq); else if (al == 0.0f && aq == 0.0f) atten /= ac; else atten = 0.0f; } /* spot factor */ if (light->spotcutoff != 180.0f) { GL_float S[3], exponent, cutoffcos, anglecos; vinit3_vec(S, light->spotdirection); exponent = light->spotexponent; cutoffcos = cos(light->spotcutoff); anglecos = -vdot3(L, S); anglecos = max(anglecos, 0.0f); if (anglecos < cutoffcos) atten *= pow(anglecos, exponent); else atten = 0.0f; } /* accumulate ambient */ vinit3_col(temp, light->ambient); vscale3(temp, temp, atten); vadd3(ambient, ambient, temp); /* accumulate diffuse */ vinit3_col(temp, light->diffuse); vscale3(temp, temp, kd * atten); vadd3(diffuse, diffuse, temp); /* accumulate specular */ vinit3_col(temp, light->specular); vscale3(temp, temp, ks * atten); vadd3(specular, specular, temp); } } /* primary color */ vcopy3(primary, material->emission); vmul3(ambient, ambient, material->ambient); vadd3(primary, primary, ambient); vmul3(diffuse, diffuse, material->diffuse); vadd3(primary, primary, diffuse); primary[3] = material->diffuse[3]; /* secondary color */ vmul3(secondary, specular, material->specular); secondary[3] = 0.0f; /* computer overall color, no separate specular */ vadd(color, primary, secondary); }