Пример #1
0
void Project::CreateDepthMap(GzDisplay* display, unsigned char* depthmap)
{
	int maxZ = 0;
	int minZ = INT_MAX;
	for (int y = 0; y < m_nHeight; ++y)
	{
		for (int x = 0; x < m_nWidth; ++x)
		{
			GzIntensity r,g,b,a;
			GzDepth z;
			GzGetDisplay(display, x, y, &r, &g, &b, &a, &z);
			maxZ = max(z, maxZ);
			minZ = min(z, minZ);
		}
	}

	for (int y = 0; y < m_nHeight; ++y)
	{
		for (int x = 0; x < m_nWidth; ++x)
		{
			GzIntensity r,g,b,a;
			GzDepth z;
			GzGetDisplay(display, x, y, &r, &g, &b, &a, &z);
			int framebufferIndex = 3 * x + (y * m_nWidth * 3);
			int zval = (int) (((float) (z - minZ) / ((float) (maxZ - minZ))) * 255.0);
			depthmap[framebufferIndex] = zval;
			depthmap[framebufferIndex + 1] = zval;
			depthmap[framebufferIndex + 2] = zval;
		}
	}
}
int render(BackBuffer* bf)
{
	BitBlt(bf->back_dc, 0, 0, bf->width, bf->height, NULL, 0, 0, BLACKNESS );
	
	//Render teapot to refraction texture
	render_teapot_refraction(renderer);
	GzCopyDisplay(refraction_display, renderer->display);

	//Render the model itself.
	//render_teapot(renderer);			//skip rendering the teapot to save some time
	render_water_plane(renderer);

	//blend

	for(int i=0; i<refraction_display->xres; i++)
	{
		for(int j=0; j<refraction_display->yres; j++)
		{
			GzIntensity r,g,b,a;
			GzDepth z;
			GzGetDisplay(refraction_display, i, j, &r, &g, &b, &a, &z);
			if(a > 0)
			{
				GzIntensity r1,g1,b1,a1;
				GzDepth z1;
				GzGetDisplay(renderer->display, i, j, &r1, &g1, &b1, &a1, &z1);
				//blend with 0.6, 0.4
				float blend_des = 0.6f, blend_src = 0.4f;
				r = r1*blend_des+ r*blend_src;
				g = g1*blend_des + g*blend_src;
				b = b1*blend_des + b*blend_src;
				GzPutDisplay(renderer->display, i,j,r,g,b,a,z);
			}
		}
	}

	flush_display(renderer->display, bf);

	return 0;
}
Пример #3
0
void line(float x0, float y0, float x1, float y1, GzRender *render)
{
	float dx = x1 - x0;
	float dy = y1 - y0;
	float m = dy/dx;
	float x = x0, y = y0;

	for(x = x0; x <= x1; x++)
	{
		GzIntensity red, green, blue, alpha; 
		GzDepth oldZ;
		GzGetDisplay(render->display,x,y,&red,&green,&blue,&alpha,&oldZ);
		GzPutDisplay(render->display,x,y,ctoi(render->flatcolor[0]),ctoi(render->flatcolor[1]),ctoi(render->flatcolor[2]),alpha,oldZ);
		y = y + m;
	}
}
static void flush_display(GzDisplay* display, BackBuffer* bf)
{
	BITMAP bitmap;
	GetObject(bf->buffer_bmp, sizeof(BITMAP), &bitmap);
	char* buffer = new char[bitmap.bmWidthBytes*bitmap.bmHeight];

	BITMAPINFO binfo;
	ZeroMemory(&binfo,sizeof(BITMAPINFO)); 
	binfo.bmiHeader.biBitCount=bitmap.bmBitsPixel;  
	binfo.bmiHeader.biCompression=0; 
	binfo.bmiHeader.biHeight=bitmap.bmHeight; 
	binfo.bmiHeader.biPlanes=1; 
	binfo.bmiHeader.biSizeImage=0; 
	binfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); 
	binfo.bmiHeader.biWidth=bitmap.bmWidth;

	GetDIBits(bf->back_dc,bf->buffer_bmp, 0, bitmap.bmHeight, buffer, &binfo, DIB_RGB_COLORS);
	
	int stride = (binfo.bmiHeader.biWidth * (binfo.bmiHeader.biBitCount / 8) + 3) & ~3;
	for(int i=0; i<display->yres; i++)
	{
		int row_base = i*stride;
		for(int j = 0; j<display->xres; j++)
		{
			int col_base = j*(binfo.bmiHeader.biBitCount / 8);
			GzIntensity r,g,b,a;
			GzDepth z;
			GzGetDisplay(display, j, display->yres-1 - i, &r, &g, &b, &a, &z);
			buffer[row_base + col_base ] = GzIntensityToChar(b);
			buffer[row_base + col_base + 1] = GzIntensityToChar(g);
			buffer[row_base +col_base + 2] = GzIntensityToChar(r);
		}
	}

	SetDIBits(bf->back_dc, bf->buffer_bmp, 0, bitmap.bmHeight, buffer, &binfo, DIB_RGB_COLORS);
}
Пример #5
0
//------------------------------------------------------------------------------
int GzPutTriangle(GzRender *render, int numParts, GzToken *nameList, GzPointer *valueList) {
    /* numParts : how many names and values */

    // Do some sanity checking    
    if(NULL == render || NULL == nameList || NULL == valueList || numParts != 3)
    {
        return GZ_FAILURE;
    } 
    
        
    Matrix *Xsm = render->xStack.leftMulMatricesOnStack();
    if (Xsm == NULL)
    {
        fprintf(stderr, "Got NULL from stack in GzPutTriangle.\n");
    } 
    
    
    
    
    GzCoord *c_old;
    GzCoord *n;
    GzColor triEdgeColors[3];
    GzTextureIndex *triTextures;
    
    for (int i = 0; i < numParts; i++)
    {
        int name = nameList[i];
        switch(name)
        {
            case GZ_POSITION:
            {
                // Get ready to read coordinates
                void *l1 = valueList;
                GzCoord **l2 = static_cast<GzCoord **> (l1);
                c_old = static_cast<GzCoord *> (l2[i]);
                
                break;
            }
            
            case GZ_NORMAL:
            {
                void *l1 = valueList;
                GzCoord **l2 = static_cast<GzCoord **> (l1);
                
                n = static_cast<GzCoord *> (l2[i]);
                
                
                if (render->interp_mode == GZ_COLOR) 
                {
                    for (int k = 0; k < 3; k++)
                        calc_color(render, n[k], triEdgeColors[k], (render->tex_fun == false));

                }

                break;
            }
            
            case GZ_TEXTURE_INDEX:
            {
                void *l1 = valueList;
                GzTextureIndex **l2 = static_cast<GzTextureIndex**> (l1);
                triTextures = l2[i];             
                
                break;
            }
            
            default:
                return GZ_FAILURE;            
        }// end of switch statement
    }//end of for loop
    
    
    
   

    GzCoord c[3];
    // Transform triangle coordinates into screen coordinates
    for(int i = 0; i < 3 ; i++)
    {
        float array[4] = {c_old[i][0], c_old[i][1], c_old[i][2], 1};
        float rMulResult[4] ={0, 0, 0, 0};
        Xsm->rightMultiply(array, 4, rMulResult);
        c[i][X] = rMulResult[0] + render->aa_delta_x;
        c[i][Y] = rMulResult[1] + render->aa_delta_y;
        c[i][Z] = rMulResult[2];           
    }

    // Lets see if all 3 triangle coordinates are viewable or not.
    if(isBehindViewPlane(render, c) || isClipped(render, c))
        return GZ_FAILURE;   

    // Find bounding box
    int x_min = floor(findMin(c, 0, 3));
    int x_max = ceil (findMax(c, 0, 3));
    int y_min = floor(findMin(c, 1, 3));
    int y_max = ceil (findMax(c, 1, 3));


    // Iterate over every pixel in the bounding box
    for(int j = y_min; j <= y_max; j++)        
        for(int i = x_min; i <= x_max; i++)
        {
            // Calculate Barycentric coordinates
            GzCoord p = {float(i), float(j), 0};
            float alpha = f(c[1], c[2], p) / f(c[1], c[2], c[0]);
            float beta  = f(c[2], c[0], p) / f(c[2], c[0], c[1]);
            float gamma = f(c[0], c[1], p) / f(c[0], c[1], c[2]);

            // Litmus Test: Is pixel (i,j) inside triangle?
            if ( alpha > 0 && beta > 0 && gamma > 0)                
            {
                //interpolate z value
                float newZ = alpha*(c[0][2]) + beta*(c[1][2]) + gamma*(c[2][2]);


                // Get current Z value for this specific pixel (i,j)
                GzIntensity dummy;
                GzDepth oldZ;
                GzGetDisplay(render->display, i, j, &dummy, &dummy, &dummy, &dummy, &oldZ);


                // Check will this pixel be displayed or not
                if(newZ < oldZ)
                {

                    GzColor interpColor = {0, 0, 0};                    
                    GzColor color = {1.0f, 1.0f, 1.0f}; // color coming from texture
                    if(render->tex_fun != false)
                        calcTexture(render, triTextures, c, newZ, alpha, beta, gamma, color);


                    
                    
                    
                    if(render->interp_mode == GZ_NORMALS) // Phong Shading
                    {
                        GzCoord interpN = {0,0,0};
                        for (int k = 0; k < 3; k++)
                            interpN[k] = alpha*n[0][k] + beta*n[1][k] + gamma*n[2][k];
                        
                        if(render->tex_fun != false)
                        {
                                memcpy(render->Ka, color, sizeof (GzColor));
                                memcpy(render->Kd, color, sizeof (GzColor));
                        }
                
                        

                          
                        calc_color(render, interpN, interpColor, true);
                        
                        GzPutDisplay(render->display, i, j, ctoi(interpColor[X]), ctoi(interpColor[Y]), ctoi(interpColor[Z]), 1, newZ);
                        
                    }
                    else if(render->interp_mode == GZ_COLOR) // Gouraud Shading
                    {
                        float r = alpha * triEdgeColors[0][X] + beta * triEdgeColors[1][X] + gamma * triEdgeColors[2][X];
                        float g = alpha * triEdgeColors[0][Y] + beta * triEdgeColors[1][Y] + gamma * triEdgeColors[2][Y];
                        float b = alpha * triEdgeColors[0][Z] + beta * triEdgeColors[1][Z] + gamma * triEdgeColors[2][Z];
                        
                        // Multiply by Kt which is in color due to earlier texture calculation
                        r *= color[RED];
                        g *= color[GREEN];
                        b *= color[BLUE];



                        GzPutDisplay(render->display, i, j, ctoi(r), ctoi(g), ctoi(b), 1, newZ);
                        
                    }
                    
                    
                    // FLAT Shading 
                                            
                        //GzPutDisplay(render->display, i, j, ctoi(render->flatcolor[0]), 
                        //ctoi(render->flatcolor[1]), ctoi(render->flatcolor[2]), 1, newZ);                   

                }


            }// end of litmus test if
        }   
    
    return GZ_SUCCESS;
}
Пример #6
0
int GzPutTriangle(GzRender	*render, int numParts, GzToken *nameList, GzPointer	*valueList)
/* numParts : how many names and values */
{
/*  
- pass in a triangle description with tokens and values corresponding to 
      GZ_POSITION:3 vert positions in model space 
- Xform positions of verts using matrix on top of stack 
- Clip - just discard any triangle with any vert(s) behind view plane 
       - optional: test for triangles with all three verts off-screen (trivial frustum cull)
- invoke triangle rasterizer  
*/ 
	if ((NULL == render) || (NULL == nameList) || (NULL == valueList))
	{
		return GZ_FAILURE;
	}
	for (int nCnt = 0; nCnt < numParts; nCnt++)
	{
		if (nameList[nCnt] == GZ_POSITION)
		{
			GzCoord* acGzCoord;
			acGzCoord = (GzCoord*)(valueList[nCnt]);
			GzMatrix topMat;
			int top = render->matlevel;
			memcpy(topMat, render->Ximage[top], sizeof(GzMatrix));
			float aCoordMat[4][4] = { { acGzCoord[0][0], acGzCoord[1][0], acGzCoord[2][0], 0 }, { acGzCoord[0][1], acGzCoord[1][1], acGzCoord[2][1], 0 }, { acGzCoord[0][2], acGzCoord[1][2], acGzCoord[2][2], 0 }, { 1, 1, 1, 0 } };
			float aCoordMatProduct[4][4];
			MatrixProduct(topMat, aCoordMat, aCoordMatProduct);
			if ((aCoordMatProduct[3][0] == 0) || (aCoordMatProduct[3][1] == 0) || (aCoordMatProduct[3][2] == 0))
			{
				continue;
			}
#if 1
			GzCoord asGzCoordX = { aCoordMatProduct[0][0] / aCoordMatProduct[3][0], aCoordMatProduct[0][1] / aCoordMatProduct[3][1], aCoordMatProduct[0][2] / aCoordMatProduct[3][2] };
			GzCoord asGzCoordY = { aCoordMatProduct[1][0] / aCoordMatProduct[3][0], aCoordMatProduct[1][1] / aCoordMatProduct[3][1], aCoordMatProduct[1][2] / aCoordMatProduct[3][2] };
			GzCoord asGzCoordZ = { aCoordMatProduct[2][0] / aCoordMatProduct[3][0], aCoordMatProduct[2][1] / aCoordMatProduct[3][1], aCoordMatProduct[2][2] / aCoordMatProduct[3][2] };
			// clipping part
			if ((asGzCoordX[X] < 0 || asGzCoordX[X] > (render->display->xres)) && (asGzCoordX[Y] < 0 || asGzCoordX[Y] > (render->display->xres)) && (asGzCoordX[Z] < 0 || asGzCoordX[Z] > (render->display->xres)))
			{
				return GZ_FAILURE;
			}

			if ((asGzCoordY[X] < 0 || asGzCoordY[X] > (render->display->yres)) && (asGzCoordY[Y] < 0 || asGzCoordY[Y] > (render->display->yres)) && (asGzCoordY[Z] < 0 || asGzCoordY[Z] > (render->display->yres)))
			{
				return GZ_FAILURE;
			}

			if (asGzCoordZ[X] < 0 && asGzCoordZ[Y] < 0 && asGzCoordZ[Z] < 0)
			{
				return GZ_FAILURE;
			}
#else 

			GzCoord asGzCoordX = { acGzCoord[0][0], acGzCoord[1][0], acGzCoord[2][0] };
			GzCoord asGzCoordY = { acGzCoord[0][1], acGzCoord[1][1], acGzCoord[2][1] };
			GzCoord asGzCoordZ = { acGzCoord[0][2], acGzCoord[1][2], acGzCoord[2][2] };
#endif
			//Sort the matrix according to Y
			for (int anSortYCnt = 1; anSortYCnt < 3; anSortYCnt++)
			{
				if (asGzCoordY[anSortYCnt - 1] > asGzCoordY[anSortYCnt])
				{
					float afSortTemmp;
					afSortTemmp = asGzCoordX[anSortYCnt - 1];
					asGzCoordX[anSortYCnt - 1] = asGzCoordX[anSortYCnt];
					asGzCoordX[anSortYCnt] = afSortTemmp;
					afSortTemmp = asGzCoordY[anSortYCnt - 1];
					asGzCoordY[anSortYCnt - 1] = asGzCoordY[anSortYCnt];
					asGzCoordY[anSortYCnt] = afSortTemmp;
					afSortTemmp = asGzCoordZ[anSortYCnt - 1];
					asGzCoordZ[anSortYCnt - 1] = asGzCoordZ[anSortYCnt];
					asGzCoordZ[anSortYCnt] = afSortTemmp;
				}
			}
			float afGzCoordY_Min = asGzCoordY[0];			// find min y 
			float afGzCoordY_Max = asGzCoordY[2];			// find max y
			float tmp;
			for (int anSortYCnt = 1; anSortYCnt < 3; anSortYCnt++)
			{
				if ((asGzCoordY[anSortYCnt - 1] == asGzCoordY[anSortYCnt]) && (asGzCoordX[anSortYCnt - 1] > asGzCoordX[anSortYCnt]))
				{
					float afSortTemmp;
					afSortTemmp = asGzCoordX[anSortYCnt - 1];
					asGzCoordX[anSortYCnt - 1] = asGzCoordX[anSortYCnt];
					asGzCoordX[anSortYCnt] = afSortTemmp;
					afSortTemmp = asGzCoordY[anSortYCnt - 1];
					asGzCoordY[anSortYCnt - 1] = asGzCoordY[anSortYCnt];
					asGzCoordY[anSortYCnt] = afSortTemmp;
					afSortTemmp = asGzCoordZ[anSortYCnt - 1];
					asGzCoordZ[anSortYCnt - 1] = asGzCoordZ[anSortYCnt];
					asGzCoordZ[anSortYCnt] = afSortTemmp;
				}
			}
			float afCoefA = asGzCoordY[2] - asGzCoordY[0];
			float afCoefB = asGzCoordX[0] - asGzCoordX[2];
			float afCoefC = -afCoefB*asGzCoordY[0] - afCoefA * asGzCoordX[0];
			float acTestX = -(afCoefB*asGzCoordY[1] + afCoefC) / afCoefA;
			if (acTestX < asGzCoordX[1])
			{
				tmp = asGzCoordY[2];
				asGzCoordY[2] = asGzCoordY[1];
				asGzCoordY[1] = tmp;
				tmp = asGzCoordX[2];
				asGzCoordX[2] = asGzCoordX[1];
				asGzCoordX[1] = tmp;
				tmp = asGzCoordZ[2];
				asGzCoordZ[2] = asGzCoordZ[1];
				asGzCoordZ[1] = tmp;
			}
			//find the max and min for X and Y
			float afMaxX, afMinX, afMaxY, afMinY;
			afMaxX = asGzCoordX[0];
			afMinX = asGzCoordX[0];
			afMaxY = asGzCoordY[0];
			afMinY = asGzCoordY[0];
			for (int anCntMinMaxCnt = 1; anCntMinMaxCnt < 3; anCntMinMaxCnt++)
			{
				if (afMaxX <= asGzCoordX[anCntMinMaxCnt])
				{
					afMaxX = asGzCoordX[anCntMinMaxCnt];
				}
				if (afMinX >= asGzCoordX[anCntMinMaxCnt])
				{
					afMinX = asGzCoordX[anCntMinMaxCnt];
				}
				if (afMaxY <= asGzCoordY[anCntMinMaxCnt])
				{
					afMaxY = asGzCoordY[anCntMinMaxCnt];
				}
				if (afMinY >= asGzCoordY[anCntMinMaxCnt])
				{
					afMinY = asGzCoordY[anCntMinMaxCnt];
				}
			}
			//set the boundary of x and y
			if (afMinX < 0)
			{
				afMinX = 0;
			}
			else if (afMinX > 255)
			{
				afMinX = 255;
			}
			if (afMaxX < 0){
				afMaxX = 0;
			}
			else if (afMaxX > 255)
			{
				afMaxX = 255;
			}
			if (afMinY < 0){
				afMinY = 0;
			}
			else if (afMinY > 255)
			{
				afMinY = 255;
			}
			if (afMaxY < 0){
				afMaxY = 0;
			}
			else if (afMaxY > 255)
			{
				afMaxY = 255;
			}
			//set the variants of vertex Ax + By + C = 0
			float afCoefA1, afCoefA2, afCoefA3, afCoefB1, afCoefB2, afCoefB3, afCoefC1, afCoefC2, afCoefC3;
			float AfDiff1, AfDiff2, AfDiff3;
			float afVar1, afVar2, afVar3, afVar4;
			GzIntensity asR, asG, asB, asAlpha;
			GzDepth anZ;
			int anInterZ;
			afCoefA1 = asGzCoordY[1] - asGzCoordY[0];
			afCoefA2 = asGzCoordY[2] - asGzCoordY[1];
			afCoefA3 = asGzCoordY[0] - asGzCoordY[2];
			afCoefB1 = -(asGzCoordX[1] - asGzCoordX[0]);
			afCoefB2 = -(asGzCoordX[2] - asGzCoordX[1]);
			afCoefB3 = -(asGzCoordX[0] - asGzCoordX[2]);
			afCoefC1 = ((-(afCoefB1)*asGzCoordY[1]) - (afCoefA1 * asGzCoordX[1]));
			afCoefC2 = ((-(afCoefB2)*asGzCoordY[2]) - (afCoefA2 * asGzCoordX[2]));
			afCoefC3 = ((-(afCoefB3)*asGzCoordY[0]) - (afCoefA3 * asGzCoordX[0]));
			afVar1 = (((asGzCoordY[1] - asGzCoordY[0])*(asGzCoordZ[2] - asGzCoordZ[0])) - ((asGzCoordY[2] - asGzCoordY[0])*(asGzCoordZ[1] - asGzCoordZ[0])));
			afVar2 = (((asGzCoordX[2] - asGzCoordX[0])*(asGzCoordZ[1] - asGzCoordZ[0])) - ((asGzCoordX[1] - asGzCoordX[0])*(asGzCoordZ[2] - asGzCoordZ[0])));
			afVar3 = (((asGzCoordX[1] - asGzCoordX[0])*(asGzCoordY[2] - asGzCoordY[0])) - ((asGzCoordX[2] - asGzCoordX[0])*(asGzCoordY[1] - asGzCoordY[0])));
			afVar4 = -((asGzCoordY[0] * (afVar2)) + (asGzCoordX[0] * (afVar1)) + (asGzCoordZ[0] * (afVar3)));
			for (int anCntRangeX = int(afMinX); (float)anCntRangeX < (afMaxX); anCntRangeX++){
				for (int anCntRangeY = int(afMinY); (float)anCntRangeY < (afMaxY); anCntRangeY++){
					AfDiff1 = (afCoefA1*anCntRangeX) + (afCoefB1*anCntRangeY) + afCoefC1;
					AfDiff2 = (afCoefA2*anCntRangeX) + (afCoefB2*anCntRangeY) + afCoefC2;
					AfDiff3 = (afCoefA3*anCntRangeX) + (afCoefB3*anCntRangeY) + afCoefC3;
					anInterZ = -(afVar1*anCntRangeX + afVar2*anCntRangeY + afVar4) / afVar3;
					if (!(AfDiff1 < 0 || AfDiff2 < 0 || AfDiff3 < 0)){
						asR = 0;
						asG = 0;
						asB = 0;
						asAlpha = 0;
						anZ = 0;
						if (GZ_FAILURE == GzGetDisplay(render->display, anCntRangeX, anCntRangeY, &asR, &asG, &asB, &asAlpha, &anZ))
						{
							return GZ_FAILURE;
						}
						if (anZ == 0 || anInterZ < anZ)
						{
							if (GZ_FAILURE == GzPutDisplay(render->display, anCntRangeX, anCntRangeY, ctoi(render->flatcolor[RED]), ctoi(render->flatcolor[GREEN]), ctoi(render->flatcolor[BLUE]), asAlpha, anInterZ))
							{
								return GZ_FAILURE;
							}
						}
					}
				}
			}
		}
		else if (nameList[nCnt] == GZ_NULL_TOKEN)
		{
			continue;
		}
	}
	return GZ_SUCCESS;
}
Пример #7
0
void GzRasterize(GzRender *render,GzCoord *triVertex)
{		

	//AfxMessageBox("Rasterize");				
		
		float x1 = triVertex[0][0];
		float x2 = triVertex[1][0];
		float x3 = triVertex[2][0];
		float y1 = triVertex[0][1];
		float y2 = triVertex[1][1];
		float y3 = triVertex[2][1];
		float z1 = triVertex[0][2];
		float z2 = triVertex[1][2];
		float z3 = triVertex[2][2];
		
		float xMin,yMin,xMax,yMax;
		float a1,b1,c1,a2,b2,c2,a3,b3,c3;
		float aX,bY,cZ,d;
		int xStart,yStart,xEnd,yEnd;
		
		/*	xMin, xMax, yMin, yMax are calculated for fixing the bounding box triangle	*/
		xMin = min(x1,min(x2,x3));
		xMax = max(x1,max(x2,x3));

		yMin = min(y1,min(y2,y3));
		yMax = max(y1,max(y2,y3));

		/*	Computing Line Equation coefficients */
		
		// First Edge (x1,y1) -> (x2,y2)
		a1 = y1 - y2;
		b1 = x2 - x1;
		c1 = ((x1 - x2) * y2) - ((y1 - y2) * x2);

		//Second Edge (x2,y2) -> (x3,y3)
		a2 = y2 - y3;
		b2 = x3 - x2;
		c2 = ((x2 - x3) * y3) - ((y2 - y3) * x3);

		//Third Edge (x3,y3) -> (x1,y1)
		a3 = y3 - y1;
		b3 = x1 - x3;
		c3 = ((x3 - x1) * y1) - ((y3 - y1) * x1);

		/*	Finding Crossproduct of 2 edges to obtain the plane equation for the triangle	*/
	
		aX = (((y1 - y2) * (z2 - z3)) - ((z1 - z2) * (y2 - y3)));
		bY = -(((x1 - x2) * (z2 - z3)) - ((z1 - z2) * (x2 - x3)));
		cZ = (((x1 - x2) * (y2 - y3)) - ((y1 - y2) * (x2 - x3)));
		d = -(aX * x1 + bY * y1 + cZ * z1);
				
		xStart = max(int(ceil((xMin))),0);
		yStart = max(int(ceil((yMin))),0);
	
		xEnd = min(int(floor((xMax))),render->display->xres);
		yEnd = min(int(floor((yMax))),render->display->yres);
				
		if(WIREFRAME)
		{
			line(x1,y1,x2,y2,render);
			line(x2,y2,x3,y3,render);
			line(x3,y3,x1,y1,render);
		}
		else{
		for(int y  = yStart; y <= yEnd; y++)
		{
			for(int x = xStart; x <= xEnd; x++)
			{				
				//check if x,y lies outside the line. If yes, skip triangle and move to next
				if (a1 * x + b1 * y + c1 < 0)
				{
						continue;
				}
				if(a2 * x + b2 * y + c2 < 0)
				{
						continue;
				}
				if(a3 * x + b3 * y + c3 < 0)
				{
						continue; 
				}													
					GzDepth newZ = (GzDepth)(-(aX * x + bY * y + d) / cZ);

					if(newZ > 0)
					{
						GzIntensity red,green,blue,alpha;
						GzDepth oldZ;				
					
						GzGetDisplay(render->display,x,y,&red,&green,&blue,&alpha,&oldZ);
				
						if(newZ < oldZ)
						{					
							GzPutDisplay(render->display,x,y,ctoi(render->flatcolor[0]),ctoi(render->flatcolor[1]),ctoi(render->flatcolor[2]),alpha,newZ);							
						}	
					}			
				}												
			
		}
		}
	}
