Exemplo n.º 1
0
// Light's Functions
void AreaLight::AccumulateIlluminationAtSurface(
    const Ray           &ray,
    const Vector<float> &surfaceNormal,
    const float         &surfaceRoughness,
    const Scene         &scene,
    Color &diffuse,
    Color &specular ) const
{
    if( _positions.empty() )
        return;

    Color areaLightDiffuse( 0 );
    Color areaLightSpecular( 0 );

    // Accumulate the illumination from all the positions
    for(VectorList::const_iterator itr = _positions.begin(); itr != _positions.end(); ++itr )
    {
        const Vector<float> &lightPosition = (*itr);

        Vector<float> lightRayDirection = lightPosition - ray.Origin();
        const float lightRayLength = lightRayDirection.Normalize();

        // If the light is out of range of the surface
        if( lightRayLength > _range )
            continue;

        // The illumination from this light
        const Ray lightRay( ray.Origin(), lightRayDirection, ray );
        const Color illuminationFromLight = Illumination( lightRay, lightRayLength, scene );

        if( illuminationFromLight.Magnitude2() < Maths::Tolerance )
            continue;

        // Calculate the illumination at the point on the surface
        const Color illumination = illuminationFromLight * ( 1 - lightRayLength * _oneOverRange );

        // Accumulate the diffuse
        areaLightDiffuse += illumination * Maths::Max<float>(0, surfaceNormal.Dot( lightRayDirection ));

        // Accumulate the specular
        areaLightSpecular += illuminationFromLight * powf( Maths::Max<float>(0, ray.Direction().Dot( lightRayDirection.Reflect( surfaceNormal ) ) ), surfaceRoughness );
    }

    diffuse += areaLightDiffuse * (1.0f / _positions.size());
    specular += areaLightSpecular * (1.0f / _positions.size());
}
Exemplo n.º 2
0
int Render_SSD(SCENE *ascene, CAMERA *acamera)
{
  /* We clear all pixels  */
  glClearColor(ascene->bcolor.rgba[0], ascene->bcolor.rgba[1],
	       ascene->bcolor.rgba[2], ascene->bcolor.rgba[3]);
  glClear (GL_COLOR_BUFFER_BIT);
  	int i,j;
	double matrixFinal[4][4],mTransform[4][4];
	double intermediaM[4][4],mCam[4][4],mInverse[4][4],tmpMatrix[4][4];
	double mTranslate[4][4],mRotate[4][4],mScale[4][4];
	double homo_coordinates[4] = {0,0,0,1};
	//double mInverse[4][4];
	
	matrixInitial(matrixFinal);
	matrixInitial(mTransform);
	matrixInitial(mTranslate);
	matrixInitial(mRotate);
	matrixInitial(mScale);
	
	int screenW = ascene->screen_w;
	int screenH = ascene->screen_h;

	buffer = (HIDDEN *)malloc(sizeof(HIDDEN) * screenW * screenH);


	for(i = 0;i < screenW * screenH;i++)
	{
		buffer[i].rgba[0] = ascene->bcolor.rgba[0];
		buffer[i].rgba[1] = ascene->bcolor.rgba[1];
		buffer[i].rgba[2] = ascene->bcolor.rgba[2];
		buffer[i].z = 9999;
	}

	/* Camera View */
	int ii;
	matrixInitial(mInverse);
	matrixInitial(tmpMatrix);
	matrixInitial(intermediaM);
	matrixInitial(mCam);
	double u[3],v[3],w[3];
	double gaze[3] = {acamera->gaze.xyzw[0],acamera->gaze.xyzw[1],acamera->gaze.xyzw[2]};
	double upVector[3] = {acamera->upVector.xyzw[0],acamera->upVector.xyzw[1],acamera->upVector.xyzw[2]};
	
	vecUnitization(gaze,w);

	for(ii = 0; ii < 3; ii++){
		w[ii] = -w[ii];
	}
	vecCross(upVector,w,u);
	vecUnitization(u,u);
	vecCross(w,u,v);
	ii = 0;
	for(ii = 0; ii < 3; ii++){
		intermediaM[0][ii] = u[ii];
		intermediaM[1][ii] = v[ii];
		intermediaM[2][ii] = w[ii];
		mCam[ii][3] = -acamera->eye.xyzw[ii];
	}	
	matrixMultiply(intermediaM,mCam,0);
	
	/*inverse  matrixMultiply() 0:normal  1:inverse */
	matrixInitial(intermediaM);
	ii = 0;
	for(ii = 0; ii < 3; ii++){
		intermediaM[ii][0] = u[ii];
		intermediaM[ii][1] = v[ii];
		intermediaM[ii][2] = w[ii];
		tmpMatrix[ii][3] = acamera->eye.xyzw[ii];
	}	
	matrixMultiply(mInverse,tmpMatrix,1);
	matrixMultiply(mInverse,intermediaM,1);


	/*Persective(1) and Orthographic(0) Projection matrix*/
	double anglePers, nearPers, farPers, rightOrtho, topOrtho, farOrtho, nearOrtho,pjType;
	double screenWidth,screenHeight;
	screenWidth = ascene->screen_w;
	screenHeight = ascene->screen_h;
	anglePers = ascene->persp.angle;
	nearPers = ascene->persp.near;
	farPers = ascene->persp.far; 
	rightOrtho = ascene->ortho.right;
	topOrtho = ascene->ortho.top;
	farOrtho = ascene->ortho.far; 
	nearOrtho = ascene->ortho.near;
	pjType = ascene->pjType;

	getFinalTransformMatrix(anglePers, nearPers, farPers, rightOrtho, topOrtho, farOrtho, nearOrtho, pjType, screenWidth, screenHeight, mCam, matrixFinal,mInverse);

	double vpInverse[4][4];
	matrixInitial(vpInverse);
	vpInverse[0][0] = (double)2/ascene->screen_w;
	vpInverse[0][3] = (double)(1-ascene->screen_w)/ascene->screen_w;
	vpInverse[1][1] = (double)2/ascene->screen_h;
	vpInverse[1][3] = (double)(1-ascene->screen_h)/ascene->screen_h;
	matrixMultiply(mInverse,vpInverse,1);

	/* Draw floor */
	double xmin,xmax,ymin,ymax,floorEdge;
	int nX,nY;

	xmin = ascene->floor.xmin;
	xmax = ascene->floor.xmax;
	ymin = ascene->floor.ymin;
	ymax = ascene->floor.ymax;
	floorEdge = ascene->floor.size;
	nY = ((xmax-xmin)/floorEdge) + 1;
	nX = ((ymax-ymin)/floorEdge) + 1;
	Line floor[nX + nY];
	
	glLineWidth(2);
	glBegin(GL_LINES);
	glColor3f(ascene->floor.color.rgba[0],ascene->floor.color.rgba[1],ascene->floor.color.rgba[2]);
	drawFloor(xmin,xmax,ymin,ymax,nX,nY,floorEdge,matrixFinal,floor);
	glEnd();

	/* draw axis*/
	glLineWidth(ascene->axis.width);
	glBegin(GL_LINES);
	if(ascene->isAxis == 1){
		double origin[4] = {0,0,0,1};
		double axisX[4] = {ascene->axis.length,0,0,1};
		double axisY[4] = {0,ascene->axis.length,0,1};
		double axisZ[4] = {0,0,ascene->axis.length,1};
		
		matrixApply(matrixFinal,origin);
		matrixApply(matrixFinal,axisX);
		matrixApply(matrixFinal,axisY);
		matrixApply(matrixFinal,axisZ);

		glColor3f(1,0,0);
		glVertex2d(origin[0]/origin[3],origin[1]/origin[3]);
		glVertex2d(axisX[0]/axisX[3],axisX[1]/axisX[3]);
		glColor3f(0,1,0);
		glVertex2d(origin[0]/origin[3],origin[1]/origin[3]);
		glVertex2d(axisY[0]/axisY[3],axisY[1]/axisY[3]);
		glColor3f(0,0,1);
		glVertex2d(origin[0]/origin[3],origin[1]/origin[3]);
		glVertex2d(axisZ[0]/axisZ[3],axisZ[1]/axisZ[3]);
	}
	glEnd();

	/* implement objects*/
	int nT = 0;
	int nR = 0;
	int nS = 0;
	int nM = 0;
	for(i = 0; i < ascene->nidentities; i++){
		matrixInitial(mTransform);
		for(j = 0; j < ascene->identities[i].inStr_num; j++){
			if(ascene->identities[i].instr[j] == TRANSLATE_KEY){
					matrixInitial(mTranslate);
					mTranslate[0][3] = ascene->translate[nT].xyz[0];
					mTranslate[1][3] = ascene->translate[nT].xyz[1];
					mTranslate[2][3] = ascene->translate[nT].xyz[2];
					matrixMultiply(mTranslate,mTransform,0);
					nT++;
			}
			else if(ascene->identities[i].instr[j] == ROTATE_KEY){
					double axis[3];
					axis[0] = ascene->rotate[nR].xyz[0];
					axis[1] = ascene->rotate[nR].xyz[1];
					axis[2] = ascene->rotate[nR].xyz[2];
					double Pi = 3.141592653;
					double radian = (ascene->rotate[nR].angle/(double)180) * Pi;
					rotateMatrix(axis,mRotate,mTransform,radian);
					nR++;
					
			}
			else if(ascene->identities[i].instr[j] == SCALE_KEY){
					matrixInitial(mScale);
					mScale[0][0] = ascene->scale[nS].xyz[0];
					mScale[1][1] = ascene->scale[nS].xyz[1];
					mScale[2][2] = ascene->scale[nS].xyz[2];
					matrixMultiply(mScale,mTransform,0);
					nS++;
			}
			else if(ascene->identities[i].instr[j] == MESH_KEY){			
					double tM[4][4];
					matrixInitial(tM);
					matrixMultiply(mTransform,tM,0);
					matrixMultiply(matrixFinal,tM,0);
					int k,l,d;

					/*apply transform matrix to all vertices in world coordinates*/
					COLOR_VERTEX colorVertices[ascene->mesh[nM].nvertices];
					for(k = 0; k < ascene->mesh[nM].nvertices; k++){
						colorVertices[k] = ascene->mesh[nM].vertices[k];
						matrixApply(mTransform,colorVertices[k].xyzw);
					}

					//flat shading
					if(ascene->mesh[nM].shading == 0){
						for(k = 0; k < ascene->mesh[nM].npolygons; k++){				
								COLOR_VERTEX vertices[3] = {colorVertices[ascene->mesh[nM].polygons[k].num[0]],
																						colorVertices[ascene->mesh[nM].polygons[k].num[1]],
																						colorVertices[ascene->mesh[nM].polygons[k].num[2]]};
								
								double normal[3]; 
								triangleNormal(vertices[0].xyzw,vertices[1].xyzw,vertices[2].xyzw,normal);
								double center[3];
								center[0] = (vertices[0].xyzw[0] + vertices[1].xyzw[0] + vertices[2].xyzw[0])/(double)3;
								center[1] = (vertices[0].xyzw[1] + vertices[1].xyzw[1] + vertices[2].xyzw[1])/(double)3;
								center[2] = (vertices[0].xyzw[2] + vertices[1].xyzw[2] + vertices[2].xyzw[2])/(double)3;
										Illumination(normal,ascene->mesh[nM].diffuse,ascene->mesh[nM].specular,center);	
	int i;
								for(i = 0; i < 3; i++){			matrixApply(matrixFinal,vertices[i].xyzw);
								}				
								toScreen(vertices[0].xyzw,vertices[1].xyzw,vertices[2].xyzw);								triRendering(vertices[0].xyzw,vertices[1].xyzw,vertices[2].xyzw,0,0,0,0,0,0,mInverse);

						}
					}

					//phong shading
					else if (ascene->mesh[nM].shading == 2){
						double vertex_normal[ascene->mesh[nM].nvertices][3];
						for(k = 0; k < ascene->mesh[nM].nvertices; k++){
						double composeNormal[3] = {0,0,0};
							for(l = 0; l < ascene->mesh[nM].npolygons; l++){
								for(d = 0; d < ascene->mesh[nM].polygons[l].nvertices; d++){
									if(ascene->mesh[nM].polygons[l].num[d] == k){
									COLOR_VERTEX vertices[3] = {colorVertices[ascene->mesh[nM].polygons[l].num[0]],
																								colorVertices[ascene->mesh[nM].polygons[l].num[1]],
																								colorVertices[ascene->mesh[nM].polygons[l].num[2]]};
									double normal[3];
										triangleNormal(vertices[0].xyzw,vertices[1].xyzw,vertices[2].xyzw,normal);
													composeNormal[0] += normal[0];
										composeNormal[1] += normal[1];
										composeNormal[2] += normal[2];
									}
								}
							}										vecUnitization(composeNormal,composeNormal);
						int i=0;			
						for(i = 0; i < 3; i++){
							colorVertices[k].rgba[i] = composeNormal[i];
							}
						}
	setBuffer(colorVertices,matrixFinal,nM,ascene->mesh[nM].diffuse,ascene->mesh[nM].specular,2,mInverse);				
					}
					//smooth shading
					else{
					   for(k = 0; k < ascene->mesh[nM].nvertices; k++){
						double composeNormal[3] = {0,0,0};
						for(l = 0; l < ascene->mesh[nM].npolygons; l++){
						   for(d = 0; d < ascene->mesh[nM].polygons[l].nvertices; d++){
																		       if(ascene->mesh[nM].polygons[l].num[d] == k){
							     COLOR_VERTEX vertices[3] = {colorVertices[ascene->mesh[nM].polygons[l].num[0]],
																								colorVertices[ascene->mesh[nM].polygons[l].num[1]],
																								colorVertices[ascene->mesh[nM].polygons[l].num[2]]};
							     double normal[3];
					triangleNormal(vertices[0].xyzw,vertices[1].xyzw,vertices[2].xyzw,normal);	
														composeNormal[0] += normal[0];								composeNormal[1] += normal[1];								composeNormal[2] += normal[2];
							  }
						      }
						  }
	vecUnitization(composeNormal,composeNormal);
	Illumination(composeNormal,ascene->mesh[nM].diffuse,ascene->mesh[nM].specular,colorVertices[k].xyzw);

	colorVertices[k].rgba[0] = illuColor[0];
	colorVertices[k].rgba[1] = illuColor[1];
	colorVertices[k].rgba[2] = illuColor[2];
						}	
	setBuffer(colorVertices,matrixFinal,nM,0,0,1,mInverse);		
					}
					glLineWidth(ascene->mesh[nM].width);
					glBegin(GL_POINTS);
					for(k = 0; k < ascene->screen_h; k++){
						for(l = 0; l < ascene->screen_w; l++){
						   	if(buffer[k*(ascene->screen_w)+l].z < 9999){										glColor3f(buffer[k*(ascene->screen_w) + l].rgba[0],buffer[k*(ascene->screen_w) + l].rgba[1],buffer[k*(ascene->screen_w) + l].rgba[2]);										glVertex2i(l,k);
							}
						} 					
					}
					glEnd();
					nM++;

			}		
		}
	}


  for(i = 0; i < ascene->nlines; i++){
	ascene->lines[i].vertices[0].xyzw[3] = 1;
	ascene->lines[i].vertices[1].xyzw[3] = 1;
	COLOR_VERTEX vertices[2];
	vertices[0] = ascene->lines[i].vertices[0];
	vertices[1] = ascene->lines[i].vertices[1];
	matrixApply(matrixFinal,vertices[0].xyzw);
	matrixApply(matrixFinal,vertices[1].xyzw);

	glLineWidth(ascene->lines[i].width);
	glBegin(GL_LINES);
	glColor3f(vertices[0].rgba[0],vertices[0].rgba[1],vertices[0].rgba[2]);
	glVertex2d(vertices[0].xyzw[0]/vertices[0].xyzw[3],vertices[0].xyzw[1]/vertices[0].xyzw[3]);
	glColor3f(vertices[1].rgba[0],vertices[1].rgba[1],vertices[1].rgba[2]);
	glVertex2d(vertices[1].xyzw[0]/vertices[1].xyzw[3],vertices[1].xyzw[1]/vertices[1].xyzw[3]);
	glEnd();
	}

  free(buffer);
  glFlush ();
  glutSwapBuffers();
  return 0;
}
Exemplo n.º 3
0
void triRendering(double v0[],double v1[],double v2[],float c0[],float c1[],float c2[],double d[],double s[],int shading,double mInverse[][4])
{
	/*triangle constant*/
	int xmax,xmin,ymax,ymin;
	double l0_12,l1_02,l2_01;
	double x_incr_alpha,x_incr_beta,x_incr_gamma;
	double y_incr_alpha,y_incr_beta,y_incr_gamma;
	double alpha0,beta0,gamma0,flag_12,flag_02,flag_01;

	xmin=min(min(v0[0],v1[0]),v2[0]);
  	xmax=max(max(v0[0],v1[0]),v2[0]);
  	ymin=min(min(v0[1],v1[1]),v2[1]);
  	ymax=max(max(v0[1],v1[1]),v2[1]);
	
	/*const*/
	l0_12 = decision(v1,v2,v0[0],v0[1]);
	l1_02 = decision(v0,v2,v1[0],v1[1]);
	l2_01 = decision(v0,v1,v2[0],v2[1]);

	x_incr_alpha = (v1[1]-v2[1])/l0_12;
	x_incr_beta = (v0[1]-v2[1])/l1_02;
	x_incr_gamma = (v0[1]-v1[1])/l2_01;

	y_incr_alpha = (v2[0]-v1[0])/l0_12;
	y_incr_beta = (v2[0]-v0[0])/l1_02;
	y_incr_gamma = (v1[0]-v0[0])/l2_01;

	alpha0 = decision(v1,v2,xmin,ymin)/l0_12;
	beta0 = decision(v0,v2,xmin,ymin)/l1_02;
	gamma0 = decision(v0,v1,xmin,ymin)/l2_01;

	/* (-1,-1) or (-2,-1) */
	flag_12 = decision(v1,v2,-1,-1);
	flag_02 = decision(v0,v2,-1,-1);
	flag_01 = decision(v0,v1,-1,-1);

	if(flag_12 == 0)
			flag_12 = decision(v1,v2,-2,-1);
	if(flag_02 == 0)
			flag_02 = decision(v0,v2,-2,-1);
	if(flag_01 == 0)
			flag_01 = decision(v0,v1,-2,-1);

	int i,x,y;
	double alpha,beta,gamma;	 
	for (y = ymin; y <= ymax; y++){
		alpha = alpha0;
		beta = beta0;
		gamma = gamma0;
		for (x = xmin; x <= xmax; x++){
			if(alpha >= 0 && beta >= 0 && gamma >= 0){
				if( (alpha > 0 || l0_12 * flag_12 >0) && (beta > 0 || l1_02 * flag_02 >0) && (gamma > 0 || l2_01 * flag_01 > 0)){				
					double z = alpha * v0[2] + beta * v1[2] + gamma * v2[2];
					if(z < buffer[y*thescene.screen_w+x].z){
						if(shading == 0){
							for(i = 0; i < 3; i++){
								buffer[y*thescene.screen_w+x].rgba[i] = illuColor[i];

							}			
				              buffer[y*thescene.screen_w+x].z = z;
						}
						else if(shading == 1){
							for(i = 0; i < 3; i++){
								buffer[y*thescene.screen_w+x].rgba[i] = alpha * c0[i] + beta * c1[i] + gamma * c2[i];
							}
						 buffer[y*thescene.screen_w+x].z = z;
						}
						else{	
							double normal[3];
							for(i = 0; i < 3; i++){
								normal[i] = alpha * c0[i] + beta * c1[i] + gamma * c2[i];
							}
							vecUnitization(normal,normal);

							double w = alpha * v0[3] + beta * v1[3] + gamma * v2[3];
							double p[4] = {x*w,y*w,z,w};
							
							matrixApply(mInverse,p);
							Illumination(normal,d,s,p);
							for(i = 0; i < 3; i++){
								buffer[y*thescene.screen_w+x].rgba[i] = illuColor[i];

							}		
							buffer[y*thescene.screen_w+x].z = z;
						}
					}
				}	
			}
			alpha += x_incr_alpha;
			beta += x_incr_beta;
			gamma += x_incr_gamma;
			
		}
		alpha0 += y_incr_alpha;
		beta0 += y_incr_beta;
		gamma0 += y_incr_gamma;
	}
}