/* non optimized lightening model */ void gl_shade_vertex(GLContext *c,GLVertex *v) { GLfloat R,G,B,A; GLMaterial *m; GLLight *l; glm::vec3 n,s,d; GLfloat dist,tmp,att,dot,dot_spot,dot_spec; int twoside = c->light_model_two_side; m=&c->materials[0]; n.x=v->normal.x; n.y=v->normal.y; n.z=v->normal.z; R=(m->emission.x+ (m->ambient.x* c->ambient_light_model.x)); G=(m->emission.y+ (m->ambient.y* c->ambient_light_model.y)); B=(m->emission.z+ (m->ambient.z* c->ambient_light_model.z)); A=clampf(m->diffuse.w, (float)(0), (float)(1)); for(l=c->first_light;l!=NULL;l=l->next) { GLfloat lR,lB,lG; /* ambient */ lR=(l->ambient.x* m->ambient.x); lG=(l->ambient.y* m->ambient.y); lB=(l->ambient.z* m->ambient.z); if ((float)(l->position.w) == (float)((float)(0))) { /* light at infinity */ d.x=l->position.x; d.y=l->position.y; d.z=l->position.z; att=(float)(1); } else { /* distance attenuation */ d.x=(l->position.x- v->ec.x); d.y=(l->position.y- v->ec.y); d.z=(l->position.z- v->ec.z); dist=(float)sqrt((((d.x*d.x)+ (d.y*d.y))+ (d.z*d.z))); if ((float)(dist)>(float)((1E-3))) { tmp=((float)(1)/dist); d.x=(d.x* tmp); d.y=(d.y* tmp); d.z=(d.z* tmp); } att=((float)(1)/ (l->attenuation[0]+(dist* (l->attenuation[1]+(dist* l->attenuation[2]))))); } dot=(((d.x*n.x)+ (d.y*n.y))+ (d.z*n.z)); if (twoside && (float)(dot) < (float)((float)(0))) dot = -(dot); if ((float)(dot)>(float)((float)(0))) { /* diffuse light */ lR = (lR+ ((dot* l->diffuse.x)* m->diffuse.x)); lG = (lG+ ((dot* l->diffuse.y)* m->diffuse.y)); lB = (lB+ ((dot* l->diffuse.z)* m->diffuse.z)); /* spot light */ if ((float)(l->spot_cutoff) != (float)((float)(180))) { dot_spot=-((((d.x*l->norm_spot_direction.x)+(d.y*l->norm_spot_direction.y))+(d.z*l->norm_spot_direction.z))); if (twoside && (float)(dot_spot) < (float)((float)(0))) dot_spot = -(dot_spot); if ((float)(dot_spot) < (float)(l->cos_spot_cutoff)) { /* no contribution */ continue; } else { /* TODO: optimize */ if ((float)(l->spot_exponent) > (float)((float)(0))) { att=(att* (float)pow(dot_spot,l->spot_exponent)); } } } /* specular light */ if (c->local_light_model) { glm::vec3 vcoord; vcoord.x=v->ec.x; vcoord.y=v->ec.y; vcoord.z=v->ec.z; vcoord = glm::normalize(vcoord); //gl_V3_Norm(&vcoord); s.x=(d.x- vcoord.x); s.y=(d.y- vcoord.x); s.z=(d.z- vcoord.x); } else { s.x=d.x; s.y=d.y; s.z=(d.z+ (float)(1)); } dot_spec=(((n.x*s.x)+ (n.y*s.y))+(n.z*s.z)); if (twoside && (float)(dot_spec) < (float)((float)(0))) dot_spec = -(dot_spec); if ((float)(dot_spec)>(float)((float)(0))) { GLSpecBuf *specbuf; int idx; tmp=(float)sqrt((((s.x*s.x)+(s.y*s.y))+(s.z*s.z))); if ((float)(tmp) > (float)((1E-3))) { dot_spec=(dot_spec/ tmp); } /* TODO: optimize */ /* testing specular buffer code */ /* dot_spec= pow(dot_spec,m->shininess);*/ specbuf = specbuf_get_buffer(c, m->shininess_i, m->shininess); idx = (int)((dot_spec* (float)(SPECULAR_BUFFER_SIZE))); if (idx > SPECULAR_BUFFER_SIZE) idx = SPECULAR_BUFFER_SIZE; dot_spec = specbuf->buf[idx]; lR=(lR+ ((dot_spec* l->specular.x)* m->specular.x)); lG=(lG+ ((dot_spec* l->specular.y)* m->specular.y)); lB=(lB+ ((dot_spec* l->specular.z)* m->specular.z)); } } R=(R+ (att* lR)); G=(G+ (att* lG)); B=(B+ (att* lB)); } v->color.x=clampf(R, (float)(0), (float)(1)); v->color.y=clampf(G, (float)(0), (float)(1)); v->color.z=clampf(B, (float)(0), (float)(1)); v->color.w=A; }
// non optimized lightening model void gl_shade_vertex(GLContext *c, GLVertex *v) { float R, G, B, A; GLMaterial *m; GLLight *l; Vector3 n, s, d; float dist, tmp, att, dot, dot_spot, dot_spec; int twoside = c->light_model_two_side; m = &c->materials[0]; n = v->normal; R = m->emission.X + m->ambient.X * c->ambient_light_model.X; G = m->emission.Y + m->ambient.Y * c->ambient_light_model.Y; B = m->emission.Z + m->ambient.Z * c->ambient_light_model.Z; A = clampf(m->diffuse.W, 0, 1); for (l = c->first_light; l != NULL; l = l->next) { float lR, lB, lG; // ambient lR = l->ambient.X * m->ambient.X; lG = l->ambient.Y * m->ambient.Y; lB = l->ambient.Z * m->ambient.Z; if (l->position.W == 0) { // light at infinity d.X = l->position.X; d.Y = l->position.Y; d.Z = l->position.Z; att = 1; } else { // distance attenuation d.X = l->position.X - v->ec.X; d.Y = l->position.Y - v->ec.Y; d.Z = l->position.Z - v->ec.Z; dist = sqrt(d.X * d.X + d.Y * d.Y + d.Z * d.Z); if (dist > 1E-3) { tmp = 1 / dist; d *= tmp; } att = 1.0f / (l->attenuation[0] + dist * (l->attenuation[1] + dist * l->attenuation[2])); } dot = d.X * n.X + d.Y * n.Y + d.Z * n.Z; if (twoside && dot < 0) dot = -dot; if (dot > 0) { // diffuse light lR += dot * l->diffuse.X * m->diffuse.X; lG += dot * l->diffuse.Y * m->diffuse.Y; lB += dot * l->diffuse.Z * m->diffuse.Z; // spot light if (l->spot_cutoff != 180) { dot_spot = -(d.X * l->norm_spot_direction.X + d.Y * l->norm_spot_direction.Y + d.Z * l->norm_spot_direction.Z); if (twoside && dot_spot < 0) dot_spot = -dot_spot; if (dot_spot < l->cos_spot_cutoff) { // no contribution continue; } else { // TODO: optimize if (l->spot_exponent > 0) { att = att * pow(dot_spot, l->spot_exponent); } } } // specular light if (c->local_light_model) { Vector3 vcoord; vcoord.X = v->ec.X; vcoord.Y = v->ec.Y; vcoord.Z = v->ec.Z; vcoord.normalize(); s.X = d.X - vcoord.X; s.Y = d.Y - vcoord.Y; s.Z = d.Z - vcoord.Z; } else { s.X = d.X; s.Y = d.Y; s.Z = (float)(d.Z + 1.0); } dot_spec = n.X * s.X + n.Y * s.Y + n.Z * s.Z; if (twoside && dot_spec < 0) dot_spec = -dot_spec; if (dot_spec > 0) { GLSpecBuf *specbuf; int idx; tmp = sqrt(s.X * s.X + s.Y * s.Y + s.Z * s.Z); if (tmp > 1E-3) { dot_spec = dot_spec / tmp; } // TODO: optimize // testing specular buffer code // dot_spec= pow(dot_spec,m->shininess) specbuf = specbuf_get_buffer(c, m->shininess_i, m->shininess); tmp = dot_spec * SPECULAR_BUFFER_SIZE; if (tmp > SPECULAR_BUFFER_SIZE) idx = SPECULAR_BUFFER_SIZE; else idx = (int)tmp; dot_spec = specbuf->buf[idx]; lR += dot_spec * l->specular.X * m->specular.X; lG += dot_spec * l->specular.Y * m->specular.Y; lB += dot_spec * l->specular.Z * m->specular.Z; } } R += att * lR; G += att * lG; B += att * lB; } v->color.X = clampf(c->current_color.X * R, 0, 1); v->color.Y = clampf(c->current_color.Y * G, 0, 1); v->color.Z = clampf(c->current_color.Z * B, 0, 1); v->color.W = c->current_color.W * A; }
/* non optimized lightening model */ void gl_shade_vertex(GLContext *c,GLVertex *v) { float R,G,B,A; GLMaterial *m; GLLight *l; V3 n,s,d; float dist,tmp,att,dot,dot_spot,dot_spec; int twoside = c->light_model_two_side; m=&c->materials[0]; n.X=v->normal.X; n.Y=v->normal.Y; n.Z=v->normal.Z; R=m->emission.v[0]+m->ambient.v[0]*c->ambient_light_model.v[0]; G=m->emission.v[1]+m->ambient.v[1]*c->ambient_light_model.v[1]; B=m->emission.v[2]+m->ambient.v[2]*c->ambient_light_model.v[2]; A=clampf(m->diffuse.v[3],0,1); for(l=c->first_light; l!=NULL; l=l->next) { float lR,lB,lG; /* ambient */ lR=l->ambient.v[0] * m->ambient.v[0]; lG=l->ambient.v[1] * m->ambient.v[1]; lB=l->ambient.v[2] * m->ambient.v[2]; if (l->position.v[3] == 0) { /* light at infinity */ d.X=l->position.v[0]; d.Y=l->position.v[1]; d.Z=l->position.v[2]; att=1; } else { /* distance attenuation */ d.X=l->position.v[0]-v->ec.v[0]; d.Y=l->position.v[1]-v->ec.v[1]; d.Z=l->position.v[2]-v->ec.v[2]; dist=(float)sqrt(d.X*d.X+d.Y*d.Y+d.Z*d.Z); if (dist>1E-3) { tmp=1/dist; d.X*=tmp; d.Y*=tmp; d.Z*=tmp; } att=1.0f/(l->attenuation[0]+dist*(l->attenuation[1]+ dist*l->attenuation[2])); } dot=d.X*n.X+d.Y*n.Y+d.Z*n.Z; if (twoside && dot < 0) dot = -dot; if (dot>0) { /* diffuse light */ lR+=dot * l->diffuse.v[0] * m->diffuse.v[0]; lG+=dot * l->diffuse.v[1] * m->diffuse.v[1]; lB+=dot * l->diffuse.v[2] * m->diffuse.v[2]; /* spot light */ if (l->spot_cutoff != 180) { dot_spot=-(d.X*l->norm_spot_direction.v[0]+ d.Y*l->norm_spot_direction.v[1]+ d.Z*l->norm_spot_direction.v[2]); if (twoside && dot_spot < 0) dot_spot = -dot_spot; if (dot_spot < l->cos_spot_cutoff) { /* no contribution */ continue; } else { /* TODO: optimize */ if (l->spot_exponent > 0) { att=(float)(att*pow(dot_spot,l->spot_exponent)); } } } /* specular light */ if (c->local_light_model) { V3 vcoord; vcoord.X=v->ec.X; vcoord.Y=v->ec.Y; vcoord.Z=v->ec.Z; r7_v3_normal(&vcoord); s.X=d.X-vcoord.X; s.Y=d.Y-vcoord.X; s.Z=d.Z-vcoord.X; } else { s.X=d.X; s.Y=d.Y; s.Z=d.Z+1.0f; } dot_spec=n.X*s.X+n.Y*s.Y+n.Z*s.Z; if (twoside && dot_spec < 0) dot_spec = -dot_spec; if (dot_spec>0) { GLSpecBuf *specbuf; int idx; tmp=(float)sqrt(s.X*s.X+s.Y*s.Y+s.Z*s.Z); if (tmp > 1E-3) { dot_spec=dot_spec / tmp; } /* TODO: optimize */ /* testing specular buffer code */ /* dot_spec= pow(dot_spec,m->shininess);*/ specbuf = specbuf_get_buffer(c, m->shininess_i, m->shininess); idx = (int)(dot_spec*SPECULAR_BUFFER_SIZE); if (idx > SPECULAR_BUFFER_SIZE) idx = SPECULAR_BUFFER_SIZE; dot_spec = specbuf->buf[idx]; lR+=dot_spec * l->specular.v[0] * m->specular.v[0]; lG+=dot_spec * l->specular.v[1] * m->specular.v[1]; lB+=dot_spec * l->specular.v[2] * m->specular.v[2]; } } R+=att * lR; G+=att * lG; B+=att * lB; } v->color.v[0]=clampf(R,0,1); v->color.v[1]=clampf(G,0,1); v->color.v[2]=clampf(B,0,1); v->color.v[3]=A; }