Пример #8
0
bool rastlee(GzRender* render, GzCoord* cord, GzCoord * norms, GzTextureIndex * Textcord) {

    //swap and sort Y of vertex

    //sort Y by ascending order

    for (int j = 0; j < 2; j++) {
        for (int k = 0; k < 2 - j; k++) {
            if (cord[k][Y]>cord[k + 1][Y]) {
                float tempx = cord[k][X];
                float tempy = cord[k][Y];
                float tempz = cord[k][Z];
                cord[k][X] = cord[k + 1][X];
                cord[k][Y] = cord[k + 1][Y];
                cord[k][Z] = cord[k + 1][Z];
                cord[k + 1][X] = tempx;
                cord[k + 1][Y] = tempy;
                cord[k + 1][Z] = tempz;

                float tempNx = norms[k][X];
                float tempNy = norms[k][Y];
                float tempNz = norms[k][Z];
                norms[k][X] = norms[k + 1][X];
                norms[k][Y] = norms[k + 1][Y];
                norms[k][Z] = norms[k + 1][Z];
                norms[k + 1][X] = tempNx;
                norms[k + 1][Y] = tempNy;
                norms[k + 1][Z] = tempNz;

                float tempU = Textcord[k][U];
                float tempV = Textcord[k][V];
                Textcord[k][U] = Textcord[k + 1][U];
                Textcord[k][V] = Textcord[k + 1][V];
                Textcord[k + 1][U] = tempU;
                Textcord[k + 1][V] = tempV;

            }
        }
    }


    // determine L/R CW
    //horizontal case have two top Y
    if (cord[0][Y] == cord[1][Y]) {
        if (cord[0][X] > cord[1][X]) {
            float tempx = cord[0][X];
            float tempy = cord[0][Y];
            float tempz = cord[0][Z];
            cord[0][X] = cord[1][X];
            cord[0][Y] = cord[1][Y];
            cord[0][Z] = cord[1][Z];
            cord[1][X] = tempx;
            cord[1][Y] = tempy;
            cord[1][Z] = tempz;

            float tempNx = norms[0][X];
            float tempNy = norms[0][Y];
            float tempNz = norms[0][Z];
            norms[0][X] = norms[1][X];
            norms[0][Y] = norms[1][Y];
            norms[0][Z] = norms[1][Z];
            norms[1][X] = tempNx;
            norms[1][Y] = tempNy;
            norms[1][Z] = tempNz;


            float tempU = Textcord[0][U];
            float tempV = Textcord[0][V];
            Textcord[0][U] = Textcord[1][U];
            Textcord[0][V] = Textcord[1][V];
            Textcord[1][U] = tempU;
            Textcord[1][V] = tempV;

        }

    }
    //horizontal case have two bot Y
    else if (cord[1][Y] == cord[2][Y]) {
        if (cord[2][X] > cord[1][X]) {
            float tempx = cord[2][X];
            float tempy = cord[2][Y];
            float tempz = cord[2][Z];
            cord[2][X] = cord[1][X];
            cord[2][Y] = cord[1][Y];
            cord[2][Z] = cord[1][Z];
            cord[1][X] = tempx;
            cord[1][Y] = tempy;
            cord[1][Z] = tempz;

            float tempNx = norms[2][X];
            float tempNy = norms[2][Y];
            float tempNz = norms[2][Z];
            norms[2][X] = norms[1][X];
            norms[2][Y] = norms[1][Y];
            norms[2][Z] = norms[1][Z];
            norms[1][X] = tempNx;
            norms[1][Y] = tempNy;
            norms[1][Z] = tempNz;

            float tempU = Textcord[2][U];
            float tempV = Textcord[2][V];
            Textcord[2][U] = Textcord[1][U];
            Textcord[2][V] = Textcord[1][V];
            Textcord[1][U] = tempU;
            Textcord[1][V] = tempV;
        }
    }

    //bound box
    int top = (int)floor(cord[0][Y]);
    int bot = (int)ceil(cord[2][Y]);
    int left = cord[0][X];
    int right = cord[2][X];

    for (int i = 0; i < 3; i++) {
        if (cord[i][X] < left)
            left = (int)floor(cord[i][X]);
        if (cord[i][X]>right)
            right = (int)ceil(cord[i][X]);
    }

    //interpolate z
    float interpz;
    GzCoord vec01, vec12;
    vec01[X] = cord[1][X] - cord[0][X];
    vec01[Y] = cord[1][Y] - cord[0][Y];
    vec01[Z] = cord[1][Z] - cord[0][Z];

    vec12[X] = cord[2][X] - cord[1][X];
    vec12[Y] = cord[2][Y] - cord[1][Y];
    vec12[Z] = cord[2][Z] - cord[1][Z];

    float A = vec01[Y] * vec12[Z] - vec01[Z] * vec12[Y];
    float B = vec01[Z] * vec12[X] - vec01[X] * vec12[Z];
    float C = vec01[X] * vec12[Y] - vec01[Y] * vec12[X];
    float D = -(A*cord[0][X] + B*cord[0][Y] + C*cord[0][Z]);



    //Gouraud shading
    GzColor goudinter;
    GzColor color0, color1, color2;
    /*
    ShadingEquation(render, color0, norms[0]);
    ShadingEquation(render, color1, norms[1]);
    ShadingEquation(render, color2, norms[2]);*/

    if (render->interp_mode == GZ_COLOR) {
        if (render->tex_fun == NULL) {
            ShadingEquation(render, color0, norms[0]);
            ShadingEquation(render, color1, norms[1]);
            ShadingEquation(render, color2, norms[2]);
        }
        else {//use texture function
            render->Ka[RED] =1;
            render->Ka[GREEN] =1;
            render->Ka[BLUE] = 1;

            render->Kd[RED] = 1;
            render->Kd[GREEN] =1;
            render->Kd[BLUE] = 1;

            render->Ks[RED] = 1;
            render->Ks[GREEN] =1;
            render->Ks[BLUE] = 1;
            ShadingEquation(render, color0, norms[0]);
            ShadingEquation(render, color1, norms[1]);
            ShadingEquation(render, color2, norms[2]);
        }
    }
    GzColor gA, gB, gC, gD;


    gA[RED] = vec01[Y] * (color2[RED] - color1[RED]) - (color1[RED] - color0[RED]) * vec12[Y];
    gB[RED] = (color1[RED] - color0[RED]) * vec12[X] - vec01[X] * (color2[RED] - color1[RED]);
    gC[RED] = vec01[X] * vec12[Y] - vec01[Y] * vec12[X];
    gD[RED] = -(gA[RED]*cord[0][X] + gB[RED]*cord[0][Y] + gC[RED]*color0[RED]);

    gA[GREEN] = vec01[Y] * (color2[GREEN] - color1[GREEN]) - (color1[GREEN] - color0[GREEN]) * vec12[Y];
    gB[GREEN] = (color1[GREEN] - color0[GREEN]) * vec12[X] - vec01[X] * (color2[GREEN] - color1[GREEN]);
    gC[GREEN] = vec01[X] * vec12[Y] - vec01[Y] * vec12[X];
    gD[GREEN] = -(gA[GREEN] * cord[0][X] + gB[GREEN] * cord[0][Y] + gC[GREEN] * color0[GREEN]);

    gA[BLUE] = vec01[Y] * (color2[BLUE] - color1[BLUE]) - (color1[BLUE] - color0[BLUE]) * vec12[Y];
    gB[BLUE] = (color1[BLUE] - color0[BLUE]) * vec12[X] - vec01[X] * (color2[BLUE] - color1[BLUE]);
    gC[BLUE] = vec01[X] * vec12[Y] - vec01[Y] * vec12[X];
    gD[BLUE] = -(gA[BLUE] * cord[0][X] + gB[BLUE] * cord[0][Y] + gC[BLUE] * color0[BLUE]);

    //prepare for interp UV texture
    float Vzp;// Vz'
    GzTextureIndex*  perspTextcord = new GzTextureIndex[3];//warp uv-> UV from image space to perspective space for each vertex
    for (int k = 0; k < 3; k++) {

        Vzp = cord[k][Z] / (INT_MAX - cord[k][Z]);
        perspTextcord[k][U] = Textcord[k][U] / (Vzp + 1);
        perspTextcord[k][V] = Textcord[k][V] / (Vzp + 1);
    }



    //if in bbox draw pixel
    for (int i = left; i < right; i++) {
        if (i<0 || i>render->display->xres) {
            continue;
        }
        for (int j = top; j < bot; j++) {
            if (j<0 || j>render->display->yres) {
                continue;
            }

            float a01 = cord[1][Y] - cord[0][Y];
            float a12 = cord[2][Y] - cord[1][Y];
            float a20 = cord[0][Y] - cord[2][Y];
            float b01 = -(cord[1][X] - cord[0][X]);
            float b12 = -(cord[2][X] - cord[1][X]);
            float b20 = -(cord[0][X] - cord[2][X]);
            float c01 = -b01*cord[0][Y] - a01*cord[0][X];
            float c12 = -b12*cord[1][Y] - a12*cord[1][X];
            float c20 = -b20*cord[2][Y] - a20*cord[2][X];

            float e01 = a01*(float)i + b01*(float)j + c01;
            float e12 = a12*(float)i + b12*(float)j + c12;
            float e20 = a20*(float)i + b20*(float)j + c20;

            if ((e01 == 0 || e12 == 0 || e20 == 0)||((e01 > 0) && (e12 > 0) && (e20 > 0)) ||
                    ((e01 < 0) && (e12 < 0) && (e20 < 0))) {

                interpz = (-(A*i) - (B*j) - D) / C;
                GzIntensity r, g, b, a;
                GzDepth z;

                GzGetDisplay(render->display, i, j, &r, &g, &b, &a, &z);

                if (interpz < z) {
                    GzCoord pers01, pers12;
                    pers01[U] = perspTextcord[1][U] - perspTextcord[0][U];
                    pers01[V] = perspTextcord[1][V] - perspTextcord[0][V];

                    pers12[U] = perspTextcord[2][U] - perspTextcord[1][U];
                    pers12[V] = perspTextcord[2][V] - perspTextcord[1][V];


                    //	GzCoord intepcrossprod;
                    //crossvector(pers01, pers12, intepcrossprod);

                    GzTextureIndex tA, tB, tC, tD, textureinter, newuv;
                    tA[U] = vec01[Y] * (pers12[U]) - (pers01[U]) * vec12[Y];
                    tB[U] = (pers01[U]) * vec12[X] - vec01[X] * (pers12[U]);
                    tC[U] = vec01[X] * vec12[Y] - vec01[Y] * vec12[X];
                    tD[U] = -(tA[U] * cord[0][X] + tB[U] * cord[0][Y] + tC[U] * perspTextcord[0][U]);

                    tA[V] = vec01[Y] * (pers12[V]) - (pers01[V]) * vec12[Y];
                    tB[V] = (pers01[V]) * vec12[X] - vec01[X] * (pers12[V]);
                    tC[V] = vec01[X] * vec12[Y] - vec01[Y] * vec12[X];
                    tD[V] = -(tA[V] * cord[0][X] + tB[V] * cord[0][Y] + tC[V] * perspTextcord[0][V]);
                    // interpolateUV to pixel
                    /*textureinter[U] = -(tA[U] * i + tB[U] * j + tD[U]) / tC[U];
                    textureinter[V] = -(tA[V] * i + tB[V] * j + tD[V]) / tC[V];*/
                    textureinter[U] = interpolate(tA[U], tB[U], tC[U], tD[U], i, j);
                    textureinter[V] = interpolate(tA[V], tB[V], tC[V], tD[V], i, j);
                    //unwarping
                    float Vzp = interpz / (INT_MAX - interpz);
                    newuv[U] = textureinter[U] * (Vzp + 1);
                    newuv[V] = textureinter[V] * (Vzp + 1);

                    //texture color lookup with bilinear interpolation
                    GzColor texColor;
                    if (render->tex_fun != NULL) {
                        render->tex_fun(newuv[U], newuv[V], texColor);
                    }
                    switch (render->interp_mode) {
                    case GZ_FLAT:
                        r = (GzIntensity)ctoi((float)render->flatcolor[0]);
                        g = (GzIntensity)ctoi((float)render->flatcolor[1]);
                        b = (GzIntensity)ctoi((float)render->flatcolor[2]);
                        z = interpz;
                        break;
                    case GZ_COLOR://ground shading


                        render->Ka[RED] = texColor[RED];
                        render->Ka[GREEN] = texColor[GREEN];
                        render->Ka[BLUE] = texColor[BLUE];
                        render->Kd[RED] = texColor[RED];
                        render->Kd[GREEN] = texColor[GREEN];
                        render->Kd[BLUE] = texColor[BLUE];
                        render->Ks[RED] = texColor[RED];
                        render->Ks[GREEN] = texColor[GREEN];
                        render->Ks[BLUE] = texColor[BLUE];


                        goudinter[RED] = -(gA[RED] * i + gB[RED] * j + gD[RED]) / gC[RED];
                        goudinter[GREEN] = -(gA[GREEN] * i + gB[GREEN] * j + gD[GREEN]) / gC[GREEN];
                        goudinter[BLUE] = -(gA[BLUE] * i + gB[BLUE] * j + gD[BLUE]) / gC[BLUE];

                        //texture color
                        if (render->tex_fun != NULL) {
                            goudinter[RED] *= texColor[RED] ;
                            goudinter[GREEN] *= texColor[GREEN];
                            goudinter[BLUE] *= texColor[BLUE];
                        }

                        if (goudinter[RED] > 1.0) goudinter[RED] = 1.0;
                        if (goudinter[GREEN] > 1.0) goudinter[GREEN] = 1.0;
                        if (goudinter[BLUE] > 1.0) goudinter[BLUE] = 1.0;
                        r = (GzIntensity)ctoi(goudinter[RED]);
                        g = (GzIntensity)ctoi(goudinter[GREEN]);
                        b = (GzIntensity)ctoi(goudinter[BLUE]);
                        z = interpz;
                        break;

                    case GZ_NORMALS:
                        //interpolizing norms;
                        GzColor pA, pB, pC, pD;
                        pA[RED] = vec01[Y] * (norms[2][RED] - norms[1][RED]) - (norms[1][RED] - norms[0][RED]) * vec12[Y];
                        pB[RED] = (norms[1][RED] - norms[0][RED]) * vec12[X] - vec01[X] * (norms[2][RED] - norms[1][RED]);
                        pC[RED] = vec01[X] * vec12[Y] - vec01[Y] * vec12[X];
                        pD[RED] = -(pA[RED] * cord [0][X] + pB[RED] * cord[0][Y] + pC[RED] * norms[0][RED]);

                        pA[GREEN] = vec01[Y] * (norms[2][GREEN] - norms[1][GREEN]) - (norms[1][GREEN] - norms[0][GREEN]) * vec12[Y];
                        pB[GREEN] = (norms[1][GREEN] - norms[0][GREEN]) * vec12[X] - vec01[X] * (norms[2][GREEN] - norms[1][GREEN]);
                        pC[GREEN] = vec01[X] * vec12[Y] - vec01[Y] * vec12[X];
                        pD[GREEN] = -(pA[GREEN] * cord[0][X] + pB[GREEN] * cord[0][Y] + pC[GREEN] * norms[0][GREEN]);

                        pA[BLUE] = vec01[Y] * (norms[2][BLUE] - norms[1][BLUE]) - (norms[1][BLUE] - norms[0][BLUE]) * vec12[Y];
                        pB[BLUE] = (norms[1][BLUE] - norms[0][BLUE]) * vec12[X] - vec01[X] * (norms[2][BLUE] - norms[1][BLUE]);
                        pC[BLUE] = vec01[X] * vec12[Y] - vec01[Y] * vec12[X];
                        pD[BLUE] = -(pA[BLUE] * cord[0][X] + pB[BLUE] * cord[0][Y] + pC[BLUE] * norms[0][BLUE]);

                        GzColor phonginter;

                        phonginter[0] = -(pA[0] * i + pB[0] * j + pD[0]) / pC[0];
                        phonginter[1] = -(pA[1] * i + pB[1] * j + pD[1]) / pC[1];
                        phonginter[2] = -(pA[2] * i + pB[2] * j + pD[2]) / pC[2];
                        NormVector(phonginter);

                        //Then shading calculation with texture color used as Kd and Ka
                        if (render->tex_fun != NULL) {
                            render->Ka[RED] = render->Kd[RED] = texColor[RED];
                            render->Ka[GREEN] = render->Kd[GREEN] = texColor[GREEN];
                            render->Ka[BLUE] = render->Kd[BLUE] = texColor[BLUE];
                        }
                        GzColor colorpix;
                        ShadingEquation(render, colorpix, phonginter);
                        r = (GzIntensity)ctoi(colorpix[RED]);
                        g = (GzIntensity)ctoi(colorpix[GREEN]);
                        b = (GzIntensity)ctoi(colorpix[BLUE]);
                        z = interpz;

                        break;
                    }
                    GzPutDisplay(render->display, i, j, r, g, b, a, z);
                }
            }


        }

    }
    return true;
}
Пример #9
0
void GzRasterize(GzRender *render,GzCoord *imageV, GzCoord *imageN,GzCoord *screenV,GzTextureIndex *textureC)
{
	
	float xMin,xMax,yMin,yMax;
	float a1,b1,c1,a2,b2,c2,a3,b3,c3;
	float aX,bY,cZ,d;
	GzCoord v0,v1,v2;
	GzEdge edge[3];
	
	GzCoord tempCoord1, tempCoord2;

	// gourad shading values
	GzColor cpA,cpB,cpC,cpD;
	
	// phong shading values
	GzCoord imageVa, imageVb, imageVc, imageVd; //image vertices
	GzCoord imageNa, imageNb, imageNc, imageNd; //image normals

	GzTextureIndex texCPa,texCPb,texCPc,texCPd;

	//Find xmin,xmax,ymin and ymax to obtain bounding rectangle for the triangle
	xMin = min(screenV[0][X],min(screenV[1][X],screenV[2][X]));
	yMin = min(screenV[0][Y],min(screenV[1][Y],screenV[2][Y]));

	xMax = max(screenV[0][X],max(screenV[1][X],screenV[2][X]));
	yMax = max(screenV[0][Y],max(screenV[1][Y],screenV[2][Y]));

	xMin = max((int)(ceil(xMin)),0);
	yMin = max((int)(ceil(yMin)),0);

	xMax = min((int)(floor(xMax)),render->display->xres);
	yMax = min((int)(floor(yMax)),render->display->yres);

	
	// Setting vertices of the triangle and the edges of the triangle in anti-clockwise direction for processing

	v0[X] = screenV[0][X];
	v0[Y] = screenV[0][Y];
	v0[Z] = screenV[0][Z];

	v1[X] = screenV[1][X];
	v1[Y] = screenV[1][Y];
	v1[Z] = screenV[1][Z];

	v2[X] = screenV[2][X];
	v2[Y] = screenV[2][Y];
	v2[Z] = screenV[2][Z];

	//edge 0 v0 -> v2
	edge[0].start[X] = v0[X];
	edge[0].start[Y] = v0[Y];
	edge[0].start[Z] = v0[Z];
		
	edge[0].end[X] = v2[X];
	edge[0].end[Y] = v2[Y];
	edge[0].end[Z] = v2[Z];
	
	//edge 1 v2 -> v1
	edge[1].start[X] = v2[X];
	edge[1].start[Y] = v2[Y];
	edge[1].start[Z] = v2[Z];
	
	edge[1].end[X] = v1[X];
	edge[1].end[Y] = v1[Y];
	edge[1].end[Z] = v1[Z];
	
	//edge 2 v1 -> v0
	edge[2].start[X] = v1[X];
	edge[2].start[Y] = v1[Y];
	edge[2].start[Z] = v1[Z];
	
	edge[2].end[X] = v0[X];
	edge[2].end[Y] = v0[Y];
	edge[2].end[Z] = v0[Z];
	
	/* Computing Line Equation coefficients */

	a1 = edge[0].end[Y] - edge[0].start[Y];
	b1 = edge[0].start[X] - edge[0].end[X];
	c1 = (((edge[0].end[X] - edge[0].start[X]) * edge[0].start[Y]) - ((edge[0].end[Y] - edge[0].start[Y]) * edge[0].start[X]));

	a2 = edge[1].end[Y] - edge[1].start[Y];
	b2 = edge[1].start[X] - edge[1].end[X];
	c2 = (((edge[1].end[X] - edge[1].start[X]) * edge[1].start[Y]) - ((edge[1].end[Y] - edge[1].start[Y]) * edge[1].start[X]));

	a3 = edge[2].end[Y] - edge[2].start[Y];
	b3 = edge[2].start[X] - edge[2].end[X];
	c3 = (((edge[2].end[X] - edge[2].start[X]) * edge[2].start[Y]) - ((edge[2].end[Y] - edge[2].start[Y]) * edge[2].start[X]));
		
	/*	Finding Crossproduct of 2 edges to obtain the plane equation for the triangle	*/
	aX = (((edge[0].end[Y] - edge[0].start[Y]) * (edge[1].end[Z] - edge[1].start[Z])) - ((edge[0].end[Z] - edge[0].start[Z]) * (edge[1].end[Y] - edge[1].start[Y])));
	bY = -(((edge[0].end[X] - edge[0].start[X]) * (edge[1].end[Z] - edge[1].start[Z])) - ((edge[0].end[Z] - edge[0].start[Z]) * (edge[1].end[X] - edge[1].start[X])));
	cZ = (((edge[0].end[X] - edge[0].start[X]) * (edge[1].end[Y] - edge[1].start[Y])) - ((edge[0].end[Y] - edge[0].start[Y]) * (edge[1].end[X] - edge[1].start[X])));
	d = -(aX * screenV[0][X] + bY * screenV[0][Y] + cZ * screenV[0][Z]);
		
	/*	setting values for pixels which will be constant through the interpolation calculation	*/
	tempCoord1[X] = edge[0].end[X] - edge[0].start[X];
	tempCoord2[X] = edge[1].end[X] - edge[1].start[X];
	
	tempCoord1[Y] = edge[0].end[Y] - edge[0].start[Y];
	tempCoord2[Y] = edge[1].end[Y] - edge[1].start[Y];

	//For Gourad Shading
	if(render->interp_mode == GZ_COLOR)
	{	
		//calculate the color for each vertex and set up the interpolation plane coefficients
		GzColor vertexClr[3];
		int dummy1 = 0,dummy2 = 0;	
		GzShade(render,imageV[0],imageN[0],vertexClr[0],textureC[0],dummy1,dummy2);
		GzShade(render,imageV[1],imageN[1],vertexClr[1],textureC[1],dummy1,dummy2);
		GzShade(render,imageV[2],imageN[2],vertexClr[2],textureC[2],dummy1,dummy2);		

		tempCoord1[Z] = vertexClr[2][0] - vertexClr[0][0];
		tempCoord2[Z] = vertexClr[1][0] - vertexClr[2][0];
												
		cpA[0] = tempCoord1[Y] * tempCoord2[Z] - tempCoord1[Z] * tempCoord2[Y];
		cpB[0] = tempCoord1[Z] * tempCoord2[X] - tempCoord1[X] * tempCoord2[Z];
		cpC[0] = tempCoord1[X] * tempCoord2[Y] - tempCoord1[Y] * tempCoord2[X];
		cpD[0] = -(cpA[0] * edge[0].start[X] + cpB[0] * edge[0].start[Y] + cpC[0] * vertexClr[0][0]);

		tempCoord1[Z] = 0;
		tempCoord2[Z] = 0;

		tempCoord1[Z] = vertexClr[2][1] - vertexClr[0][1];
		tempCoord2[Z] = vertexClr[1][1] - vertexClr[2][1];
												
		cpA[1] = tempCoord1[Y] * tempCoord2[Z] - tempCoord1[Z] * tempCoord2[Y];
		cpB[1] = tempCoord1[Z] * tempCoord2[X] - tempCoord1[X] * tempCoord2[Z];
		cpC[1] = tempCoord1[X] * tempCoord2[Y] - tempCoord1[Y] * tempCoord2[X];
		cpD[1] = -(cpA[1] * edge[0].start[X] + cpB[1] * edge[0].start[Y] + cpC[1] * vertexClr[0][1]);

		tempCoord1[Z] = 0;
		tempCoord2[Z] = 0;

		tempCoord1[Z] = vertexClr[2][2] - vertexClr[0][2];
		tempCoord2[Z] = vertexClr[1][2] - vertexClr[2][2];
												
		cpA[2] = tempCoord1[Y] * tempCoord2[Z] - tempCoord1[Z] * tempCoord2[Y];
		cpB[2] = tempCoord1[Z] * tempCoord2[X] - tempCoord1[X] * tempCoord2[Z];
		cpC[2] = tempCoord1[X] * tempCoord2[Y] - tempCoord1[Y] * tempCoord2[X];
		cpD[2] = -(cpA[2] * edge[0].start[X] + cpB[2] * edge[0].start[Y] + cpC[2] * vertexClr[0][2]);

		tempCoord1[Z] = 0;
		tempCoord2[Z] = 0;
			
	}
	
	/*	For phong shading  */
	else if(render->interp_mode == GZ_NORMALS)
	{	
		/* calculate interpolation plane coefficient for planes and normals	*/
		for(int i = 0; i < 3; i++)
		{
			/* For vertices	*/
			tempCoord1[Z] = imageV[2][i] - imageV[0][i];
			tempCoord2[Z] = imageV[1][i] - imageV[2][i];						
					
			imageVa[i] = tempCoord1[Y] * tempCoord2[Z] - tempCoord1[Z] * tempCoord2[Y];
			imageVb[i] = tempCoord1[Z] * tempCoord2[X] - tempCoord1[X] * tempCoord2[Z];
			imageVc[i] = tempCoord1[X] * tempCoord2[Y] - tempCoord1[Y] * tempCoord2[X];
			imageVd[i] = -(imageVa[i] * edge[0].start[X] + imageVb[i] * edge[0].start[Y] + imageVc[i] * imageV[0][i]);

			/* For normals	*/
			tempCoord1[Z] = imageN[2][i] - imageN[0][i];
			tempCoord2[Z] = imageN[1][i] - imageN[2][i];
		
			imageNa[i] = tempCoord1[Y] * tempCoord2[Z] - tempCoord1[Z] * tempCoord2[Y];
			imageNb[i] = tempCoord1[Z] * tempCoord2[X] - tempCoord1[X] * tempCoord2[Z];
			imageNc[i] = tempCoord1[X] * tempCoord2[Y] - tempCoord1[Y] * tempCoord2[X];
			imageNd[i] = -(imageNa[i] * edge[0].start[X] + imageNb[i] * edge[0].start[Y] + imageNc[i] * imageN[0][i]);
		}

		GzTextureIndex perspTextC[3];
		float screenSpaceZ[3];
			
		for(int i = 0; i < 3; i++)
		{			
			screenSpaceZ[i] = -(aX * screenV[i][X] + bY * screenV[i][Y] + d)/cZ;
			//transform from image space to perspective space by warping 
			perspTextC[i][U] = textureC[i][U] / ((screenSpaceZ[i]/(INT_MAX - screenSpaceZ[i])) + 1);
			perspTextC[i][V] = textureC[i][V] / ((screenSpaceZ[i]/(INT_MAX - screenSpaceZ[i])) + 1);						

		}

		
		for( int i = 0; i < 2; i++ )
		{
			// set up interpolation coefficients for perspective space texture coordinate
			tempCoord1[Z] = perspTextC[2][i] - perspTextC[0][i];
			tempCoord2[Z] = perspTextC[1][i] - perspTextC[2][i];
									
			texCPa[i] = tempCoord1[Y] * tempCoord2[Z] - tempCoord1[Z] * tempCoord2[Y];
			texCPb[i] = tempCoord1[Z] * tempCoord2[X] - tempCoord1[X] * tempCoord2[Z];
			texCPc[i] = tempCoord1[X] * tempCoord2[Y] - tempCoord1[Y] * tempCoord2[X];
			texCPd[i] = -(texCPa[i] * edge[0].start[X] + texCPb[i] * edge[0].start[Y] + texCPc[i] * perspTextC[0][i]); 			

		}

				
	}
	
	int zMax = 0;

	for( int y = yMin; y <= yMax; y++ )
	{
		for( int x = xMin; x <= xMax; x++ )
		{			
			if((a1 * x + b1 * y + c1 > 0 && a2 * x + b2 * y + c2 > 0 && a3 * x + b3 * y + c3 > 0) || ((a1 * x + b1 * y + c1) <= 0 && (a2 * x + b2 * y + c2) <= 0 && (a3 * x + b3 * y + c3) <= 0))
			{
				GzDepth newZ = (GzDepth)(-( aX * x + bY * y  + d ) / cZ);

				// Check if the new value of z is in front of the camera
				if( newZ > 0 )
				{	
					if(newZ > zMax)
					{
						zMax = newZ;
					}
					GzIntensity r, g, b, a;
					GzDepth oldZ;
					
					GzGetDisplay( render->display, x, y, &r, &g, &b, &a, &oldZ);			

					//If the value of new z id greater than old z then it can be skipped because it will be hidden
					if( newZ < oldZ )
					{
												
						GzColor color;						
						

						/* For Phong shading	*/
						switch(render->interp_mode){
						case GZ_NORMALS:
						{
							/* Perform biliniear interpolation, normalize it and calculate the color at the current pixel by calling GzShade*/
							GzCoord imageVi, imageNi;
							GzTextureIndex textC;
							
							for(int i = 0; i < 3; i++)
							{
								imageVi[i] = -(imageVa[i] * x + imageVb[i] * y + imageVd[i]) / imageVc[i];							                               						                                   
								imageNi[i] = -(imageNa[i] * x + imageNb[i] * y  + imageNd[i]) / imageNc[i];							                                 						                                     
							}							

							for( int i = 0; i < 2; i++ )
							{															                                                         																								
								//calculate interpolation plane for texture coords and unwarp it from perspective to image space
								textC[i] = -(texCPa[i] * x + texCPb[i] * y + texCPd[i]) / texCPc[i];
								textC[i] = GzperspToimage( newZ, textC[i] );									
							}													
						
							float normalizer = sqrt(imageNi[X] * imageNi[X] + imageNi[Y] * imageNi[Y] + imageNi[Z] * imageNi[Z]);
							imageNi[X] = imageNi[X]/normalizer;
							imageNi[Y] = imageNi[Y]/normalizer;
							imageNi[Z] = imageNi[Z]/normalizer;														
							GzShade(render,imageVi,imageNi,color,textC,newZ,zMax);								
							break;
						}
						case GZ_COLOR:							
						{
							/*	Interpolate the colors for Gourad Shading at each vertex	*/
							color[RED] = -(cpA[0] * x + cpB[0] * y + cpD[0])/cpC[0];
							color[GREEN] = -(cpA[1] * x + cpB[1] * y  + cpD[1])/cpC[1];
							color[BLUE] = -(cpA[2] * x + cpB[2] * y  + cpD[2])/cpC[2];														

							break;
						}					
						default:
						{
							/*	Default flat shading	*/
							color[RED] = render->flatcolor[RED];
							color[GREEN] = render->flatcolor[GREEN];
							color[BLUE] = render->flatcolor[BLUE];							
							break;
						}		
						}
						/* Put the calculated values of the color onto the display	*/
						
						if(GRAINY_NOISE_EFFECT)
						{
							float noise = scaled_octave_noise(8,0.75,2,0,4,x,y,newZ/(oldZ - newZ));							
							GzPutDisplay(render->display, x, y, int(ctoi(color[RED]) * noise),int(ctoi(color[GREEN]) * noise),int(ctoi(color[BLUE]) * noise),a,newZ);								  								 								  								  											
						}
						else
						{
							GzPutDisplay(render->display, x, y, int(ctoi(color[RED])),int(ctoi(color[GREEN])),int(ctoi(color[BLUE])),a,newZ);								  								 								  								  				
						}
					}
				}
			}						
		}
	} 
} 	
Пример #10
0
void Rasterization( GzRender * render, GzCoord * vertex, GzCoord * normXY)
{
	float temp1=0.0,temp2=0.0,temp3=0.0,temp4=0.0,m=0.0,midPoint=0.0;
	triEdge tEdges[3];
	int flag =0;
	int defVertex[3]={0,1,2};
	
float xDiffE0,yDiffE0,zDiffE0,xDiffE1,yDiffE1,zDiffE1,xDiffE2,yDiffE2,zDiffE2;
float A,B,C,D;
float a0,b0,c0,a1,b1,c1,a2,b2,c2;
float lowerX=99999999.0,lowerY=99999999.0,upperX=0.0,upperY=0.0;
float v0,v1,v2,v;
GzIntensity r,g,b,a;
GzDepth z;
	//First sort the vertices by Y if Y is same sort it according to X

sortTriangle(vertex,&defVertex[0]);

	//Assign edge in CCW
	if(vertex[0][1]== vertex[1][1])
	{
		tEdges[0].x1= vertex[1][0];
		tEdges[0].x2= vertex[0][0];
		tEdges[0].y1= vertex[1][1];
		tEdges[0].y2= vertex[0][1];
		tEdges[0].z1= vertex[1][2];
		tEdges[0].z2= vertex[0][2];
		

		tEdges[1].x1= vertex[0][0];
		tEdges[1].x2= vertex[2][0];
		tEdges[1].y1= vertex[0][1];
		tEdges[1].y2= vertex[2][1];
		tEdges[1].z1= vertex[0][2];
		tEdges[1].z2= vertex[2][2];
		

		tEdges[2].x1= vertex[2][0];
		tEdges[2].x2= vertex[1][0];
		tEdges[2].y1= vertex[2][1];
		tEdges[2].y2= vertex[1][1];
		tEdges[2].z1= vertex[2][2];
		tEdges[2].z2= vertex[1][2];

		tEdges[0].tl= defVertex[1];		
		tEdges[0].hd= defVertex[0];
		tEdges[1].tl= defVertex[0];		
		tEdges[1].hd= defVertex[2];
		tEdges[2].tl= defVertex[2];		
		tEdges[2].hd= defVertex[1];

		
	}


	if(vertex[1][1]== vertex[2][1])
	{

		
		tEdges[0].x1= vertex[0][0];
		tEdges[0].x2= vertex[1][0];
		tEdges[0].y1= vertex[0][1];
		tEdges[0].y2= vertex[1][1];
		tEdges[0].z1= vertex[0][2];
		tEdges[0].z2= vertex[1][2];
		


		tEdges[1].x1= vertex[1][0];
		tEdges[1].x2= vertex[2][0];
		tEdges[1].y1= vertex[1][1];
		tEdges[1].y2= vertex[2][1];
		tEdges[1].z1= vertex[1][2];
		tEdges[1].z2= vertex[2][2];
		


		tEdges[2].x1= vertex[2][0];
		tEdges[2].x2= vertex[0][0];
		tEdges[2].y1= vertex[2][1];
		tEdges[2].y2= vertex[0][1];
		tEdges[2].z1= vertex[2][2];
		tEdges[2].z2= vertex[0][2];

		tEdges[0].tl= defVertex[0];	
		tEdges[0].hd= defVertex[1];
		tEdges[1].tl= defVertex[1];		
		tEdges[1].hd= defVertex[2];
		tEdges[2].tl= defVertex[2];	
		tEdges[2].hd= defVertex[0];

		
	}

	else
	{
		
	float slope=0.0;
	slope= ( vertex[2][1] - vertex[0][1] ) / ( vertex[2][0] - vertex[0][0] );
		midPoint=vertex[0][0]+( ( vertex[1][1] - vertex[0][1] ) / slope )  ;
		if( vertex[1][0]< midPoint )
		{
			tEdges[0].x1= vertex[0][0];
			tEdges[0].x2= vertex[1][0];
			tEdges[0].y1= vertex[0][1];
			tEdges[0].y2= vertex[1][1];
			tEdges[0].z1= vertex[0][2];
			tEdges[0].z2= vertex[1][2];
			


			tEdges[1].x1= vertex[1][0];
			tEdges[1].x2= vertex[2][0];
			tEdges[1].y1= vertex[1][1];
			tEdges[1].y2= vertex[2][1];
			tEdges[1].z1= vertex[1][2];
			tEdges[1].z2= vertex[2][2];
			


			tEdges[2].x1= vertex[2][0];
			tEdges[2].x2= vertex[0][0];
			tEdges[2].y1= vertex[2][1];
			tEdges[2].y2= vertex[0][1];
			tEdges[2].z1= vertex[2][2];
			tEdges[2].z2= vertex[0][2];

			tEdges[0].tl= defVertex[0];			
			tEdges[0].hd= defVertex[1];
			tEdges[1].tl= defVertex[1];			
			tEdges[1].hd= defVertex[2];
			tEdges[2].tl= defVertex[2];			
			tEdges[2].hd= defVertex[0];
		}

		else if( vertex[1][0]>midPoint  )
		{
			tEdges[0].x1= vertex[0][0];
			tEdges[0].x2= vertex[2][0];
			tEdges[0].y1= vertex[0][1];
			tEdges[0].y2= vertex[2][1];
			tEdges[0].z1= vertex[0][2];
			tEdges[0].z2= vertex[2][2];
			


			tEdges[1].x1= vertex[2][0];
			tEdges[1].x2= vertex[1][0];
			tEdges[1].y1= vertex[2][1];
			tEdges[1].y2= vertex[1][1];
			tEdges[1].z1= vertex[2][2];
			tEdges[1].z2= vertex[1][2];
			


			tEdges[2].x1= vertex[1][0];
			tEdges[2].x2= vertex[0][0];
			tEdges[2].y1= vertex[1][1];
			tEdges[2].y2= vertex[0][1];
			tEdges[2].z1= vertex[1][2];
			tEdges[2].z2= vertex[0][2];

			tEdges[0].tl= defVertex[0];			
			tEdges[0].hd= defVertex[2];
			tEdges[1].tl= defVertex[2];			
			tEdges[1].hd= defVertex[1];
			tEdges[2].tl= defVertex[1];			
			tEdges[2].hd= defVertex[0];

		}

		
	}

	
	xDiffE0=tEdges[0].x2 - tEdges[0].x1;
	xDiffE1= tEdges[1].x2 - tEdges[1].x1;
	xDiffE2=tEdges[2].x2 - tEdges[2].x1;

	yDiffE0= tEdges[0].y2 - tEdges[0].y1;
	yDiffE1=tEdges[1].y2 - tEdges[1].y1;
	yDiffE2=tEdges[2].y2 - tEdges[2].y1;

	zDiffE0= tEdges[0].z2 - tEdges[0].z1;
	zDiffE1= tEdges[1].z2 - tEdges[1].z1;
	zDiffE2=tEdges[2].z2-tEdges[1].z1;
	
	//Find ABC value for the line equation
	a0 = yDiffE0;
	a1 = yDiffE1;
	a2 =yDiffE2;

	 b0 = -xDiffE0;
	 b1 = -xDiffE1;
	 b2 = -xDiffE2;

	 c0 = xDiffE0 * tEdges[0].y1  - yDiffE0 * tEdges[0].x1 ;	
	 c1 = xDiffE1 * tEdges[1].y1 - yDiffE1 * tEdges[1].x1 ;	
	 c2 =  xDiffE2* tEdges[2].y1  - yDiffE2 * tEdges[2].x1 ;

	 //Find Ax+By+Cz+d=0
	 float temp=0.0;
	A = yDiffE0 * zDiffE1 - zDiffE0 * yDiffE1;
	B = - xDiffE0 * zDiffE1 + zDiffE0 * xDiffE1 ;
	C = xDiffE0 * yDiffE1 - yDiffE0 * xDiffE1;
	temp=A* vertex[0][0] + B* vertex[0][1] + C* vertex[0][2];
	D=-temp;

	//Find the bounding box for the triangle
	
	//construct bounding box
	createBoundingBox(vertex,&lowerX,&lowerY,&upperX,&upperY);
	

	 if(render->interp_mode== GZ_NORMALS)
	{
		getPlaneCoeff(tEdges,normXY);
	}
	else if(render->interp_mode== GZ_COLOR)
	{
		GzColor c[3];
		memset(c,0,sizeof(GzColor)*3);

		for( int p =0; p <3; p++ )
		doShading(render,c[p],normXY[p]);
		
		getPlaneCoeff(tEdges,c);

	}
	

	//Check for each pixel within the bounding box whether it lies in the triangle
	for(int i=lowerY;i<= upperY; i++ )
	{
		for(int j=lowerX;j<= upperX; j++ )
		{
			GzIntensity r, g, b, a;
			GzDepth z;

			v =-(A*j+B*i+D)/C;

			 v0 = a0 * j + b0 * i + c0;
			 v1 = a1 * j + b1 * i + c1;
			 v2 = a2 * j + b2 * i + c2;
			

			if(v<0||v0<0||v1<0||v2<0)
			continue;

			
			GzGetDisplay( render->display, j, i, &r, &g, &b, &a, &z );
			//Check with prev Z vaule
			GzColor q;

			
				
				 for(int k=0;k<3;k++)
				q[k] = -( pCof[k].planeA * j + pCof[k].planeB * i  + pCof[k].planeD ) / pCof[k].planeC;
				

				if(render->interp_mode == GZ_FLAT)
				{
					for(int k=0;k<3;k++)
					q[k] = render->flatcolor[k];
						if( v < z || z==0)
					GzPutDisplay(render->display,j,i,ctoi(q[0]),ctoi(q[1]),ctoi(q[2]),a,(GzDepth )v);
				}
				if(render->interp_mode == GZ_COLOR)
				{
						if( v < z || z==0)
					GzPutDisplay(render->display,j,i,ctoi(q[0]),ctoi(q[1]),ctoi(q[2]),a,(GzDepth )v);
				}
				else if(render->interp_mode == GZ_NORMALS)
				{
					GzColor c;
					memset(c,0,sizeof(GzColor));
					getNormal(q);
					doShading(render,c,q);
						if( v < z || z==0)
					GzPutDisplay(render->display,j,i,ctoi(c[0]),ctoi(c[1]),ctoi(c[2]),a,(GzDepth )v);
				}
				

			
		} 
	} 

}
Пример #11
0
int Rasterization( GzRender * render, GzCoord * vertex )
{
	float temp1=0.0,temp2=0.0,temp3=0.0,m=0.0,midPoint=0.0;
float edges[3][6]; //x1,y1,z1,x2,y2,z2
float xDiffE0,yDiffE0,zDiffE0,xDiffE1,yDiffE1,zDiffE1,xDiffE2,yDiffE2,zDiffE2;
float A,B,C,D;
float a0,b0,c0,a1,b1,c1,a2,b2,c2;
float lowerX=99999999.0,lowerY=99999999.0,upperX=0.0,upperY=0.0;
float v0,v1,v2,v;
GzIntensity r,g,b,a;
GzDepth z;
	
for(int i=0;i<2;i++)
{
	for(int j=0;j<2-i;j++)
	{
		if( (vertex[j+1][1]<vertex[j][1])|| (vertex[j+1][0]<vertex[j][0] && vertex[j][1]==vertex[j+1][1]))
		{
			temp1=vertex[j][0];//x
			temp2=vertex[j][1];//y
			temp3=vertex[j][2];//z
			
			vertex[j][0]=vertex[j+1][0];
			vertex[j][1]=vertex[j+1][1];
			vertex[j][2]=vertex[j+1][2];
			
			vertex[j+1][0]=temp1;
			vertex[j+1][1]=temp2;
			vertex[j+1][2]=temp3;
		
		}

	}
}

//get in anti clockwise
if(vertex[1][1]==vertex[2][1])
{
//edge 0-1
	m=0.0;
edges[0][0]=vertex[0][0];//x1
edges[0][3]=vertex[1][0];//x2
edges[0][1]=vertex[0][1];//y1
edges[0][4]=vertex[1][1];//y2
edges[0][2]=vertex[0][2];//z1
edges[0][5]=vertex[1][2];//z2

//edge 1-2
edges[1][0]=vertex[1][0];
edges[1][3]=vertex[2][0];
edges[1][1]=vertex[1][1];
edges[1][4]=vertex[2][1];
edges[1][2]=vertex[1][2];
edges[1][5]=vertex[2][2];

//edge 2-0
edges[2][0]=vertex[2][0];
edges[2][3]=vertex[0][0];
edges[2][1]=vertex[2][1];
edges[2][4]=vertex[0][1];
edges[2][2]=vertex[2][2];
edges[2][5]=vertex[0][2];
}

else if(vertex[1][1]==vertex[0][1])
{
	m=0.0;
//edge 1-0
edges[0][0]=vertex[1][0];
edges[0][3]=vertex[0][0];
edges[0][1]=vertex[1][1];
edges[0][4]=vertex[0][1];
edges[0][2]=vertex[1][2];
edges[0][5]=vertex[0][2];

//edge 0-2
edges[1][0]=vertex[0][0];
edges[1][3]=vertex[2][0];
edges[1][1]=vertex[0][1];
edges[1][4]=vertex[2][1];
edges[1][2]=vertex[0][2];
edges[1][5]=vertex[2][2];

//edge 2-1
edges[2][0]=vertex[2][0];
edges[2][3]=vertex[1][0];
edges[2][1]=vertex[2][1];
edges[2][4]=vertex[1][1];
edges[2][2]=vertex[2][2];
edges[2][5]=vertex[1][2];
}
else
{
	m=0.0;
float slope=0.0;
slope=(float)(vertex[2][1]-vertex[0][1])/(float)(vertex[2][0]-vertex[0][0]);
midPoint= vertex[0][0]+( (vertex[1][1]-vertex[0][1])/slope );
if(midPoint<vertex[1][0])
{
//edge 0-2
edges[0][0]=vertex[0][0];
edges[0][3]=vertex[2][0];
edges[0][1]=vertex[0][1];
edges[0][4]=vertex[2][1];
edges[0][2]=vertex[0][2];
edges[0][5]=vertex[2][2];

//edge 2-1
edges[1][0]=vertex[2][0];
edges[1][3]=vertex[1][0];
edges[1][1]=vertex[2][1];
edges[1][4]=vertex[1][1];
edges[1][2]=vertex[2][2];
edges[1][5]=vertex[1][2];

//edge 1-0
edges[2][0]=vertex[1][0];
edges[2][3]=vertex[0][0];
edges[2][1]=vertex[1][1];
edges[2][4]=vertex[0][1];
edges[2][2]=vertex[1][2];
edges[2][5]=vertex[0][2];
}

else if(midPoint>vertex[1][0])
{
	m=0.0;
//edge 0-1
edges[0][0]=vertex[0][0];
edges[0][3]=vertex[1][0];
edges[0][1]=vertex[0][1];
edges[0][4]=vertex[1][1];
edges[0][2]=vertex[0][2];
edges[0][5]=vertex[1][2];

//edge 1-2
edges[1][0]=vertex[1][0];
edges[1][3]=vertex[2][0];
edges[1][1]=vertex[1][1];
edges[1][4]=vertex[2][1];
edges[1][2]=vertex[1][2];
edges[1][5]=vertex[2][2];

//edge 2-0
edges[2][0]=vertex[2][0];
edges[2][3]=vertex[0][0];
edges[2][1]=vertex[2][1];
edges[2][4]=vertex[0][1];
edges[2][2]=vertex[2][2];
edges[2][5]=vertex[0][2];
}
}

xDiffE0=edges[0][3]-edges[0][0];
xDiffE1=edges[1][3]-edges[1][0];
xDiffE2=edges[2][3]-edges[2][0];

yDiffE0=edges[0][4]-edges[0][1];
yDiffE1=edges[1][4]-edges[1][1];
yDiffE2=edges[2][4]-edges[2][1];

zDiffE0=edges[0][5]-edges[0][2];
zDiffE1=edges[1][5]-edges[1][2];
zDiffE2=edges[2][5]-edges[2][2];

//get coefficients of line
a0=yDiffE0;
a1=yDiffE1;
a2=yDiffE2;

b0=-xDiffE0;
b1=-xDiffE1;
b2=-xDiffE2;

c0=xDiffE0*edges[0][1] - yDiffE0*edges[0][0];
c1=xDiffE1*edges[1][1] - yDiffE1*edges[1][0];
c2=xDiffE2*edges[2][1] - yDiffE2*edges[2][0];

float temp=0.0;

//get Ax+By+Cz+D
A=yDiffE0*zDiffE1-yDiffE1*zDiffE0;
B=xDiffE1*zDiffE0-xDiffE0*zDiffE1;
C=xDiffE0*yDiffE1-xDiffE1*yDiffE0;
temp=A*edges[1][0] + B*edges[1][1] + C*edges[1][2];
D=-temp;
	
//construct bounding box
for(int i=0;i<3;i++)
	{
		m=0.0;
		float temp=0.0;
		if(vertex[i][0]<lowerX)
			lowerX=vertex[i][0];
		if(vertex[i][1]<lowerY)
			lowerY=vertex[i][1];
		temp=lowerY-lowerX;
		if(vertex[i][0]>upperX)
			upperX=vertex[i][0];
		if(vertex[i][1]>upperY)
			upperY=vertex[i][1];
	}
	
for(int i=lowerY;i<=upperY;i++)
{
for(int j=lowerX;j<=upperX;j++)
{
			float temp=0.0;
			v =-(A*j+B*i+D)/C;
			v0=a0*j+b0*i+c0;
			v1=a1*j+b1*i+c1;
			
			temp=a2*j+b1*i;
			temp=-temp/C;
			v2=a2*j+b2*i+c2;
			
			if(v<0||v0<0||v1<0||v2<0)
			continue;

			int ret=GzGetDisplay(render->display,j,i,&r,&g,&b,&a,&z);
			float q1,q2,q3;
			q1=render->flatcolor[0];
			q2=render->flatcolor[1];
			q3=render->flatcolor[2];
			if(z==0 || v < z)
			ret=GzPutDisplay(render->display,j,i,ctoi(q1),ctoi(q2),ctoi(q3),a,(GzDepth)v);
			
}
}
	
	
	
	
	return GZ_SUCCESS;
}
Пример #12
0
int GzPutTriangle(GzRender	*render, int numParts, GzToken *nameList, 
				  GzPointer	*valueList)
