Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
}