示例#1
0
文件: light.cpp 项目: cxw42/textglc
/* 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;
}
示例#2
0
文件: light.cpp 项目: Akz-/residual
// 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;
}
示例#3
0
/* 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;
}