void updateFrustumPoints(frustum_t &f, camera_t *v) { vec3_t up, right, forward; vec3_t nc, fc, tmp1, tmp2; vec3_t gl_up_vec = {0,1,0}; vec3_t center; M_MultVec3(v->viewaxis[AXIS_FORWARD], 1, forward); right[0] = forward[1]; forward[1] = forward[2]; forward[2] = right[0]; M_MultVec3(v->origin, 1, center); right[0] = center[1]; center[1] = center[2]; center[2] = right[0]; //f.bmax[AXIS_Z] = v->farclip; //f.bmin[AXIS_Z] = v->nearclip; M_MultVec3(forward, f.bmax[AXIS_Z], fc); M_AddVec3(fc, center, fc); M_MultVec3(forward, f.bmin[AXIS_Z], nc); M_AddVec3(nc, center, nc); M_CrossProduct(forward, gl_up_vec, right); M_Normalize(right); M_CrossProduct(right, forward, up); M_Normalize(up); float near_height = tan(f.fov/2.0f) * f.bmin[AXIS_Z]; float near_width = near_height*f.ratio; float far_height = tan(f.fov/2.0f) * f.bmax[AXIS_Z]; float far_width = far_height*f.ratio; M_MultVec3(up, near_height, tmp1); M_MultVec3(right, near_width, tmp2); M_SubVec3(nc, tmp1, f.point[0]); M_SubVec3(f.point[0], tmp2, f.point[0]); M_AddVec3(nc, tmp1, f.point[1]); M_SubVec3(f.point[1], tmp2, f.point[1]); M_AddVec3(nc, tmp1, f.point[2]); M_AddVec3(f.point[2], tmp2, f.point[2]); M_SubVec3(nc, tmp1, f.point[3]); M_AddVec3(f.point[3], tmp2, f.point[3]); M_MultVec3(up, far_height, tmp1); M_MultVec3(right, far_width, tmp2); M_SubVec3(fc, tmp1, f.point[4]); M_SubVec3(f.point[4], tmp2, f.point[4]); M_AddVec3(fc, tmp1, f.point[5]); M_SubVec3(f.point[5], tmp2, f.point[5]); M_AddVec3(fc, tmp1, f.point[6]); M_AddVec3(f.point[6], tmp2, f.point[6]); M_SubVec3(fc, tmp1, f.point[7]); M_AddVec3(f.point[7], tmp2, f.point[7]); }
void Scene_BuildVolume(const vec3_t point, const vec3_t poly[], int numpoints, plane_t planes[]) { int n; vec3_t forward; M_CalcPlane(poly[0], poly[1], poly[2], &planes[numpoints]); M_SubVec3(poly[0], point, forward); //determine corner winding if (M_DotProduct(planes[numpoints].normal, forward) > 0) { for (n=0; n<numpoints; n++) { M_CalcPlane(point, poly[n], poly[(n+1) % numpoints], &planes[n]); } } else { M_FlipVec3(planes[numpoints].normal, planes[numpoints].normal); planes[numpoints].dist = -planes[numpoints].dist; for (n=0; n<numpoints; n++) { M_CalcPlane(poly[(n+1) % numpoints], poly[n], point, &planes[n]); } } }
bool OcTree::within(const sceneobj_t *sc) { vec3_t bmin, bmax, edgeVec; SET_VEC3(edgeVec, edge*0.5f, edge*0.5f, edge*0.25f); M_SubVec3(pos, edgeVec, bmin); M_AddVec3(pos, edgeVec, bmax); if (!M_PointInBounds(sc->pos, bmin, bmax)) return false; //if it's a model, make sure it's completely within if(sc->objtype == OBJTYPE_MODEL) { vec3_t meshmin, meshmax; model_t *mesh = Res_GetModel(sc->model); M_MultVec3(mesh->bmin, sc->scale, meshmin); M_MultVec3(mesh->bmax, sc->scale, meshmax); meshmax[AXIS_Z] *= 0.25f; meshmin[AXIS_Z] *= 0.25f; M_AddVec3(meshmin, sc->pos, meshmin); M_AddVec3(meshmax, sc->pos, meshmax); if(!M_PointInBounds(meshmin, bmin, bmax) || !M_PointInBounds(meshmax, bmin, bmax)) return false; } return true; }
bool OcTree::isVisible(const camera_t *c) { if(visibilityTested) return visible; if(!parent) visible=true; else visible = parent->visible; if(visible) { vec3_t bmin, bmax, edgeVec; SET_VEC3(edgeVec, edge*0.5f, edge*0.5f, edge*0.25f); M_SubVec3(pos, edgeVec, bmin); M_AddVec3(pos, edgeVec, bmax); visible = Scene_AABBInFrustum(bmin, bmax, false); if(visible){ //ok it has a parent, and it's still visible- //test it against occluders if(!(c->flags & CAM_NO_OCCLUDERS)) visible = Scene_AABBIsVisible(bmin, bmax, false); } } visibilityTested = true; return visible; }
void OcTree::draw() { vec3_t bmin, bmax, edgeVec; SET_VEC3(edgeVec, edge*0.5f, edge*0.5f, edge*0.25f); M_SubVec3(pos, edgeVec, bmin); M_AddVec3(pos, edgeVec, bmax); GL_DrawBox(bmin, bmax); }
bool OcTree::within(const vec3_t bm, const vec3_t bx) { vec3_t bmin, bmax, edgeVec; SET_VEC3(edgeVec, edge*0.5f, edge*0.5f, edge*0.25f); M_SubVec3(pos, edgeVec, bmin); M_AddVec3(pos, edgeVec, bmax); if(!M_PointInBounds(bm, bmin, bmax) || !M_PointInBounds(bx, bmin, bmax)) return false; return true; }
void GL_RenderScene(camera_t *camera, vec3_t userpos, unsigned int sceneRenderFlags) { if (!world.cl_loaded || !gfx_render.integer) { //GL_2dMode(); return; } static float lasttime=0; camera_t sunCam; Pass basePass; worldLight_t rimLight; float lerp; float ambBoost = (vid_realbright.integer && gfx_GLSLQuality.integer<=1) ? vid_realbrightMult.value : 1.0f; basePass.setViewer(camera); scene_cam = camera; sunLight.origin[0] = -wr_sun_x.value; sunLight.origin[1] = -wr_sun_y.value; sunLight.origin[2] = -wr_sun_z.value; memset(&rimLight, 0, sizeof(worldLight_t)); M_MultVec3(sunLight.origin, -1, rimLight.origin); rimLight.type = LIGHT_DIRECTIONAL; //// SHADOW MAP RENDER //// //shadow pass, render to texture if(gfx_shadow.integer && gfx_shadowQuality.integer >= 1 && gfx_GLSLQuality.integer>1) { vec3_t wmin, wmax, sunLook; World_GetBounds(wmin, wmax); //SET_VEC3(sunLook, (wmax[0]-wmin[0])*.5f, (wmax[1]-wmin[1])*.5f, 0 * .5f); M_MultVec3(camera->viewaxis[AXIS_FORWARD], camera->farclip*0.05, sunLook); M_AddVec2(sunLook, camera->origin, sunLook); Cam_DefaultCamera(&sunCam, gfx_shadowSize.integer, gfx_shadowSize.integer, 2, 8192); if(wr_sun_z.value < 0) { SET_VEC3(sunCam.origin, -wr_sun_x.value, -wr_sun_y.value, -wr_sun_z.value); } else { SET_VEC3(sunCam.origin, wr_sun_x.value, wr_sun_y.value, wr_sun_z.value); } M_Normalize(sunCam.origin); M_MultVec3(sunCam.origin, wmax[0], sunCam.origin); sunCam.origin[0]+=sunLook[0]; sunCam.origin[1]+=sunLook[1]; M_SubVec3(sunLook, sunCam.origin, sunCam.viewaxis[AXIS_FORWARD]); M_GetAxisFromForwardVec(sunCam.viewaxis[AXIS_FORWARD], sunCam.viewaxis); sunCam.fovy = 50; sunCam.time = camera->time; sunCam.fog_far=100000; sunCam.fog_near=99999; sunCam.flags |= CAM_NO_SKY; //CSM setup if(gfx_shadowQuality.integer >= 2) { shadowSplit=0; for(int i=0;i<gfx_shadowQuality.integer;i++) { cascadedPass[i].setViewer(&sunCam); renderer.addPass(&cascadedPass[i]); } } else { shadowPass.setViewer(&sunCam); renderer.addPass(&shadowPass); } } else if( gfx_GLSLQuality.integer > 1 ) { renderer.addPass(&shadowPass); } if(gfx_postProcEnabled.integer && gfx_GLSLQuality.integer>1 && (gfx_depthNormalPass.integer || gfx_postSSAO.integer)) { zPass->setViewer(camera); renderer.addPass(zPass); } basePass.setDepthFunc(GL_LEQUAL); basePass.setDepthMask(true); basePass.clearDepth(true); if(gfx_GLSLQuality.integer>1 && gfx_postProcessing.integer) basePass.setTarget(screenPostTarget); else basePass.setTarget(glScreen); renderer.addPass(&basePass); //// BUILD RENDER LIST //// // sun/moon if(wr_sun_z.value < 0) { lerp = CLAMP(fabs(-1 - cos(wr_sun_phi.value)), 0, 1); //Console_Printf("phi %f lerp %f\n", wr_sun_phi.value, lerp); //setup sun light color and ambient sunLight.ambient[0] = obj_ambient_r.value*ambBoost; sunLight.ambient[1] = obj_ambient_g.value*ambBoost; sunLight.ambient[2] = obj_ambient_b.value*ambBoost; sunLight.color[0] = obj_light0_r.value*.9; sunLight.color[1] = obj_light0_g.value*.9; sunLight.color[2] = obj_light0_b.value*.98; rimLight.ambient[0] = 0; rimLight.ambient[1] = 0; rimLight.ambient[2] = 0; rimLight.color[0] = lerp*obj_light1_r.value*.9; rimLight.color[1] = lerp*obj_light1_g.value*.9; rimLight.color[2] = lerp*obj_light1_b.value*.98; } else { if(wr_sun_phi.value < 5.23f && wr_sun_phi.value > 1.0472f) lerp = CLAMP(fabs(1-cos(3*(M_PI-wr_sun_phi.value))), 0, 1); else lerp = 0; //Console_Printf("phi %f lerp %f cos %f\n", wr_sun_phi.value, lerp, cos(3*(M_PI-wr_sun_phi.value))); //the lights need to flip M_MultVec3(sunLight.origin, -1, sunLight.origin); M_MultVec3(rimLight.origin, -1, rimLight.origin); //setup moon light color and ambient sunLight.ambient[0] = obj_ambient_r.value*ambBoost; sunLight.ambient[1] = obj_ambient_g.value*ambBoost; sunLight.ambient[2] = obj_ambient_b.value*ambBoost; sunLight.color[0] = obj_light1_r.value*.9; sunLight.color[1] = obj_light1_g.value*.9; sunLight.color[2] = obj_light1_b.value*.98; rimLight.ambient[0] = 0; rimLight.ambient[1] = 0; rimLight.ambient[2] = 0; rimLight.color[0] = lerp*obj_light0_r.value*.9; rimLight.color[1] = lerp*obj_light0_g.value*.9; rimLight.color[2] = lerp*obj_light0_b.value*.98; } renderer.addLight(&sunLight, NULL, 0); renderer.addLight(&rimLight, NULL, 0); // The deal here is rather than changing the code in scene.cpp to support the // new renderer, we just "import" all the scene data //// SCENE DATA //// lightCount = 0; //objects scenelist_t *list; for (list = scenelist; list; list = list->next) { //if(list->cull) // continue; switch (list->obj.objtype) { case OBJTYPE_MODEL: GL_AddModelToLists(&list->obj); break; case OBJTYPE_LIGHT: GL_AddLight(0, &list->obj); break; default: break; } } //polys scenefacelist_t *flist; for (flist = scenefacelist; flist; flist = flist->next) { renderer.addPoly(flist, NULL, flist->shader); } //decals for (flist = scenefacelist_decals; flist; flist = flist->next) { renderer.addPoly(flist, NULL, flist->shader); } //lights scenelightlist_t *llist; for (llist = scenelightlist; llist; llist = llist->next) { worldLight_t *l = &worldlights[lightCount++]; M_CopyVec3(llist->light.color, l->color); M_CopyVec3(llist->light.pos, l->origin); renderer.addLight(l, NULL, 0); } //// END SCENE DATA //// //// ENVIRO //// if(!(camera->flags & CAM_NO_WORLD)) { //terrain if (!(scene_cam->flags & CAM_NO_TERRAIN)) renderer.addCustomListItem(&terrainItem, false); //sprites for (std::list<scenelist_t*>::iterator itr = spritelist.begin(); itr != spritelist.end(); itr++) { scenelist_t *sprite = *itr; renderer.addSprite(sprite, &sprite->obj, sprite->obj.shader); } //clouds (at the back) if(gfx_sky.integer) { renderer.addCustomListItem(&cloudsItem, false); } if(gfx_water.integer) { waterItem.set(NULL,NULL,0); renderer.addCustomListItem(&waterItem, false); } //sky if (gfx_sky.integer) { if(Cvar_GetInteger("tl_suntod") <= 1440) sky.setTimeofDay(Cvar_GetValue("tl_suntod")/1440.0f); else sky.setTimeofDay((Cvar_GetValue("tod_sunminute"))/1440.0f); //renderer.addListItem(&clouds, false); renderer.addCustomListItem(&sky, false); } //// FX LAYER //// //polys for (flist = scenefxfacelist; flist; flist = flist->next) { renderer.addPolyFX(flist, NULL, flist->shader); } //decals for (flist = scenefxfacelist_decals; flist; flist = flist->next) { renderer.addPolyFX(flist, NULL, flist->shader); } //sprites for (std::list<scenelist_t*>::iterator itr = spritefxlist.begin(); itr != spritefxlist.end(); itr++) { scenelist_t *sprite = *itr; renderer.addSpriteFX(sprite, &sprite->obj, sprite->obj.shader); } } //// RENDER //// renderer.render(camera->time-lasttime); lasttime = camera->time; }
// // R_CalcSlope // // SoM: Calculates the rslope info from the OHV vectors and rotation/offset // information in the plane struct // static void R_CalcSlope(visplane_t *pl) { // This is where the crap gets calculated. Yay double xl, yl, tsin, tcos; double ixscale, iyscale; rslope_t *rslope = &pl->rslope; texture_t *tex = textures[pl->picnum]; if(!pl->pslope) return; tsin = sin(pl->angle); tcos = cos(pl->angle); xl = tex->width; yl = tex->height; // SoM: To change the origin of rotation, add an offset to P.x and P.z // SoM: Add offsets? YAH! rslope->P.x = -pl->xoffsf * tcos - pl->yoffsf * tsin; rslope->P.z = -pl->xoffsf * tsin + pl->yoffsf * tcos; rslope->P.y = P_GetZAtf(pl->pslope, (float)rslope->P.x, (float)rslope->P.z); rslope->M.x = rslope->P.x - xl * tsin; rslope->M.z = rslope->P.z + xl * tcos; rslope->M.y = P_GetZAtf(pl->pslope, (float)rslope->M.x, (float)rslope->M.z); rslope->N.x = rslope->P.x + yl * tcos; rslope->N.z = rslope->P.z + yl * tsin; rslope->N.y = P_GetZAtf(pl->pslope, (float)rslope->N.x, (float)rslope->N.z); M_TranslateVec3(&rslope->P); M_TranslateVec3(&rslope->M); M_TranslateVec3(&rslope->N); M_SubVec3(&rslope->M, &rslope->M, &rslope->P); M_SubVec3(&rslope->N, &rslope->N, &rslope->P); M_CrossProduct3(&rslope->A, &rslope->P, &rslope->N); M_CrossProduct3(&rslope->B, &rslope->P, &rslope->M); M_CrossProduct3(&rslope->C, &rslope->M, &rslope->N); // This is helpful for removing some of the muls when calculating light. rslope->A.x *= 0.5f; rslope->A.y *= 0.5f / view.focratio; rslope->A.z *= 0.5f; rslope->B.x *= 0.5f; rslope->B.y *= 0.5f / view.focratio; rslope->B.z *= 0.5f; rslope->C.x *= 0.5f; rslope->C.y *= 0.5f / view.focratio; rslope->C.z *= 0.5f; rslope->zat = P_GetZAtf(pl->pslope, pl->viewxf, pl->viewyf); // More help from randy. I was totally lost on this... ixscale = view.tan / (float)xl; iyscale = view.tan / (float)yl; rslope->plight = (slopevis * ixscale * iyscale) / (rslope->zat - pl->viewzf); rslope->shade = 256.0f * 2.0f - (pl->lightlevel + 16.0f) * 256.0f / 128.0f; }
void Scene_SetFrustum(camera_t *camera, vec4_t rect) { vec3_t eye, viewdir, viewup, viewright; float xfov, yfov; float wr, wl, wt, wb; float tanx, tany; vec3_t spts[4]; vec3_t offset; //vec3_t farpoint, nearpoint; //vec3_t bmin, bmax; //vec3_t raydir, bpoint; //vec3_t inv_viewdir; //vec3_t toward s; vec3_t p1,p2; int n; vec3_t invViewDir; if (gfx_lockfrustum.integer) return; M_CopyVec3(camera->viewaxis[AXIS_RIGHT], viewright); M_CopyVec3(camera->viewaxis[AXIS_FORWARD], viewdir); M_CopyVec3(camera->viewaxis[AXIS_UP], viewup); M_CopyVec3(camera->origin, eye); M_FlipVec3(viewdir, invViewDir); yfov = DEG2RAD(camera->fovy); xfov = DEG2RAD(camera->fovx); tanx=tan(xfov*0.5); tany=tan(yfov*0.5); // wl = wr * ((((selectionRect_x1) / (float)camera->width) - 0.5) * 2); // wb = wt * ((((camera->height - selectionRect_y2) / (float)camera->height) - 0.5) * 2); // wt *= ((((camera->height - selectionRect_y1) / (float)camera->height) - 0.5) * 2); // wr *= (((selectionRect_x2) / (float)camera->width) - 0.5) * 2; wl = tanx * (((rect[0] / (float)camera->width) - 0.5) * 2); wr = tanx * (((rect[2] / (float)camera->width) - 0.5) * 2); wb = tany * (((rect[1] / (float)camera->height) - 0.5) * 2); wt = tany * (((rect[3] / (float)camera->height) - 0.5) * 2); M_AddVec3(camera->origin, viewdir, offset); for (n=0; n<3; n++) { spts[0][n] = viewright[n]*wr + viewup[n]*wt + offset[n]; //top-right point spts[1][n] = viewright[n]*wl + viewup[n]*wt + offset[n]; //top-left point spts[2][n] = viewright[n]*wl + viewup[n]*wb + offset[n]; //bottom-left point spts[3][n] = viewright[n]*wr + viewup[n]*wb + offset[n]; //bottom-right point } M_CalcPlane(spts[1], spts[0], eye, &frustum[0]); //top plane M_CalcPlane(spts[2], spts[1], eye, &frustum[1]); //left plane M_CalcPlane(spts[3], spts[2], eye, &frustum[2]); //bottom plane M_CalcPlane(spts[0], spts[3], eye, &frustum[3]); //right plane //far plane M_PointOnLine(camera->origin, viewdir, camera->farclip, p1); M_CopyVec3(invViewDir, frustum[4].normal); frustum[4].dist = M_DotProduct(invViewDir, p1); //near plane M_PointOnLine(camera->origin, viewdir, camera->nearclip, p1); M_CopyVec3(viewdir, frustum[5].normal); frustum[5].dist = M_DotProduct(viewdir, p1); //compute frustum bounding box (for Scene_ClipBounds) //this is not a very efficient way to do this M_ClearBounds(camera->frustum_bmin, camera->frustum_bmax); M_AddPointToBounds(spts[0], camera->frustum_bmin, camera->frustum_bmax); M_AddPointToBounds(spts[1], camera->frustum_bmin, camera->frustum_bmax); M_AddPointToBounds(spts[2], camera->frustum_bmin, camera->frustum_bmax); M_AddPointToBounds(spts[3], camera->frustum_bmin, camera->frustum_bmax); M_SubVec3(spts[0], camera->origin, p1); M_Normalize(p1); M_PointOnLine(camera->origin, p1, camera->farclip, p2); M_AddPointToBounds(p2, camera->frustum_bmin, camera->frustum_bmax); M_SubVec3(spts[1], camera->origin, p1); M_Normalize(p1); M_PointOnLine(camera->origin, p1, camera->farclip, p2); M_AddPointToBounds(p2, camera->frustum_bmin, camera->frustum_bmax); M_SubVec3(spts[2], camera->origin, p1); M_Normalize(p1); M_PointOnLine(camera->origin, p1, camera->farclip, p2); M_AddPointToBounds(p2, camera->frustum_bmin, camera->frustum_bmax); M_SubVec3(spts[3], camera->origin, p1); M_Normalize(p1); M_PointOnLine(camera->origin, p1, camera->farclip, p2); M_AddPointToBounds(p2, camera->frustum_bmin, camera->frustum_bmax); /* M_ClearBounds(bmin, bmax); Cam_ConstructRay(camera, 0, 0, raydir); M_MultVec3(raydir, gfx_farclip.value, raydir); M_AddVec3(eye, raydir, bpoint); M_AddPointToBounds(bpoint, bmin, bmax); Cam_ConstructRay(camera, camera->width, 0, raydir); M_MultVec3(raydir, gfx_farclip.value, raydir); M_AddVec3(eye, raydir, bpoint); M_AddPointToBounds(bpoint, bmin, bmax); Cam_ConstructRay(camera, 0, camera->height, raydir); M_MultVec3(raydir, gfx_farclip.value, raydir); M_AddVec3(eye, raydir, bpoint); M_AddPointToBounds(bpoint, bmin, bmax); Cam_ConstructRay(camera, camera->width, camera->height, raydir); M_MultVec3(raydir, gfx_farclip.value, raydir); M_AddVec3(eye, raydir, bpoint); M_AddPointToBounds(bpoint, bmin, bmax); M_AddPointToBounds(nearpoint, bmin, bmax); M_CopyVec3(bmin, frustum_bmin); M_CopyVec3(bmax, frustum_bmax); */ }