void renderTriangles(const SPVertex * _pVertices, const GLubyte * _pElements, u32 _numElements) { //Current depth buffer can be null if we are loading from a save state if(depthBufferList().getCurrent() == nullptr) return; vertexclip vclip[16]; vertexi vdraw[12]; const SPVertex * vsrc[4]; SPVertex vdata[6]; for (u32 i = 0; i < _numElements; i += 3) { u32 orbits = 0; if (_pElements != nullptr) { for (u32 j = 0; j < 3; ++j) { vsrc[j] = &_pVertices[_pElements[i + j]]; orbits |= vsrc[j]->clip; } } else { for (u32 j = 0; j < 3; ++j) { vsrc[j] = &_pVertices[i + j]; orbits |= vsrc[j]->clip; } } vsrc[3] = vsrc[0]; int numVertex = clipW(vsrc, vdata); if (!calcScreenCoordinates(vdata, vclip, numVertex)) continue; const int dzdx = ((orbits & CLIP_W) == 0) ? calcDzDx(vclip) : calcDzDx2(vsrc); if (dzdx == 0) continue; if (orbits == 0) { assert(numVertex == 3); if ((gSP.geometryMode & G_CULL_BACK) != 0) { for (int k = 0; k < 3; ++k) { vdraw[k].x = floatToFixed16(vclip[k].x); vdraw[k].y = floatToFixed16(vclip[k].y); vdraw[k].z = floatToFixed16(vclip[k].z); } } else { for (int k = 0; k < 3; ++k) { const u32 idx = 3 - k - 1; vdraw[k].x = floatToFixed16(vclip[idx].x); vdraw[k].y = floatToFixed16(vclip[idx].y); vdraw[k].z = floatToFixed16(vclip[idx].z); } } } else { vertexclip ** vtx; numVertex = ClipPolygon(&vtx, vclip, numVertex); if (numVertex < 3) continue; if ((gSP.geometryMode & G_CULL_BACK) != 0) { for (int k = 0; k < numVertex; ++k) { vdraw[k].x = floatToFixed16(vtx[k]->x); vdraw[k].y = floatToFixed16(vtx[k]->y); vdraw[k].z = floatToFixed16(vtx[k]->z); } } else { for (int k = 0; k < numVertex; ++k) { const u32 idx = numVertex - k - 1; vdraw[k].x = floatToFixed16(vtx[idx]->x); vdraw[k].y = floatToFixed16(vtx[idx]->y); vdraw[k].z = floatToFixed16(vtx[idx]->z); } } } Rasterize(vdraw, numVertex, dzdx); } }
void scanConverter(GzRender *render, GzCoord *vertexList) { GzCoord top, mid, btm; GzCoord vtx1, vtx2, vtx3; /* Find a bounding box of the tri, and sort 3 verts */ /* Find max and min x values */ float minx, miny, maxx, maxy; if (vertexList[0][0] >= vertexList[1][0]) { maxx = vertexList[0][0]; minx = vertexList[1][0]; } else { maxx = vertexList[1][0]; minx = vertexList[0][0]; } if (vertexList[2][0] > maxx) maxx = vertexList[2][0]; if (vertexList[2][0] < minx) minx = vertexList[2][0]; /* Find max and min y values*/ if (vertexList[0][1] >= vertexList[1][1]) { top[0] = vertexList[0][0]; top[1] = vertexList[0][1]; top[2] = vertexList[0][2]; btm[0] = vertexList[1][0]; btm[1] = vertexList[1][1]; btm[2] = vertexList[1][2]; } else { top[0] = vertexList[1][0]; top[1] = vertexList[1][1]; top[2] = vertexList[1][2]; btm[0] = vertexList[0][0]; btm[1] = vertexList[0][1]; btm[2] = vertexList[0][2]; } if (vertexList[2][1] > top[1]) { mid[0] = top[0]; mid[1] = top[1]; mid[2] = top[2]; top[0] = vertexList[2][0]; top[1] = vertexList[2][1]; top[2] = vertexList[2][2]; } else if (vertexList[2][1] < btm[1]) { mid[0] = btm[0]; mid[1] = btm[1]; mid[2] = btm[2]; btm[0] = vertexList[2][0]; btm[1] = vertexList[2][1]; btm[2] = vertexList[2][2]; } else { mid[0] = vertexList[2][0]; mid[1] = vertexList[2][1]; mid[2] = vertexList[2][2]; } maxx = ceil(maxx); maxy = ceil(top[1]); minx = floor(minx); miny = floor(btm[1]); if (top[1] == mid[1]) // Top edge exits { if (top[0] < mid[0]) { vtx1[0] = top[0]; vtx1[1] = top[1]; vtx1[2] = top[2]; vtx2[0] = mid[0]; vtx2[1] = mid[1]; vtx2[2] = mid[2]; } else { vtx2[0] = top[0]; vtx2[1] = top[1]; vtx2[2] = top[2]; vtx1[0] = mid[0]; vtx1[1] = mid[1]; vtx1[2] = mid[2]; } vtx3[0] = top[0]; vtx1[1] = top[1]; vtx1[2] = top[2]; } else if (btm[1] == mid[1]) // Bottom edge exits { if (btm[0] < mid[0]) { vtx3[0] = btm[0]; vtx3[1] = btm[1]; vtx3[2] = btm[2]; vtx2[0] = mid[0]; vtx2[1] = mid[1]; vtx2[2] = mid[2]; } else { vtx2[0] = btm[0]; vtx2[1] = btm[1]; vtx2[2] = btm[2]; vtx3[0] = mid[0]; vtx3[1] = mid[1]; vtx3[2] = mid[2]; } vtx1[0] = top[0]; vtx1[1] = top[1]; vtx1[2] = top[2]; } else { float deltax = top[0] - btm[0]; float deltay = top[1] - btm[1]; float slope = deltax / deltay; float x = mid[1] * slope - top[1] * slope + top[0]; vtx1[0] = top[0]; vtx1[1] = top[1]; vtx1[2] = top[2]; if (x < mid[0]) { vtx2[0] = mid[0]; vtx2[1] = mid[1]; vtx2[2] = mid[2]; vtx3[0] = btm[0]; vtx3[1] = btm[1]; vtx3[2] = btm[2]; } else { vtx2[0] = btm[0]; vtx2[1] = btm[1]; vtx2[2] = btm[2]; vtx3[0] = mid[0]; vtx3[1] = mid[1]; vtx3[2] = mid[2]; } } for (int i = (int)minx; i < (int)maxx; i++) { for (int j = (int)miny; j < (int)maxy; j++) { GzCoord point; point[0] = i; point[1] = j; point[2] = 0; if (LEE(vtx1, vtx2, point) >= 0 && LEE(vtx2, vtx3, point) >= 0 && LEE(vtx3, vtx1, point) >= 0) { /* Interpolate Z */ float vector1[3], vector2[3]; float *result = (float*)malloc(sizeof(float)* 3); vector1[0] = vtx1[0] - vtx2[0]; vector1[1] = vtx1[1] - vtx2[1]; vector1[2] = vtx1[2] - vtx2[2]; vector2[0] = vtx3[0] - vtx2[0]; vector2[1] = vtx3[1] - vtx2[1]; vector2[2] = vtx3[2] - vtx2[2]; result = crossProduct(vector1, vector2); if (result[0] * vtx2[0] + result[1] * vtx2[1] + result[2] * vtx2[2] == result[0] * vtx3[0] + result[1] * vtx3[1] + result[2] * vtx3[2]) int a = 3; point[2] = (result[0] * vtx1[0] + result[1] * vtx1[1] + result[2] * vtx1[2] - result[0] * i - result[1] * j) / result[2]; ///* Do the transformation */ //transform(render, point); Rasterize(render->display, point[0], point[1], ctoi(render->flatcolor[0]), ctoi(render->flatcolor[1]), ctoi(render->flatcolor[2]), 1, point[2]); } } } }