static void calcTileIllum(UDWORD tileX, UDWORD tileY) { /* The number or normals that we got is in numNormals*/ Vector3f finalVector = {0.0f, 0.0f, 0.0f}; unsigned int i, val; int dotProduct; unsigned int numNormals = 0; // How many normals have we got? Vector3f normals[8]; // Maximum 8 possible normals /* Quadrants look like:- * * 0 * 1 * * **********V********** * * 3 * 2 * * */ /* Do quadrant 0 - tile that's above and left*/ normalsOnTile(tileX-1, tileY-1, 0, &numNormals, normals); /* Do quadrant 1 - tile that's above and right*/ normalsOnTile(tileX, tileY-1, 1, &numNormals, normals); /* Do quadrant 2 - tile that's down and right*/ normalsOnTile(tileX, tileY, 2, &numNormals, normals); /* Do quadrant 3 - tile that's down and left*/ normalsOnTile(tileX-1, tileY, 3, &numNormals, normals); for(i = 0; i < numNormals; i++) { finalVector = Vector3f_Add(finalVector, normals[i]); } dotProduct = Vector3f_ScalarP(Vector3f_Normalise(finalVector), theSun); val = abs(dotProduct) / 16; if (val == 0) val = 1; if (val > 254) val = 254; mapTile(tileX, tileY)->illumination = val; }
/// Draw the shadow for a shape static void pie_DrawShadow(iIMDShape *shape, int flag, int flag_data, Vector3f* light) { unsigned int i, j, n; Vector3f *pVertices; iIMDPoly *pPolys; unsigned int edge_count = 0; static EDGE *edgelist = NULL; static unsigned int edgelistsize = 256; EDGE *drawlist = NULL; if(!edgelist) { edgelist = (EDGE*)malloc(sizeof(EDGE)*edgelistsize); } pVertices = shape->points; if( flag & pie_STATIC_SHADOW && shape->shadowEdgeList ) { drawlist = shape->shadowEdgeList; edge_count = shape->nShadowEdges; } else { for (i = 0, pPolys = shape->polys; i < shape->npolys; ++i, ++pPolys) { Vector3f p[3], v[2], normal = {0.0f, 0.0f, 0.0f}; VERTEXID current, first; for(j = 0; j < 3; j++) { current = pPolys->pindex[j]; p[j] = Vector3f_Init(pVertices[current].x, scale_y(pVertices[current].y, flag, flag_data), pVertices[current].z); } v[0] = Vector3f_Sub(p[2], p[0]); v[1] = Vector3f_Sub(p[1], p[0]); normal = Vector3f_CrossP(v[0], v[1]); if (Vector3f_ScalarP(normal, *light) > 0) { first = pPolys->pindex[0]; for (n = 1; n < pPolys->npnts; n++) { // link to the previous vertex addToEdgeList(pPolys->pindex[n-1], pPolys->pindex[n], edgelist, &edge_count, pVertices); // check if the edgelist is still large enough if(edge_count >= edgelistsize-1) { // enlarge EDGE* newstack; edgelistsize *= 2; newstack = realloc(edgelist, sizeof(EDGE) * edgelistsize); if (newstack == NULL) { debug(LOG_FATAL, "pie_DrawShadow: Out of memory!"); abort(); return; } edgelist = newstack; debug(LOG_WARNING, "new edge list size: %u", edgelistsize); } } // back to the first addToEdgeList(pPolys->pindex[pPolys->npnts-1], first, edgelist, &edge_count, pVertices); } } //debug(LOG_WARNING, "we have %i edges", edge_count); drawlist = edgelist; if(flag & pie_STATIC_SHADOW) { // first compact the current edgelist for(i = 0, j = 0; i < edge_count; i++) { if(edgelist[i].from < 0) { continue; } edgelist[j] = edgelist[i]; j++; } edge_count = j; // then store it in the imd shape->nShadowEdges = edge_count; shape->shadowEdgeList = realloc(shape->shadowEdgeList, sizeof(EDGE) * shape->nShadowEdges); memcpy(shape->shadowEdgeList, edgelist, sizeof(EDGE) * shape->nShadowEdges); } } // draw the shadow volume glBegin(GL_QUADS); for(i=0;i<edge_count;i++) { int a = drawlist[i].from, b = drawlist[i].to; if(a < 0) { continue; } glVertex3f(pVertices[b].x, scale_y(pVertices[b].y, flag, flag_data), pVertices[b].z); glVertex3f(pVertices[b].x+light->x, scale_y(pVertices[b].y, flag, flag_data)+light->y, pVertices[b].z+light->z); glVertex3f(pVertices[a].x+light->x, scale_y(pVertices[a].y, flag, flag_data)+light->y, pVertices[a].z+light->z); glVertex3f(pVertices[a].x, scale_y(pVertices[a].y, flag, flag_data), pVertices[a].z); } glEnd(); #ifdef SHOW_SHADOW_EDGES glDisable(GL_DEPTH_TEST); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColor4ub(0xFF, 0, 0, 0xFF); glBegin(GL_LINES); for(i = 0; i < edge_count; i++) { int a = drawlist[i].from, b = drawlist[i].to; if(a < 0) { continue; } glVertex3f(pVertices[b].x, scale_y(pVertices[b].y, flag, flag_data), pVertices[b].z); glVertex3f(pVertices[a].x, scale_y(pVertices[a].y, flag, flag_data), pVertices[a].z); } glEnd(); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glEnable(GL_DEPTH_TEST); #endif }