/* numParts : how many names and values */
{
/*  
- pass in a triangle description with tokens and values corresponding to 
      GZ_POSITION:3 vert positions in model space 
- Xform positions of verts  
- Clip - just discard any triangle with verts behind view plane // ALL OF THEM? or any one of them?
       - test for triangles with all three verts off-screen 
- invoke triangle rasterizer  
*/ 
	// error checking
	if (render == NULL) {
		return GZ_FAILURE;
	}
	if (nameList == NULL) {
		return GZ_FAILURE;
	}
	if (valueList == NULL) {
		return GZ_FAILURE;
	}

	// get Xsm
	if (render->matlevel > 0) {
		GzMatrix Xsm, temp;
		memcpy(Xsm, render->Ximage[0], sizeof(GzMatrix)); // copy first one 
		//copyMatrix(Xsm, render->Ximage[0]);
		for (int i = 1; i <= render->matlevel; ++i) {
			memcpy(temp, Xsm, sizeof(GzMatrix));
			//copyMatrix(temp, Xsm);
			Xsm[0][0] = temp[0][0]*render->Ximage[i][0][0] + temp[0][1]*render->Ximage[i][1][0]
						+ temp[0][2]*render->Ximage[i][2][0] + temp[0][3]*render->Ximage[i][3][0];
			Xsm[0][1] = temp[0][0]*render->Ximage[i][0][1] + temp[0][1]*render->Ximage[i][1][1]
						+ temp[0][2]*render->Ximage[i][2][1] + temp[0][3]*render->Ximage[i][3][1];
			Xsm[0][2] = temp[0][0]*render->Ximage[i][0][2] + temp[0][1]*render->Ximage[i][1][2]
						+ temp[0][2]*render->Ximage[i][2][2] + temp[0][3]*render->Ximage[i][3][2];
			Xsm[0][3] = temp[0][0]*render->Ximage[i][0][3] + temp[0][1]*render->Ximage[i][1][3]
						+ temp[0][2]*render->Ximage[i][2][3] + temp[0][3]*render->Ximage[i][3][3];
			/////
			Xsm[1][0] = temp[1][0]*render->Ximage[i][0][0] + temp[1][1]*render->Ximage[i][1][0]
						+ temp[1][2]*render->Ximage[i][2][0] + temp[1][3]*render->Ximage[i][3][0];
			Xsm[1][1] = temp[1][0]*render->Ximage[i][0][1] + temp[1][1]*render->Ximage[i][1][1]
						+ temp[1][2]*render->Ximage[i][2][1] + temp[1][3]*render->Ximage[i][3][1];
			Xsm[1][2] = temp[1][0]*render->Ximage[i][0][2] + temp[1][1]*render->Ximage[i][1][2]
						+ temp[1][2]*render->Ximage[i][2][2] + temp[1][3]*render->Ximage[i][3][2];
			Xsm[1][3] = temp[1][0]*render->Ximage[i][0][3] + temp[1][1]*render->Ximage[i][1][3]
						+ temp[1][2]*render->Ximage[i][2][3] + temp[1][3]*render->Ximage[i][3][3];
			////////////
			Xsm[2][0] = temp[2][0]*render->Ximage[i][0][0] + temp[2][1]*render->Ximage[i][1][0]
						+ temp[2][2]*render->Ximage[i][2][0] + temp[2][3]*render->Ximage[i][3][0];
			Xsm[2][1] = temp[2][0]*render->Ximage[i][0][1] + temp[2][1]*render->Ximage[i][1][1]
						+ temp[2][2]*render->Ximage[i][2][1] + temp[2][3]*render->Ximage[i][3][1];
			Xsm[2][2] = temp[2][0]*render->Ximage[i][0][2] + temp[2][1]*render->Ximage[i][1][2]
						+ temp[2][2]*render->Ximage[i][2][2] + temp[2][3]*render->Ximage[i][3][2];
			Xsm[2][3] = temp[2][0]*render->Ximage[i][0][3] + temp[2][1]*render->Ximage[i][1][3]
						+ temp[2][2]*render->Ximage[i][2][3] + temp[2][3]*render->Ximage[i][3][3];
			/////////////
			Xsm[3][0] = temp[3][0]*render->Ximage[i][0][0] + temp[3][1]*render->Ximage[i][1][0]
						+ temp[3][2]*render->Ximage[i][2][0] + temp[3][3]*render->Ximage[i][3][0];
			Xsm[3][1] = temp[3][0]*render->Ximage[i][0][1] + temp[3][1]*render->Ximage[i][1][1]
						+ temp[3][2]*render->Ximage[i][2][1] + temp[3][3]*render->Ximage[i][3][1];
			Xsm[3][2] = temp[3][0]*render->Ximage[i][0][2] + temp[3][1]*render->Ximage[i][1][2]
						+ temp[3][2]*render->Ximage[i][2][2] + temp[3][3]*render->Ximage[i][3][2];
			Xsm[3][3] = temp[3][0]*render->Ximage[i][0][3] + temp[3][1]*render->Ximage[i][1][3]
						+ temp[3][2]*render->Ximage[i][2][3] + temp[3][3]*render->Ximage[i][3][3];
		}
		// POP EVERYTHING
		for (int i = render->matlevel; i >= 0; --i) {
			GzPopMatrix(render);
		}
		// push on Xsm
		GzPushMatrix(render, Xsm);
	}

	// Get vert positions
	for (int i = 0; i < numParts; ++i) {
		if (nameList[i] == GZ_POSITION) {
			// get points
			GzCoord* tri = (GzCoord*) valueList[i];
			GzCoord* xformTri = new GzCoord[3];
			bool behindVP = false;
			GzMatrix topMat;
			int top = render->matlevel;
			memcpy(topMat, render->Ximage[top], sizeof(GzMatrix));
			//copyMatrix(topMat, render->xim
			float W;

			for (int j = 0; j < 3; ++j) {
				// xform verticies
				
				xformTri[j][X] = topMat[0][0]*tri[j][X] + topMat[0][1]*tri[j][Y] + topMat[0][2]*tri[j][Z]
					+ topMat[0][3]*1.0;
				xformTri[j][Y] = topMat[1][0]*tri[j][X] + topMat[1][1]*tri[j][Y] + topMat[1][2]*tri[j][Z]
					+ topMat[1][3]*1.0;
				xformTri[j][Z] = topMat[2][0]*tri[j][X] + topMat[2][1]*tri[j][Y] + topMat[2][2]*tri[j][Z]
					+ topMat[2][3]*1.0;
				W = topMat[3][0]*tri[j][X] + topMat[3][1]*tri[j][Y] + topMat[3][2]*tri[j][Z]
					+ topMat[3][3]*1;
				xformTri[j][X] /= W;
				xformTri[j][Y] /= W;
				xformTri[j][Z] /= W;
			
				// check if any vets in behind view plane
				if (xformTri[j][Z] < render->camera.position[Z]) {
					behindVP = true;
					break;
				}
			}
	//	float x0 = tri[0][X];
	//		float x1 = tri[1][X];
	//		float x2 = tri[2][X];
	//		float tx0 = xformTri[0][X];
	//		float tx1 = xformTri[1][X];
	//		float tx2 = xformTri[2][X];

	//		float y0 = tri[0][Y];
	//		float y1 = tri[1][Y];
	//		float y2 = tri[2][Y];
	//		float ty0 = xformTri[0][Y];
	//		float ty1 = xformTri[1][Y];
	//		float ty2 = xformTri[2][Y];

	//		float z0 = tri[0][Z];
	//		float z1 = tri[1][Z];
	//		float z2 = tri[2][Z];
	//		float tz0 = xformTri[0][Z];
	//		float tz1 = xformTri[1][Z];
	//		float tz2 = xformTri[2][Z];

			// this tri is in front of viewing plane
			if (behindVP == true) {
				break;
			}
			// CLIPPING
			//if (xformTri[0][Z] < render->camera.position[Z] 
			//	&& xformTri[1][Z] < render->camera.position[Z]
			//	&& xformTri[2][Z] < render->camera.position[Z]) {
			//	break;
			//}

			//if ((xformTri[0][X] < 0 && xformTri[1][

			// check if all verts are in screen (think i handle this in my rasterizer)
			// RASTERIZE
			// sort by Y
			int minY = 0;
			for (int i = 0; i < 2; ++i) {
				minY = i;
				for (int j = i + 1; j < 3; ++j) {
					if (xformTri[minY][Y] > xformTri[j][Y]) {
						minY = j;
					}
				}
				// swapping
				if (minY != i) {
					float tempX = xformTri[i][X];
					float tempY = xformTri[i][Y];
					float tempZ = xformTri[i][Z];
					xformTri[i][X] = xformTri[minY][X];
					xformTri[i][Y] = xformTri[minY][Y];
					xformTri[i][Z] = xformTri[minY][Z];
					xformTri[minY][X] = tempX;
					xformTri[minY][Y] = tempY;
					xformTri[minY][Z] = tempZ;
				}
			}


			// Get bounding box
			int topY = floor(xformTri[0][Y]);
			int bottomY = ceil(xformTri[2][Y]);
			int leftX, rightX;
			// 0 comes before 1
			if (xformTri[0][X] < xformTri[1][X]) {
				// 201
				if (xformTri[2][X] < xformTri[0][X]) {
					leftX = floor(xformTri[2][X]);
					rightX = ceil(xformTri[1][X]);
				} else { //0
					leftX = floor(xformTri[0][X]);
					// 021
					if (xformTri[2][X] < xformTri[1][X]) {
						rightX = ceil(xformTri[1][X]);
					} else { // 012
						rightX = ceil(xformTri[2][X]);
					}
				}
			} else { // 1 comes before 0
				//210
				if (xformTri[2][X] < xformTri[1][X]) {
					leftX = floor(xformTri[2][X]);
					rightX = ceil(xformTri[0][X]);
				} else { //1
					leftX = floor(xformTri[1][X]);
					// 120
					if (xformTri[2][X] < xformTri[0][X]) {
						rightX = ceil(xformTri[0][X]);
					} else { // 102
						rightX = ceil(xformTri[2][X]);
					}
				}
			}

			// For Z Interpolation
			// Ax + By + Cz + D = 0;
			// xformTri[0] x xformTri[1] = (A, B, C)
			GzCoord edge01;
			edge01[X] = xformTri[1][X]- xformTri[0][X];
			edge01[Y] = xformTri[1][Y] - xformTri[0][Y];
			edge01[Z] = xformTri[1][Z] - xformTri[0][Z];
			GzCoord edge12;
			edge12[X] = xformTri[2][X] - xformTri[1][X];
			edge12[Y] = xformTri[2][Y] - xformTri[1][Y];
			edge12[Z] = xformTri[2][Z] - xformTri[1][Z];

			float A = edge01[Y]*edge12[Z] - edge01[Z]*edge12[Y];
			float B = edge01[Z]*edge12[X] - edge01[X]*edge12[Z];
			float C = edge01[X]*edge12[Y] - edge01[Y]*edge12[X];
			// get D
			float D = -(A*xformTri[0][X]) - (B*xformTri[0][Y]) - (C*xformTri[0][Z]);

			// DRAW PIXELS
			float interpZ;
			for (int i = leftX; i < rightX; ++i) {
				// bounds check
				if (i < 0 || i > render->display->xres) {
					continue;
				}
				for (int j = topY; j < bottomY; ++j) {
					//// bounds check
					if (j < 0 || j > render->display->yres) {
						continue;
					}

					// Compute LEES
					// E(x, y) = dY(x-X) - dX(y-Y)
					// EDGE 0-1
					float e01 = (xformTri[1][Y] - xformTri[0][Y])*((float)i - xformTri[0][X]) 
								- (xformTri[1][X] - xformTri[0][X])*((float)j - xformTri[0][Y]);
					// EDGE 1-2
					float e12 = (xformTri[2][Y] - xformTri[1][Y])*((float)i - xformTri[1][X]) 
								- (xformTri[2][X] - xformTri[1][X])*((float)j - xformTri[1][Y]);
					// EDGE 2-0
					float e20 = (xformTri[0][Y] - xformTri[2][Y])*((float)i - xformTri[2][X]) 
								- (xformTri[0][X] - xformTri[2][X])*((float)j - xformTri[2][Y]);

					// if all have same sign then this pixel should be drawn
					if (e01 == 0 || e12 == 0 || e20 == 0) {
						interpZ = (-(A*i) - (B*j) - D) / C;

						// get current z at this pixel
						GzIntensity r, g, b, a;
						GzDepth z = 0;
						GzGetDisplay(render->display, i, j, &r, &g, &b, &a, &z);
						// compare, if interpZ less than draw over
						if (interpZ < z) {
							r = (GzIntensity ) ctoi((float) render->flatcolor[0]);
							g = (GzIntensity ) ctoi((float)render->flatcolor[1]);
							b = (GzIntensity ) ctoi((float)render->flatcolor[2]);
							z = interpZ;
							GzPutDisplay(render->display, i, j, r, g, b, a, z);
						}
					}
					else if ( ((e01 > 0) && (e12 > 0) && (e20 > 0)) || ((e01 < 0) && (e12 < 0) && (e20 < 0))) {
						//(e01 == 0 && e12 == 0 && e20 == 0) 
						// Interpolate Z value
						interpZ = (-(A*i) - (B*j) - D) / C;

						// get current z at this pixel
						GzIntensity r, g, b, a;
						GzDepth z = 0;
						GzGetDisplay(render->display, i, j, &r, &g, &b, &a, &z);
						// compare, if interpZ less than draw over
						if (interpZ < z) {
							r = (GzIntensity ) ctoi((float) render->flatcolor[0]);
							g = (GzIntensity ) ctoi((float)render->flatcolor[1]);
							b = (GzIntensity ) ctoi((float)render->flatcolor[2]);
							z = interpZ;
							GzPutDisplay(render->display, i, j, r, g, b, a, z);
						}

					}

				}
			} 

		}
	}

	return GZ_SUCCESS;
}
Пример #13
0
int GzPutTriangle(GzRender	*render, int numParts, GzToken *nameList, 
				  GzPointer	*valueList)
