/* software ID rendering: because hardware ID rendering is tricky due to frame buffer * formats, .... */ #include #include "softids.h" #include "scene.h" #include "camera.h" #include "render.h" #include "error.h" SGL_CONTEXT *SetupSoftFrameBuffer(void) { SGL_CONTEXT *sgl; sgl = sglOpen(Camera.hres, Camera.vres); sglDepthTesting(TRUE); sglClipping(TRUE); sglClear((SGL_PIXEL)0, SGL_ZMAX); sglLoadMatrix(Perspective(Camera.fov*2.*M_PI/180., (float)Camera.hres/(float)Camera.vres, Camera.near, Camera.far)); sglMultMatrix(LookAt(Camera.eyep, Camera.lookp, Camera.updir)); return sgl; } static SGL_PIXEL (*PatchPixel)(PATCH *) = NULL; static void SoftRenderPatch(PATCH *P) { VECTOR verts[4]; if (renderopts.backface_culling && VECTORDOTPRODUCT(P->normal, Camera.eyep) + P->plane_constant < EPSILON) return; verts[0] = *P->vertex[0]->point; verts[1] = *P->vertex[1]->point; verts[2] = *P->vertex[2]->point; if (P->nrvertices > 3) verts[3] = *P->vertex[3]->point; sglSetColor(PatchPixel(P)); sglPolygon(P->nrvertices, verts); } void SoftRenderPatches(SGL_PIXEL (*patch_pixel)(PATCH *)) { PatchPixel = patch_pixel; if (renderopts.frustum_culling) { int use_display_lists = renderopts.use_display_lists; renderopts.use_display_lists = FALSE; /* temporarily switch it off */ RenderWorldOctree(SoftRenderPatch); renderopts.use_display_lists = use_display_lists; } else { ForAllPatches(P, Patches) { SoftRenderPatch(P); } EndForAll; } } static SGL_PIXEL PatchID(PATCH *P) { return (SGL_PIXEL)P->id; } static void SoftRenderPatchIds(void) { SoftRenderPatches(PatchID); } unsigned long *SoftRenderIds(long *x, long *y) { SGL_CONTEXT *sgl, *oldsgl; unsigned long *ids; if (sizeof(SGL_PIXEL)!=sizeof(long)) { Fatal(-1, "SoftRenderIds", "sizeof(SGL_PIXEL)!=sizeof(long). Disable SOFT_ID_RENDERING"); } oldsgl = sglGetCurrent(); sgl = SetupSoftFrameBuffer(); SoftRenderPatchIds(); *x = sgl->width; *y = sgl->height; ids = (unsigned long *)Alloc((int)(*x) * (int)(*y) * sizeof(unsigned long)); memcpy(ids, sgl->fbuf, sgl->width*sgl->height*sizeof(long)); sglClose(sgl); sglMakeCurrent(oldsgl); return ids; }