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;
    }

}
Пример #2
0
void mx_LevelGenerator::AddRoomCube( const Room* room )
{
	for( int z= room->coord_min[2] - 1; z < room->coord_max[2]; z++ )
	for( int y= room->coord_min[1] - 1; y < room->coord_max[1]; y++ )
	for( int x= room->coord_min[0] - 1; x < room->coord_max[0]; x++ )
	{
		Element* element= ElementMap( x, y, z );
		Element* el_x= ElementMap( x + 1, y, z );
		Element* el_y= ElementMap( x, y + 1, z );
		Element* el_z= ElementMap( x, y, z + 1 );

		bool is_element= element == NULL;
		bool is_el_x= el_x == NULL;
		bool is_el_y= el_y == NULL;
		bool is_el_z= el_z == NULL;

		if( (is_element ^ is_el_x) && (element == room || el_x == room ) )
		{
			ReserveTrianglesAndVertices( 2, 4 );
			mx_LevelVertex* v= out_level_data_.vertices + out_level_data_.vertex_count;

			v[0].xyz[0]= float(x+1);
			v[0].xyz[1]= float(y);
			v[0].xyz[2]= float(z);
			v[1].xyz[0]= float(x+1);
			v[1].xyz[1]= float(y+1);
			v[1].xyz[2]= float(z);
			v[2].xyz[0]= float(x+1);
			v[2].xyz[1]= float(y+1);
			v[2].xyz[2]= float(z+1);
			v[3].xyz[0]= float(x+1);
			v[3].xyz[1]= float(y);
			v[3].xyz[2]= float(z+1);

			if( is_element ) SwapVertices( v[1].xyz, v[3].xyz );

			GenQuadIndexation( out_level_data_.triangles + out_level_data_.triangle_count, out_level_data_.vertex_count );
			out_level_data_.vertex_count+= 4;
			out_level_data_.triangle_count+= 2;
		}
		if( (is_element ^ is_el_y) && (element == room || el_y == room ) )
		{
			ReserveTrianglesAndVertices( 2, 4 );
			mx_LevelVertex* v= out_level_data_.vertices + out_level_data_.vertex_count;

			v[0].xyz[0]= float(x);
			v[0].xyz[1]= float(y+1);
			v[0].xyz[2]= float(z);
			v[1].xyz[0]= float(x);
			v[1].xyz[1]= float(y+1);
			v[1].xyz[2]= float(z+1);
			v[2].xyz[0]= float(x+1);
			v[2].xyz[1]= float(y+1);
			v[2].xyz[2]= float(z+1);
			v[3].xyz[0]= float(x+1);
			v[3].xyz[1]= float(y+1);
			v[3].xyz[2]= float(z);

			if( is_element ) SwapVertices( v[1].xyz, v[3].xyz );

			GenQuadIndexation( out_level_data_.triangles + out_level_data_.triangle_count, out_level_data_.vertex_count );
			out_level_data_.vertex_count+= 4;
			out_level_data_.triangle_count+= 2;
		}
		if( (is_element ^ is_el_z) && (element == room || el_z == room ) )
		{
			ReserveTrianglesAndVertices( 2, 4 );
			mx_LevelVertex* v= out_level_data_.vertices + out_level_data_.vertex_count;

			v[0].xyz[0]= float(x);
			v[0].xyz[1]= float(y);
			v[0].xyz[2]= float(z+1);
			v[1].xyz[0]= float(x+1);
			v[1].xyz[1]= float(y);
			v[1].xyz[2]= float(z+1);
			v[2].xyz[0]= float(x+1);
			v[2].xyz[1]= float(y+1);
			v[2].xyz[2]= float(z+1);
			v[3].xyz[0]= float(x);
			v[3].xyz[1]= float(y+1);
			v[3].xyz[2]= float(z+1);

			if( is_element ) SwapVertices( v[1].xyz, v[3].xyz );

			GenQuadIndexation( out_level_data_.triangles + out_level_data_.triangle_count, out_level_data_.vertex_count );
			out_level_data_.vertex_count+= 4;
			out_level_data_.triangle_count+= 2;
		}
	} // or xyz

}