/* numParts : how many names and values */
{
/*  
- pass in a triangle description with tokens and values corresponding to 
      GZ_POSITION:3 vert positions in model space 
- Xform positions of verts  
- Clip - just discard any triangle with verts behind view plane 
       - test for triangles with all three verts off-screen 
- invoke triangle rasterizer  
*/ 

	if(nameList[0]==GZ_POSITION)
	{
			int status=0;
			GzIntensity red,green,blue,alpha;
			GzDepth z=INT_MAX;
			GzCoord v[3],n[3],edge,edge10,edge21,point,nrml,nrml21,nrmlpoint;
			int inside;
			float intz;
			for(int i=0;i<3;i++)
				for(int j=0;j<3;j++)
					v[i][j]=((GzCoord*)valueList[0])[i][j];

			float Xformvert[4];
			for(int i=0; i<3; i++)
			{
				float vert4d[4] = {v[i][0],v[i][1],v[i][2],1};
				for(int j=0; j<4; j++)
				{
					Xformvert[j]=0;
					for(int k=0;k<4;k++)
					Xformvert[j]+=(render->Ximage[render->matlevel][j][k]*vert4d[k]);
				}
				v[i][0] = Xformvert[0]/Xformvert[3];
				v[i][1] = Xformvert[1]/Xformvert[3];
				v[i][2] = Xformvert[2]/Xformvert[3];
			}

			for(int i=0;i<3;i++)
				for(int j=0;j<3;j++)
					n[i][j]=((GzCoord*)valueList[1])[i][j];

			float Xformnorm[4];
			for(int i=0; i<3; i++)
			{
				float norm4d[4] = {n[i][0],n[i][1],n[i][2],1};
				for(int j=0; j<4; j++)
				{
					Xformnorm[j]=0;
					for(int k=0;k<4;k++)
						Xformnorm[j]+=(render->Xnorm[render->matlevel][j][k]*norm4d[k]);
				}
				n[i][0] = Xformnorm[0]/Xformnorm[3];
				n[i][1] = Xformnorm[1]/Xformnorm[3];
				n[i][2] = Xformnorm[2]/Xformnorm[3];
			}



			float xmax, xmin, ymax, ymin;
			ymin=xmin=INT_MAX;
			ymax=xmax=0;
						for(int i=0;i<3;i++)
					{	if(v[i][0]<xmin)
							xmin=v[i][0];
						if(v[i][0]>xmax)
							xmax=v[i][0];
						if(v[i][1]<ymin)
							ymin=v[i][1];
						if(v[i][1]>ymax)
							ymax=v[i][1];
					}
		
			
			edge10[0] = v[1][0] - v[0][0];
			edge10[1] = v[1][1] - v[0][1];
			edge10[2] = v[1][2] - v[0][2];

			edge21[0] = v[2][0] - v[1][0];
			edge21[1] = v[2][1] - v[1][1];
			edge21[2] = v[2][2] - v[1][2];
			crossproduct(edge21, edge10, nrml21);

			edge10[2] = 0;
			edge21[2] = 0;
			crossproduct(edge21, edge10, nrml);

			float A, B, C, D;
		
			A = nrml21[0];
			B = nrml21[1];
			C = nrml21[2];
			D = -(A*v[1][0] + B*v[1][1] + C*v[1][2]);

			GzCoord E,colorsA,colorsB,colorsC,colorsD,color[3];
			GzCoord normA,normB,normC,normD;
			
			E[0] = 0;
			E[1] = 0;
			E[2] =-1;

			for(int i=0;i<3;i++)
			{
			  GzCoord tempcolor;
			  GzCoord tempnormal;

			  for(int j=0;j<3;j++)
			  	tempnormal[j]=n[i][j];
				
				computecolor(render,E,tempnormal,tempcolor);
			  for(int j=0;j<3;j++)	
				color[i][j]=tempcolor[j];
			  
			}

			if(render->interp_mode == GZ_COLOR)
			{
				GzCoord colornormal[3];
				for(int i=0; i<3; i++)
				{
					edge10[2] = color[1][i] - color[0][i];
					edge21[2] = color[2][i] - color[1][i];				
					crossproduct(edge21, edge10, colornormal[i]);
					colorsA[i] = colornormal[i][0];
					colorsB[i] = colornormal[i][1];
					colorsC[i] = colornormal[i][2];
					colorsD[i] = -(colorsA[i]*v[0][0] + colorsB[i]*v[0][1] + colorsC[i]*color[0][i]);
				}
			}
			
			else if(render->interp_mode == GZ_NORMALS)
			{				
				GzCoord interN[3];
				for(int i=0; i<3; i++)
				{
					edge10[2] = n[1][i]-n[0][i];
					edge21[2] = n[2][i]-n[1][i];				
					crossproduct(edge21,edge10,interN[i]);
					normA[i] = interN[i][0];
					normB[i] = interN[i][1];
					normC[i] = interN[i][2];
					normD[i] = -(normA[i]*v[0][0] + normB[i]*v[0][1] + normC[i]*n[0][i]);
				}
			}
			for(int x=floor(xmin);x<=ceil(xmax) && x<(render->display->xres);x++)
			{
				if(x<0)
					x=0;
				for(int y=floor(ymin);y<=ceil(ymax) && y<(render->display->yres);y++)
				{
					if(y<0)
						y=0;							
					inside=0;
					
					for(int i=0; i<3; i++)
					{	
						edge[0] = v[(i+1)%3][0] - v[i][0];
						edge[1] = v[(i+1)%3][1] - v[i][1];
						edge[2] = 0;

						point[0] = v[(i+1)%3][0] - x;
						point[1] = v[(i+1)%3][1] - y;
						point[2] = 0;

						crossproduct(edge, point, nrmlpoint);
						
						float cond = dotproduct(nrml,nrmlpoint);

						if(cond > 0)		
							inside=inside+1;
						else
							break;
					}
					if(inside==3)
					{
						intz = -(A*x+B*y+D)/C;
						status=GzGetDisplay(render->display,x,y,&red,&green,&blue,&alpha,&z);
						if(intz<z)
						{	GzCoord tempcolor;
							if(render->interp_mode==GZ_NORMALS)
							{	GzCoord intnormal;
								for(int i=0;i<3;i++)
									intnormal[i]=-(normA[i]*x + normB[i]*y + normD[i])/normC[i];
								normalize(intnormal);
								computecolor(render,E,intnormal,tempcolor);
							}
							
							else if(render->interp_mode==GZ_COLOR)
							{
								for(int i=0;i<3;i++)
								tempcolor[i]=-(colorsA[i]*x+colorsB[i]*y+colorsD[i])/colorsC[i];
							}
							status=GzPutDisplay(render->display,x,y,ctoi(tempcolor[0]),ctoi(tempcolor[1]),ctoi(tempcolor[2]),1,intz);
						}
					}
				}
			}				
	}
		
	return GZ_SUCCESS;
}
Пример #14
0
int GzPutTriangle(GzRender	*render, int numParts, GzToken *nameList, 
				  GzPointer	*valueList)
/* numParts : how many names and values */
{
/*  
- pass in a triangle description with tokens and values corresponding to 
      GZ_POSITION:3 vert positions in model space 
- Xform positions of verts  
- Clip - just discard any triangle with verts behind view plane 
       - test for triangles with all three verts off-screen 
- invoke triangle rasterizer  
*/ 


	if (render == NULL){
		return GZ_FAILURE;
	}
	for (int i = 0; i < numParts; i++){
		if (nameList[i] == GZ_NULL_TOKEN){
			return GZ_FAILURE;
		}
		if (nameList[i] == GZ_POSITION){
			float* vertices = (float*)valueList[0];
			float x1 = *(vertices);
			float y1 = *(vertices + 1);
			float z1 = *(vertices + 2);
			float x2 = *(vertices + 3);
			float y2 = *(vertices + 4);
			float z2 = *(vertices + 5);
			float x3 = *(vertices + 6);
			float y3 = *(vertices + 7);
			float z3 = *(vertices + 8);

			//homogeneous matrix

			float coord_x[4], coord_y[4], coord_z[4];
			
			coord_x[0] = x1;
			coord_x[1] = y1;
			coord_x[2] = z1;
			coord_x[3] = 1;

			coord_y[0] = x2;
			coord_y[1] = y2;
			coord_y[2] = z2;
			coord_y[3] = 1;

			coord_z[0] = x3;
			coord_z[1] = y3;
			coord_z[2] = z3;
			coord_z[3] = 1;

			float resultant_x[4][1], resultant_y[4][1],resultant_z[4][1];

			for (int i = 0; i < 4; i++){
				resultant_x[i][0] = 0;
				for (int j = 0; j < 4; j++){
					resultant_x[i][0] = resultant_x[i][0] + ((render->Ximage[render->matlevel][i][j]) * coord_x[j]);
				}
			}

			for (int i = 0; i < 4; i++){
				resultant_y[i][0] = 0;
				for (int j = 0; j < 4; j++){
					resultant_y[i][0] = resultant_y[i][0] + ((render->Ximage[render->matlevel][i][j]) * coord_y[j]);
				}
			}

			for (int i = 0; i < 4; i++){
				resultant_z[i][0] = 0;
				for (int j = 0; j < 4; j++){
					resultant_z[i][0] = resultant_z[i][0] + ((render->Ximage[render->matlevel][i][j]) * coord_z[j]);
				}
			}

			GzCoord x, y, z;
			x[X] = resultant_x[0][0] / resultant_x[3][0];
			x[Y] = resultant_y[0][0] / resultant_y[3][0];
			x[Z] = resultant_z[0][0] / resultant_z[3][0];
			
			y[X] = resultant_x[1][0] / resultant_x[3][0];
			y[Y] = resultant_y[1][0] / resultant_y[3][0];
			y[Z] = resultant_z[1][0] / resultant_z[3][0];

			z[X] = resultant_x[2][0] / resultant_x[3][0];
			z[Y] = resultant_y[2][0] / resultant_y[3][0];
			z[Z] = resultant_z[2][0] / resultant_z[3][0];
		

				// clipping part

			if ((x[X] < 0 || x[X] > (render->display->xres)) && (x[Y] < 0 || x[Y] > (render->display->xres)) && (x[Z] < 0 || x[Z] > (render->display->xres))){
				return GZ_FAILURE;

			}

			if ((y[X] < 0 || y[X] > (render->display->yres)) && (y[Y] < 0 || y[Y] > (render->display->yres)) && (y[Z] < 0 || y[Z] > (render->display->yres))){
				return GZ_FAILURE;

			}
			
			if (z[X] < 0 && z[Y] < 0 && z[Z] < 0){
				return GZ_FAILURE;

			}

			GzCoord tempx = { x1, x2, x3 };
			float y_min, y_max;
			sort_on_y(x, y, z);		//sort on y 
			y_min = y[0];			// find minimum y for boundary box
			y_max = y[2];			// find maximum y for boundary box
			float tmp;

			if ((y[1] == y[0]) || (x[1] < x[0]))
			{
				tmp = x[0];
				x[0] = x[1];
				x[1] = tmp;

				tmp = y[0];
				y[0] = y[1];
				y[1] = tmp;

				tmp = z[0];
				z[0] = z[1];
				z[1] = tmp;

			}

			else if ((y[1] == y[2]) || (x[1] > x[2])){
				tmp = x[1];
				x[1] = x[2];
				x[2] = tmp;

				tmp = y[1];
				y[1] = y[2];
				y[2] = tmp;

				tmp = z[1];
				z[1] = z[2];
				z[2] = tmp;

			}

			float coefA = (y[2] - y[0]);
			float coefB = -(x[2] - x[0]);
			float coefC = (-coefB*y[0]) - (coefA * x[0]);

			float xx1 = (-coefB*y[1] - coefC) / coefA;
			if (xx1 < x[1]){
				tmp = y[2];
				y[2] = y[1];
				y[1] = tmp;

				tmp = x[2];
				x[2] = x[1];
				x[1] = tmp;

				tmp = z[2];
				z[2] = z[1];
				z[1] = tmp;
			}


			// find minimum  and maximum x for boundary box
			float x_min, x_max;

			if (x[0] < x[1] && x[0] < x[2]){
				x_min = x[0];

			}
			else{
				if (x[1] < x[2] && x[1] < x[0]){
					x_min = x[1];
				}
				else{
					x_min = x[2];
				}
			}


			if (x[0] > x[1] && x[0] > x[2]){
				x_max = x[0];

			}
			else{
				if (x[1] > x[2] && x[1] > x[0]){
					x_max = x[1];
				}
				else{
					x_max = x[2];
				}
			}

			//check boundary conditions

			if (x_min < 0){
				x_min = 0;

			}
			if (x_min > 255){
				x_min = 255;

			}
			if (x_max < 0){
				x_max = 0;

			}
			if (x_max > 255){
				x_max = 255;

			}
			if (y_min < 0){
				y_min = 0;

			}
			if (y_min > 255){
				y_min = 255;

			}
			if (y_max < 0){
				y_max = 0;

			}
			if (y_max > 255){
				y_max = 255;

			}



			float coefA1 = (y[1] - y[0]);
			float coefA2 = (y[2] - y[1]);
			float coefA3 = (y[0] - y[2]);

			float coefB1 = -(x[1] - x[0]);
			float coefB2 = -(x[2] - x[1]);
			float coefB3 = -(x[0] - x[2]);

			float coefC1 = ((-(coefB1)*y[1]) - (coefA1 * x[1]));
			float coefC2 = ((-(coefB2)*y[2]) - (coefA2 * x[2]));
			float coefC3 = ((-(coefB3)*y[0]) - (coefA3 * x[0]));
			float d1, d2, d3;

			float A, B, C, D;
			float x11, x22, y11, y22, z11, z22;
			x11 = (x[1] - x[0]);
			y11 = (y[1] - y[0]);
			z11 = (z[1] - z[0]);
			x22 = (x[2] - x[0]);
			y22 = (y[2] - y[0]);
			z22 = (z[2] - z[0]);
			A = ((y11*z22) - (y22*z11));
			B = ((x22*z11) - (x11*z22));
			C = ((x11*y22) - (x22*y11));
			D = ((y[0] * (B)) + (x[0] * (A)) + (z[0] * (C))) * (-1);

			int z_inter = 0;

			for (int i = floor(x_min); i < ceil(x_max); i++){
				for (int j = floor(y_min); j < ceil(y_max); j++){
					d1 = (coefA1*i) + (coefB1*j) + coefC1;
					d2 = (coefA2*i) + (coefB2*j) + coefC2;
					d3 = (coefA3*i) + (coefB3*j) + coefC3;
					z_inter = -(A*i + B*j + D) / C;

					if (!(d1 < 0 || d2 < 0 || d3 < 0)){
						GzIntensity a, b, c, d;
						GzDepth z;
						GzGetDisplay(render->display, i, j, &a, &b, &c, &d, &z);
						if (z_inter < z || z == 0)
						{
							GzPutDisplay(render->display, i, j, ctoi(render->flatcolor[RED]), ctoi(render->flatcolor[GREEN]), ctoi(render->flatcolor[BLUE]), a, z_inter);
						}
					}
				}
			}
		}
	}
	return GZ_SUCCESS;
}
int GzPutTriangle(GzRender *render, int	numParts, GzToken *nameList,
                  GzPointer *valueList)
/* numParts - how many names and values */
{
    /*
    - pass in a triangle description with tokens and values corresponding to
          GZ_NULL_TOKEN:		do nothing - no values
          GZ_POSITION:		3 vert positions
    - Invoke the scan converter and return an error code
    */
    if (NULL != nameList && NULL != render && NULL != valueList)
    {

        int nLowestY = 0;

        for (int i = 0; i < numParts; i++)
        {
            if (nameList[i] == GZ_POSITION)
            {
                // get points
                GzCoord* gzPoints = (GzCoord*)valueList[i];

                // sort the vertices by Y using bubble sort technique
                for (int i = 0; i <= 1; i++)
                {
                    nLowestY = i;
                    for (int j = i + 1; j <= 2; j++)
                    {
                        if (gzPoints[nLowestY][Y] > gzPoints[j][Y])
                        {
                            nLowestY = j;
                        }
                    }

                    if (nLowestY != i)
                    {
                        SwapVertices(gzPoints, nLowestY, i);
                    }
                }

                if (gzPoints[0][Y] == gzPoints[1][Y])
                {
                    if (gzPoints[0][X] > gzPoints[1][X])
                    {
                        SwapVertices(gzPoints, 0, 1);
                    }
                }

                else if (gzPoints[1][Y] == gzPoints[2][Y])
                {
                    if (gzPoints[1][X] < gzPoints[2][X])
                    {
                        SwapVertices(gzPoints, 2, 1);
                    }
                }

                // Find two Edges of the triangle to compute the normal vector
                GzCoord Triedge12;
                Triedge12[X] = gzPoints[1][X] - gzPoints[0][X];
                Triedge12[Y] = gzPoints[1][Y] - gzPoints[0][Y];
                Triedge12[Z] = gzPoints[1][Z] - gzPoints[0][Z];

                GzCoord Triedge23;
                Triedge23[X] = gzPoints[2][X] - gzPoints[1][X];
                Triedge23[Y] = gzPoints[2][Y] - gzPoints[1][Y];
                Triedge23[Z] = gzPoints[2][Z] - gzPoints[1][Z];

                // compute the normal vector by doing the cross product of two edges
                float fOutvectorX = Triedge12[Y] * Triedge23[Z] - Triedge12[Z] * Triedge23[Y];
                float fOutvectorY = Triedge12[Z] * Triedge23[X] - Triedge12[X] * Triedge23[Z];
                float fOutvectorZ = Triedge12[X] * Triedge23[Y] - Triedge12[Y] * Triedge23[X];

                //Ax + By + Cz + D = 0   ------- [1]
                float D = -(fOutvectorX * gzPoints[0][X]) - (fOutvectorY * gzPoints[0][Y]) - (fOutvectorZ *	gzPoints[0][Z]);

                int nLeft = 0, nRight = 0;
                GetBoundingBoxWidth(nLeft, nRight, gzPoints);

                // get the T/B from the sorted Y vertices
                int nTop = (int)floor(gzPoints[0][Y]);
                int nBottom = (int)ceil(gzPoints[2][Y]);

                float interpolatedZ = 0.0f;
                // for each pixel(x,y) in the bounding box evaluate equation [1]
                for (int x = nLeft; x < nRight; x++)
                {
                    for (int y = nTop; y < nBottom; y++)
                    {
                        float Edge12 = 0.0f, Edge23 = 0.0f, Edge31 = 0.0f;

                        Edge12 = (gzPoints[1][Y] - gzPoints[0][Y])*((float)x - gzPoints[0][X]) - (gzPoints[1][X] - gzPoints[0][X])*((float)y - gzPoints[0][Y]);

                        Edge23 = (gzPoints[2][Y] - gzPoints[1][Y])*((float)x - gzPoints[1][X]) - (gzPoints[2][X] - gzPoints[1][X])*((float)y - gzPoints[1][Y]);

                        Edge31 = (gzPoints[0][Y] - gzPoints[2][Y])*((float)x - gzPoints[2][X]) - (gzPoints[0][X] - gzPoints[2][X])*((float)y - gzPoints[2][Y]);

                        if (((Edge12 > 0) && (Edge23 > 0) && (Edge31 > 0)) || ((Edge12 < 0) && (Edge23 < 0) && (Edge31 < 0))
                                || (Edge12 == 0 || Edge23 == 0 || Edge31 == 0))
                        {
                            // Z - buffer to remove hidden surfaces
                            interpolatedZ = (- (fOutvectorX * x) - (fOutvectorY * y) - D) / fOutvectorZ;
                            GzDepth zCurrentValFb = 0;
                            GzIntensity red   = 0;
                            GzIntensity green = 0;
                            GzIntensity blue  = 0;
                            GzIntensity alpha = 0;

                            // get the current values from the frambuffer
                            GzGetDisplay(render->display, x, y, &red, &green, &blue, &alpha, &zCurrentValFb);

                            // Compare between computed Zpix versus framebuffer Z value. If lesser write new pixel color, else dont do anything
                            if (interpolatedZ < zCurrentValFb)
                            {
                                zCurrentValFb = interpolatedZ;

                                red   = (GzIntensity)ctoi((float)render->flatcolor[Red]);
                                green = (GzIntensity)ctoi((float)render->flatcolor[Green]);
                                blue  = (GzIntensity)ctoi((float)render->flatcolor[Blue]);

                                //Writing new pixel value to the framebuffer
                                GzPutDisplay(render->display, x, y, red, green, blue, alpha, zCurrentValFb);
                            }
                        }
                    }
                }
            }

            if (nameList[i] == GZ_NULL_TOKEN)
            {
                //Do nothing
                continue;
            }
        }
        return GZ_SUCCESS;
    }

    else
    {
        return GZ_FAILURE;
    }

}
int Gz_LEE_Rasterization(GzRender *render, GzCoord vertex[3])
{
	GzIntensity Red, Green, Blue, alpha;

	//bubble sort

	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 2; j++)
		{
			if (vertex[j][Y] > vertex[j + 1][Y])
			{
				Gz_Swap_Vertex(vertex[j], vertex[j + 1]);
			}
		}
	}
	//I think there is no need to do clockwise, because I can use +/- common area 
	//Gz_Make_CW(vertex[0], vertex[1], vertex[2]);

	//After the CW, vectors and a rectangle enclousing the triangle in 2D map

	GzCoord Vector_1_to_2;
	GzCoord Vector_2_to_3;
	GzCoord Vector_3_to_1;

	Vector_1_to_2[X] = vertex[1][X] - vertex[0][X];
	Vector_1_to_2[Y] = vertex[1][Y] - vertex[0][Y];
	Vector_1_to_2[Z] = vertex[1][Z] - vertex[0][Z];

	Vector_2_to_3[X] = vertex[2][X] - vertex[1][X];
	Vector_2_to_3[Y] = vertex[2][Y] - vertex[1][Y];
	Vector_2_to_3[Z] = vertex[2][Z] - vertex[1][Z];

	Vector_3_to_1[X] = vertex[0][X] - vertex[2][X];
	Vector_3_to_1[Y] = vertex[0][Y] - vertex[2][Y];
	Vector_3_to_1[Z] = vertex[0][Z] - vertex[2][Z];
	//We use + area in this 3 vectors!
	//Because the coords may not be integer! But pixels are at integers! X grows right, Y grows down.
	int Xmin = floor(Find_x_min(vertex));
	int Xmax = ceil(Find_x_max(vertex));

	int Ymin = floor(vertex[0][Y]);
	int Ymax = ceil(vertex[2][Y]);

	//Calculate the Ax+By+Cz+D=0 A B C D use vectors

	float A;
	float B;
	float C;
	float D;

	A = Vector_1_to_2[Y] * (-Vector_3_to_1[Z]) - (-Vector_3_to_1[Y]) * Vector_1_to_2[Z];
	B = Vector_1_to_2[Z] * (-Vector_3_to_1[X]) - (-Vector_3_to_1[Z]) * Vector_1_to_2[X];
	C = Vector_1_to_2[X] * (-Vector_3_to_1[Y]) - (-Vector_3_to_1[X]) * Vector_1_to_2[Y];
	D = -(A * vertex[0][X] + B * vertex[0][Y] + C * vertex[0][Z]);

	//Scan the pixels and draw!
	float Pixel_z;
	for (int i = Xmin; i <= Xmax; i++)
	{
		if (i < 0 || i > render->display->xres)
			continue;
		for (int j = Ymin; j <= Ymax; j++)
		{
			if (j < 0 || j > render->display->yres)
				continue;

			Pixel_z = -(A * i + B * j + D) / C;
			GzDepth tempz = 0;  //get z from getdisplay
			/*
			Put point into the line fuctions: E1(x,y) E2(x,y) E3(x,y) the relationship with vectors in 2D map
			*/
			float Relationship_with_1_to_2 = Vector_1_to_2[Y] * (i - vertex[0][X]) - Vector_1_to_2[X] * (j - vertex[0][Y]);
			float Relationship_with_2_to_3 = Vector_2_to_3[Y] * (i - vertex[1][X]) - Vector_2_to_3[X] * (j - vertex[1][Y]);
			float Relationship_with_3_to_1 = Vector_3_to_1[Y] * (i - vertex[2][X]) - Vector_3_to_1[X] * (j - vertex[2][Y]);

			if (Relationship_with_1_to_2 == 0 || Relationship_with_2_to_3 == 0 || Relationship_with_3_to_1 == 0)
			{
				//one the line!
				GzGetDisplay(render->display, i, j, &Red, &Green, &Blue, &alpha, &tempz);
				if (Pixel_z < tempz)
				{
					Red = ctoi(render->flatcolor[0]);
					Green = ctoi(render->flatcolor[1]);
					Blue = ctoi(render->flatcolor[2]);
					GzPutDisplay(render->display, i, j, Red, Green, Blue, alpha, Pixel_z);
				}
			}
			else if ((Relationship_with_1_to_2 > 0 && Relationship_with_2_to_3 > 0 && Relationship_with_3_to_1 > 0) || (Relationship_with_1_to_2 < 0 && Relationship_with_2_to_3 < 0 && Relationship_with_3_to_1 < 0))
			{

				GzGetDisplay(render->display, i, j, &Red, &Green, &Blue, &alpha, &tempz);

				if (Pixel_z < tempz)
				{
					Red = ctoi(render->flatcolor[0]);
					Green = ctoi(render->flatcolor[1]);
					Blue = ctoi(render->flatcolor[2]);
					GzPutDisplay(render->display, i, j, Red, Green, Blue, alpha, Pixel_z);
				}
			}
		}
	}
	return GZ_SUCCESS;
}
Пример #17
0
int GzPutTriangle(GzRender *render, int	numParts, GzToken *nameList,
	GzPointer *valueList)
	/* numParts - how many names and values */
{
	/*
	- pass in a triangle description with tokens and values corresponding to
	GZ_NULL_TOKEN:		do nothing - no values
	GZ_POSITION:		3 vert positions
	- Invoke the scan converter and return an error code
	*/
	if ((NULL == render) || (NULL == nameList) || (NULL == valueList))
	{
		return GZ_FAILURE;
	}
	for (int nCnt = 0; nCnt < numParts; nCnt++)
	{
		if (nameList[nCnt] == GZ_POSITION)
		{
			GzCoord* acGzCoord;
			acGzCoord = (GzCoord*)(valueList[nCnt]);
			GzCoord asGzCoordX = { acGzCoord[0][0], acGzCoord[1][0], acGzCoord[2][0] };
			GzCoord asGzCoordY = { acGzCoord[0][1], acGzCoord[1][1], acGzCoord[2][1] };
			GzCoord asGzCoordZ = { acGzCoord[0][2], acGzCoord[1][2], acGzCoord[2][2] };
			//Sort the matrix according to Y
			for (int anSortYCnt = 1; anSortYCnt < 3; anSortYCnt++)
			{
				if (asGzCoordY[anSortYCnt - 1] > asGzCoordY[anSortYCnt])
				{
					float afSortTemmp;
					afSortTemmp = asGzCoordX[anSortYCnt - 1];
					asGzCoordX[anSortYCnt - 1] = asGzCoordX[anSortYCnt];
					asGzCoordX[anSortYCnt] = afSortTemmp;
					afSortTemmp = asGzCoordY[anSortYCnt - 1];
					asGzCoordY[anSortYCnt - 1] = asGzCoordY[anSortYCnt];
					asGzCoordY[anSortYCnt] = afSortTemmp;
					afSortTemmp = asGzCoordZ[anSortYCnt - 1];
					asGzCoordZ[anSortYCnt - 1] = asGzCoordZ[anSortYCnt];
					asGzCoordZ[anSortYCnt] = afSortTemmp;
				}
			}
			float afGzCoordY_Min = asGzCoordY[0];			// find min y 
			float afGzCoordY_Max = asGzCoordY[2];			// find max y
			float tmp;
			for (int anSortYCnt = 1; anSortYCnt < 3; anSortYCnt++)
			{
				if ((asGzCoordY[anSortYCnt - 1] == asGzCoordY[anSortYCnt]) && (asGzCoordX[anSortYCnt - 1] > asGzCoordX[anSortYCnt]))
				{
					float afSortTemmp;
					afSortTemmp = asGzCoordX[anSortYCnt - 1];
					asGzCoordX[anSortYCnt - 1] = asGzCoordX[anSortYCnt];
					asGzCoordX[anSortYCnt] = afSortTemmp;
					afSortTemmp = asGzCoordY[anSortYCnt - 1];
					asGzCoordY[anSortYCnt - 1] = asGzCoordY[anSortYCnt];
					asGzCoordY[anSortYCnt] = afSortTemmp;
					afSortTemmp = asGzCoordZ[anSortYCnt - 1];
					asGzCoordZ[anSortYCnt - 1] = asGzCoordZ[anSortYCnt];
					asGzCoordZ[anSortYCnt] = afSortTemmp;
				}
			}
			float afCoefA = asGzCoordY[2] - asGzCoordY[0];
			float afCoefB = asGzCoordX[0] - asGzCoordX[2];
			float afCoefC = -afCoefB*asGzCoordY[0] - afCoefA * asGzCoordX[0];
			float acTestX = -(afCoefB*asGzCoordY[1] + afCoefC) / afCoefA;
			if (acTestX < asGzCoordX[1])
			{
				tmp = asGzCoordY[2];
				asGzCoordY[2] = asGzCoordY[1];
				asGzCoordY[1] = tmp;
				tmp = asGzCoordX[2];
				asGzCoordX[2] = asGzCoordX[1];
				asGzCoordX[1] = tmp;
				tmp = asGzCoordZ[2];
				asGzCoordZ[2] = asGzCoordZ[1];
				asGzCoordZ[1] = tmp;
			}
			//find the max and min for X and Y
			float afMaxX, afMinX, afMaxY, afMinY;
			afMaxX = asGzCoordX[0];
			afMinX = asGzCoordX[0];
			afMaxY = asGzCoordY[0];
			afMinY = asGzCoordY[0];
			for (int anCntMinMaxCnt = 1; anCntMinMaxCnt < 3; anCntMinMaxCnt++)
			{
				if (afMaxX <= asGzCoordX[anCntMinMaxCnt])
				{
					afMaxX = asGzCoordX[anCntMinMaxCnt];
				}
				if (afMinX >= asGzCoordX[anCntMinMaxCnt])
				{
					afMinX = asGzCoordX[anCntMinMaxCnt];
				}
				if (afMaxY <= asGzCoordY[anCntMinMaxCnt])
				{
					afMaxY = asGzCoordY[anCntMinMaxCnt];
				}
				if (afMinY >= asGzCoordY[anCntMinMaxCnt])
				{
					afMinY = asGzCoordY[anCntMinMaxCnt];
				}
			}
			//set the boundary of x and y
			if (afMinX < 0)
			{
				afMinX = 0;
			}
			else if (afMinX > 255)
			{
				afMinX = 255;
			}
			if (afMaxX < 0){
				afMaxX = 0;
			}
			else if (afMaxX > 255)
			{
				afMaxX = 255;
			}
			if (afMinY < 0){
				afMinY = 0;
			}
			else if (afMinY > 255)
			{
				afMinY = 255;
			}
			if (afMaxY < 0){
				afMaxY = 0;
			}
			else if (afMaxY > 255)
			{
				afMaxY = 255;
			}
			//set the variants of vertex Ax + By + C = 0
			float afCoefA1, afCoefA2, afCoefA3, afCoefB1, afCoefB2, afCoefB3, afCoefC1, afCoefC2, afCoefC3;
			float AfDiff1, AfDiff2, AfDiff3;
			float afVar1, afVar2, afVar3, afVar4;
			GzIntensity asR, asG, asB, asAlpha;
			GzDepth anZ;
			int anInterZ;
			afCoefA1 = asGzCoordY[1] - asGzCoordY[0];
			afCoefA2 = asGzCoordY[2] - asGzCoordY[1];
			afCoefA3 = asGzCoordY[0] - asGzCoordY[2];
			afCoefB1 = -(asGzCoordX[1] - asGzCoordX[0]);
			afCoefB2 = -(asGzCoordX[2] - asGzCoordX[1]);
			afCoefB3 = -(asGzCoordX[0] - asGzCoordX[2]);
			afCoefC1 = ((-(afCoefB1)*asGzCoordY[1]) - (afCoefA1 * asGzCoordX[1]));
			afCoefC2 = ((-(afCoefB2)*asGzCoordY[2]) - (afCoefA2 * asGzCoordX[2]));
			afCoefC3 = ((-(afCoefB3)*asGzCoordY[0]) - (afCoefA3 * asGzCoordX[0]));
			afVar1 = (((asGzCoordY[1] - asGzCoordY[0])*(asGzCoordZ[2] - asGzCoordZ[0])) - ((asGzCoordY[2] - asGzCoordY[0])*(asGzCoordZ[1] - asGzCoordZ[0])));
			afVar2 = (((asGzCoordX[2] - asGzCoordX[0])*(asGzCoordZ[1] - asGzCoordZ[0])) - ((asGzCoordX[1] - asGzCoordX[0])*(asGzCoordZ[2] - asGzCoordZ[0])));
			afVar3 = (((asGzCoordX[1] - asGzCoordX[0])*(asGzCoordY[2] - asGzCoordY[0])) - ((asGzCoordX[2] - asGzCoordX[0])*(asGzCoordY[1] - asGzCoordY[0])));
			afVar4 = -((asGzCoordY[0] * (afVar2)) + (asGzCoordX[0] * (afVar1)) + (asGzCoordZ[0] * (afVar3)));
			for (int anCntRangeX = int(afMinX); (float)anCntRangeX < (afMaxX); anCntRangeX++){
				for (int anCntRangeY = int(afMinY); (float)anCntRangeY < (afMaxY); anCntRangeY++){
					AfDiff1 = (afCoefA1*anCntRangeX) + (afCoefB1*anCntRangeY) + afCoefC1;
					AfDiff2 = (afCoefA2*anCntRangeX) + (afCoefB2*anCntRangeY) + afCoefC2;
					AfDiff3 = (afCoefA3*anCntRangeX) + (afCoefB3*anCntRangeY) + afCoefC3;
					anInterZ = -(afVar1*anCntRangeX + afVar2*anCntRangeY + afVar4) / afVar3;
					if (!(AfDiff1 < 0 || AfDiff2 < 0 || AfDiff3 < 0)){
						asR = 0;
						asG = 0;
						asB = 0;
						asAlpha = 0;
						anZ = 0;
						if (GZ_FAILURE == GzGetDisplay(render->display, anCntRangeX, anCntRangeY, &asR, &asG, &asB, &asAlpha, &anZ))
						{
							return GZ_FAILURE;
						}
						if (anZ == 0||anInterZ < anZ)
						{
							if (GZ_FAILURE == GzPutDisplay(render->display, anCntRangeX, anCntRangeY, ctoi(render->flatcolor[RED]), ctoi(render->flatcolor[GREEN]), ctoi(render->flatcolor[BLUE]), asAlpha, anInterZ))
							{
								return GZ_FAILURE;
							}
						}
					}
				}
			}
		}
		else if (nameList[nCnt] == GZ_NULL_TOKEN)
		{
			continue;
		}
	}
	return GZ_SUCCESS;
}
Пример #18
0
int GzPutTriangle(GzRender *render, int	numParts, GzToken *nameList,
	GzPointer *valueList)
	/* numParts - how many names and values */
{
	/*
	- pass in a triangle description with tokens and values corresponding to
	GZ_NULL_TOKEN:		do nothing - no values
	GZ_POSITION:		3 vert positions
	- Invoke the scan converter and return an error code
	*/
	if (NULL == render || NULL == nameList || NULL == valueList || numParts == 0)
		return GZ_FAILURE;

	GzCoord * pre_vertexList, *cur_vertexList, *pre_normalList, *cur_normalList;
	GzTextureIndex * pre_uvList, * pre_wrapeduvList, * cur_wrapeduvList;
	bool Triangle_Hidden = false, Triangle_Out = false;
	for (int i = 0; i < numParts; i++) {
		//GzMatrix transform_matrix;
		if (nameList[i] == GZ_POSITION) {
			pre_vertexList = (GzCoord*)(valueList[i]);
			cur_vertexList = new GzCoord[3];
			for (int i = 0; i < 3; i++) {
				Transformation(pre_vertexList[i], cur_vertexList[i], render->Ximage[render->matlevel]);
				cur_vertexList[i][X] += render->Xshift;
				cur_vertexList[i][Y] += render->Yshift;
			}
				
		}
		else if (nameList[i] == GZ_NORMAL) {
			pre_normalList = (GzCoord*)(valueList[i]);
			cur_normalList = new GzCoord[3];
			for (int i = 0; i < 3; i++)
				Transformation(pre_normalList[i], cur_normalList[i], render->Xnorm[render->matlevel]);
		}
		else if (nameList[i] == GZ_TEXTURE_INDEX) {
			pre_uvList = (GzTextureIndex*)valueList[i];
		}
		else if (nameList[i] == GZ_NULL_TOKEN) {
			return GZ_SUCCESS;
		}
	}

	cur_wrapeduvList = new GzTextureIndex[2];

	//Warp u,v to perspective space (U,V) at verts
	for (int i = 0; i < 3; i++) {
		float Vz = cur_vertexList[i][Z] / (INT_MAX - cur_vertexList[i][Z]);
		cur_wrapeduvList[i][U] = pre_uvList[i][U] / (Vz + 1);
		cur_wrapeduvList[i][V] = pre_uvList[i][V] / (Vz + 1);
	}

	//sort vertexes asa based on the y coordinates  then x coordinates in ascendent order, cur_vertexList[2] has the most high y coordinates value
	float temp_x, temp_y, temp_z;
	for (int m = 0; m < 2; m++) {
		for (int n = 0; n < 2 - m; n++) {
			//aaaading: if 3 vertex is in a line if vertex are overlap each other
			if ((cur_vertexList[n][Y] > cur_vertexList[n + 1][Y]) || (cur_vertexList[n][X] >cur_vertexList[n + 1][X] && cur_vertexList[n][Y] == cur_vertexList[n + 1][Y])) {
				//sort vertex
				temp_x = cur_vertexList[n][X];
				temp_y = cur_vertexList[n][Y];
				temp_z = cur_vertexList[n][Z];

				cur_vertexList[n][X] = cur_vertexList[n + 1][X];
				cur_vertexList[n][Y] = cur_vertexList[n + 1][Y];
				cur_vertexList[n][Z] = cur_vertexList[n + 1][Z];

				cur_vertexList[n + 1][X] = temp_x;
				cur_vertexList[n + 1][Y] = temp_y;
				cur_vertexList[n + 1][Z] = temp_z;

				//sort vertex normal vector
				temp_x = cur_normalList[n][X];
				temp_y = cur_normalList[n][Y];
				temp_z = cur_normalList[n][Z];
				
				cur_normalList[n][X] = cur_normalList[n + 1][X];
				cur_normalList[n][Y] = cur_normalList[n + 1][Y];
				cur_normalList[n][Z] = cur_normalList[n + 1][Z];

				cur_normalList[n + 1][X] = temp_x;
				cur_normalList[n + 1][Y] = temp_y;
				cur_normalList[n + 1][Z] = temp_z;

				//sort vertex normal vector
				temp_x = cur_wrapeduvList[n][X];
				temp_y = cur_wrapeduvList[n][Y];

				cur_wrapeduvList[n][X] = cur_wrapeduvList[n + 1][X];
				cur_wrapeduvList[n][Y] = cur_wrapeduvList[n + 1][Y];

				cur_wrapeduvList[n + 1][X] = temp_x;
				cur_wrapeduvList[n + 1][Y] = temp_y;
			}
		}
	}

	//Frustums and Clipping
	if (cur_vertexList[0][Y] < 0 && cur_vertexList[1][Y] < 0 && cur_vertexList[2][Y] < 0)
		Triangle_Out = true;
	else if (cur_vertexList[0][Y] > render->display->yres && cur_vertexList[1][Y] > render->display->yres && cur_vertexList[2][Y] > render->display->yres)
		Triangle_Out = true;
	else if (cur_vertexList[0][X] < 0 && cur_vertexList[1][X] < 0 && cur_vertexList[2][X] < 0)
		Triangle_Out = true;
	else if (cur_vertexList[0][X] > render->display->xres && cur_vertexList[1][X] > render->display->xres && cur_vertexList[2][X] > render->display->xres)
		Triangle_Out = true;
	else
		Triangle_Out = false;

	for (int n = 0; n < 3; n++) {
		if (cur_vertexList[n][Z] < 0) {

			Triangle_Hidden = true;
			break;
		}
	}

	if (Triangle_Hidden || Triangle_Out)
		return GZ_SUCCESS;

	//CW order
	int cw_flag;
	float dX_edge[3], dY_edge[3], dZ_edge[3];	
	// dX_edge_0 represents the edge originates from vertex 0
	// horizontal edges situation, include the situation of both horizontal and vertical edges
	if (cur_vertexList[1][Y] == cur_vertexList[2][Y]) {
		cw_flag = 1;
	}
	else if (cur_vertexList[0][Y] == cur_vertexList[1][Y]) {
		cw_flag = 2;
	}
	// only vertical edges situation
	else if (cur_vertexList[0][X] == cur_vertexList[1][X]) {
		if (cur_vertexList[2][X] > cur_vertexList[1][X]){
			cw_flag = 1;
		}
		else {
			cw_flag = 2;
		}
	}
	else if (cur_vertexList[0][X] == cur_vertexList[2][X]){
		if (cur_vertexList[1][X] < cur_vertexList[2][X]){
			cw_flag = 1;
		}
		else {
			cw_flag = 2;
		} 

	}
	else if (cur_vertexList[1][X] == cur_vertexList[2][X]){
		if (cur_vertexList[0][X] < cur_vertexList[1][X]){
			cw_flag = 2;
		}
		else {
			cw_flag = 1;
		}
	}
	// the situation of none horizontal and vertical edges
	else {
		float slope_2_0 = (cur_vertexList[2][Y] - cur_vertexList[0][Y]) / (cur_vertexList[2][X] - cur_vertexList[0][X]);
		float mid_Y_vertex = cur_vertexList[0][X] + ((cur_vertexList[1][Y] - cur_vertexList[0][Y]) / slope_2_0);
		if (mid_Y_vertex < cur_vertexList[1][X]) {    // long edge in the left
			cw_flag = 2;
		}
		else  {   // long edge in the right
			cw_flag = 1; 
		} 
	} 
	VectorCW(dX_edge, dY_edge, dZ_edge, cur_vertexList, cw_flag);
	//get coefficients of edge 0 1 2  dYx + (-dX)y + (dXY - dYX) = 0   Ax + By + C = 0 XY means the vector tail coordinates

	float A_edge_0, B_edge_0, C_edge_0, A_edge_1, B_edge_1, C_edge_1, A_edge_2, B_edge_2, C_edge_2;
	A_edge_0 = dY_edge[0];   //A = dY
	B_edge_0 = -dX_edge[0];  //B = -dX
	C_edge_0 = dX_edge[0] * cur_vertexList[0][Y] - dY_edge[0] * cur_vertexList[0][X];  //C = dXY - DYX

	A_edge_1 = dY_edge[1];
	B_edge_1 = -dX_edge[1];
	C_edge_1 = dX_edge[1] * cur_vertexList[1][Y] - dY_edge[1] * cur_vertexList[1][X];

	A_edge_2 = dY_edge[2];
	B_edge_2 = -dX_edge[2];
	C_edge_2 = dX_edge[2] * cur_vertexList[2][Y] - dY_edge[2] * cur_vertexList[2][X];

	//get cofficient for plane equation Ax + By + Cz + D = 0
	float A_plane, B_plane, C_plane, D_plane;
	//(Ax, Ay, Az) X (Bx, By, Bz) = (AyBz - AzBy, AzBx - AxBz, AxBy - AyBx) = (A, B, C), take (A, B, C) into  Ax+By+Cz+D = 0 to caculate D
	//(dX_edge_0, dY_edge_0, dZ_edge_0) X (dX_edge_1, dY_edge_1, dZ_edge_1)
	A_plane = dY_edge[0] * dZ_edge[1] - dZ_edge[0] * dY_edge[1];
	B_plane = dZ_edge[0] * dX_edge[1] - dX_edge[0] * dZ_edge[1];
	C_plane = dX_edge[0] * dY_edge[1] - dY_edge[0] * dX_edge[1];
	D_plane = 0 - (A_plane * cur_vertexList[0][X] + B_plane * cur_vertexList[0][Y] + C_plane * cur_vertexList[0][Z]);

	/* Rasterization */
	float A_cof_color[3], B_cof_color[3], C_cof_color[3], D_cof_color[3];
	float sign_edge_0, sign_edge_1, sign_edge_2;
	GzDepth pixel_z, pixel_depth;
	GzIntensity red, green, blue, alpha;
	GzColor pixel_color, pixel_norm, pixel_wrapeduv;

	float A_cof_norm[3], B_cof_norm[3], C_cof_norm[3], D_cof_norm[3];
	//Interpolation of Color/Normal and caculate coefficients

	if (render->interp_mode == GZ_COLOR) {
		GzColor cur_colorList[3];
		
		if (render->tex_fun) {
			for (int i = 0; i < 3; i++) {    // i means the order of the color of three vertex
				PixelColorShading(render, cur_normalList[i], cur_colorList[i], NULL, GOURAUD_TEXTURE);  //Gouraud Shading with texture
			}
		}
		else {
			for (int i = 0; i < 3; i++) {
				PixelColorShading(render, cur_normalList[i], cur_colorList[i], NULL, NON_TEXTURE);  //Gouraud Shading without texture
			}
		}
		


		//interpolate color as Z
		for (int i = 0; i < 3; i++) { /*three different group of X Y Z for each vertex, Z comes from cur_normalList, the first round
									  for vertex 0 is {cur_vertexList[0][X],  cur_vertexList[0][Y], cur_normalList[0][X]} */
			cur_vertexList[0][Z] = cur_colorList[0][i]; // i = 0 => RED	   i = 0 => GREEN	  i = 0 => BLUE
			cur_vertexList[1][Z] = cur_colorList[1][i];
			cur_vertexList[2][Z] = cur_colorList[2][i];
			VectorCW(dX_edge, dY_edge, dZ_edge, cur_vertexList, cw_flag);
			A_cof_color[i] = dY_edge[0] * dZ_edge[1] - dZ_edge[0] * dY_edge[1];
			B_cof_color[i] = dZ_edge[0] * dX_edge[1] - dX_edge[0] * dZ_edge[1];
			C_cof_color[i] = dX_edge[0] * dY_edge[1] - dY_edge[0] * dX_edge[1];
			D_cof_color[i] = 0 - (A_cof_color[i] * cur_vertexList[0][X] + B_cof_color[i] * cur_vertexList[0][Y] + C_cof_color[i] * cur_vertexList[0][Z]);
		}
	}
	else if (render->interp_mode == GZ_NORMALS) {
		//interpolate normal as Z
		
		for (int i = 0; i < 3; i++) {
			//cof[X] for normal coordinate x interpolation
			//X Y Z: Screen Space    normalized vector(cur_normalList) , light direction : affine/image space
			cur_vertexList[0][Z] = cur_normalList[0][i]; // i = 0 => X    i = 0 => Y    i = 0 => Z
			cur_vertexList[1][Z] = cur_normalList[1][i];
			cur_vertexList[2][Z] = cur_normalList[2][i];
			VectorCW(dX_edge, dY_edge, dZ_edge, cur_vertexList, cw_flag);
			A_cof_norm[i] = dY_edge[0] * dZ_edge[1] - dZ_edge[0] * dY_edge[1];
			B_cof_norm[i] = dZ_edge[0] * dX_edge[1] - dX_edge[0] * dZ_edge[1];
			C_cof_norm[i] = dX_edge[0] * dY_edge[1] - dY_edge[0] * dX_edge[1];
			D_cof_norm[i] = 0 - (A_cof_norm[i] * cur_vertexList[0][X] + B_cof_norm[i] * cur_vertexList[0][Y] + C_cof_norm[i] * cur_vertexList[0][Z]);
		}
	}

	//interpolate texture as Z
	float A_cof_wrapeduv[2], B_cof_wrapeduv[2], C_cof_wrapeduv[2], D_cof_wrapeduv[2];
	for (int i = 0; i < 2; i++) {
		//cof[X] for normal coordinate x interpolation
		cur_vertexList[0][Z] = cur_wrapeduvList[0][i]; // i = 0 => U   i = 1 => V
		cur_vertexList[1][Z] = cur_wrapeduvList[1][i];
		cur_vertexList[2][Z] = cur_wrapeduvList[2][i];
		VectorCW(dX_edge, dY_edge, dZ_edge, cur_vertexList, cw_flag);
		A_cof_wrapeduv[i] = dY_edge[0] * dZ_edge[1] - dZ_edge[0] * dY_edge[1];
		B_cof_wrapeduv[i] = dZ_edge[0] * dX_edge[1] - dX_edge[0] * dZ_edge[1];
		C_cof_wrapeduv[i] = dX_edge[0] * dY_edge[1] - dY_edge[0] * dX_edge[1];
		D_cof_wrapeduv[i] = 0 - (A_cof_wrapeduv[i] * cur_vertexList[0][X] + B_cof_wrapeduv[i] * cur_vertexList[0][Y] + C_cof_wrapeduv[i] * cur_vertexList[0][Z]);
	}
	
	

	//bounding rectangle
	float left_boundary = 256.0, top_boundary = 256.0, right_boundary = 0.0, bottom_boundary = 0.0;    ////revise here!!!!

	for (int i = 0; i<3; i++) {
		if (cur_vertexList[i][X] < left_boundary)
			left_boundary = cur_vertexList[i][X];
		if (cur_vertexList[i][Y] < top_boundary)
			top_boundary = cur_vertexList[i][Y];
		if (cur_vertexList[i][X] > right_boundary)
			right_boundary = cur_vertexList[i][X];
		if (cur_vertexList[i][Y] > bottom_boundary)
			bottom_boundary = cur_vertexList[i][Y];
	}

	for (int pixel_y = top_boundary; pixel_y <= bottom_boundary; pixel_y++) {

		for (int pixel_x = left_boundary; pixel_x <= right_boundary; pixel_x++) {
			// interpolate Z
			// z = -(Ax + By + D) / C
			pixel_z = (GzDepth)(-(A_plane * pixel_x + B_plane * pixel_y + D_plane) / C_plane);
			

			sign_edge_0 = A_edge_0 * pixel_x + B_edge_0 * pixel_y + C_edge_0;
			sign_edge_1 = A_edge_1 * pixel_x + B_edge_1 * pixel_y + C_edge_1;
			sign_edge_2 = A_edge_2 * pixel_x + B_edge_2 * pixel_y + C_edge_2;

			if (pixel_z >= 0 && sign_edge_0 >= 0 && sign_edge_1 >= 0 && sign_edge_2 >= 0) {
				// compute interpolated pixel wraped pixel
				pixel_wrapeduv[U] = -(A_cof_wrapeduv[U] * pixel_x + B_cof_wrapeduv[U] * pixel_y + D_cof_wrapeduv[U]) / C_cof_wrapeduv[U];
				pixel_wrapeduv[V] = -(A_cof_wrapeduv[V] * pixel_x + B_cof_wrapeduv[V] * pixel_y + D_cof_wrapeduv[V]) / C_cof_wrapeduv[V];

				//unwarp U,V
				float pixel_unwrapeduv[2];
				float Vz = pixel_z * 1.0 / (INT_MAX - pixel_z);
				pixel_unwrapeduv[U] = pixel_wrapeduv[U] * (Vz + 1);
				pixel_unwrapeduv[V] = pixel_wrapeduv[V] * (Vz + 1);

				GzColor pixel_tex;
				if (render->tex_fun) 
					render->tex_fun(pixel_unwrapeduv[U], pixel_unwrapeduv[V], pixel_tex);

				GzGetDisplay(render->display, pixel_x, pixel_y, &red, &green, &blue, &alpha, &pixel_depth);
				if (pixel_depth == 0 || pixel_z < pixel_depth) {
					//float pixel_red, pixel_green, pixel_blue;

					if (render->interp_mode == GZ_FLAT) {

						pixel_color[RED] = render->flatcolor[RED];
						pixel_color[GREEN] = render->flatcolor[GREEN];
						pixel_color[BLUE] = render->flatcolor[BLUE];

					}
					else if (render->interp_mode == GZ_COLOR) {
						//for(int k=0;k<3;k++)
						//q[k] = -(pCof[k].planeA * j + pCof[k].planeB * i  + pCof[k].planeD) / pCof[k].planeC;

						pixel_color[RED] = -(A_cof_color[RED] * pixel_x + B_cof_color[RED] * pixel_y + D_cof_color[RED]) / C_cof_color[RED];
						pixel_color[GREEN] = -(A_cof_color[GREEN] * pixel_x + B_cof_color[GREEN] * pixel_y + D_cof_color[GREEN]) / C_cof_color[GREEN];
						pixel_color[BLUE] = -(A_cof_color[BLUE] * pixel_x + B_cof_color[BLUE] * pixel_y + D_cof_color[BLUE]) / C_cof_color[BLUE];			

						if (render->tex_fun) {
							pixel_color[RED] *= pixel_tex[RED];
							pixel_color[GREEN] *= pixel_tex[GREEN];
							pixel_color[BLUE] *= pixel_tex[BLUE];
						}
						
						CHECK_OVERFLOW(pixel_color[RED]);
						CHECK_OVERFLOW(pixel_color[GREEN]);
						CHECK_OVERFLOW(pixel_color[BLUE]);
					}
					else if (render->interp_mode == GZ_NORMALS) {  //Phong Shading
						//getNormal(q);
						//for(int k=0;k<3;k++)
						//q[k] = -( pCof[k].planeA * j + pCof[k].planeB * i  + pCof[k].planeD ) / pCof[k].planeC;
						pixel_norm[X] = -(A_cof_norm[X] * pixel_x + B_cof_norm[X] * pixel_y + D_cof_norm[X]) / C_cof_norm[X];
						pixel_norm[Y] = -(A_cof_norm[Y] * pixel_x + B_cof_norm[Y] * pixel_y + D_cof_norm[Y]) / C_cof_norm[Y];
						pixel_norm[Z] = -(A_cof_norm[Z] * pixel_x + B_cof_norm[Z] * pixel_y + D_cof_norm[Z]) / C_cof_norm[Z];

						if (render->tex_fun)
							PixelColorShading(render, pixel_norm, pixel_color, pixel_tex, PHONG_TEXTURE); 
						else 
							PixelColorShading(render, pixel_norm, pixel_color, NULL, NON_TEXTURE); 
					}
					else {
						return GZ_FAILURE;
					}
					GzPutDisplay(render->display, pixel_x, pixel_y, ctoi(pixel_color[RED]), ctoi(pixel_color[GREEN]), ctoi(pixel_color[BLUE]), alpha, pixel_z);

				}

			}
		}
	}

	return GZ_SUCCESS;
}