public void Intersect(idScreenRect rect) { if (rect.X1 > this.X1) { this.X1 = rect.X1; } if (rect.X2 < this.X2) { this.X2 = rect.X2; } if (rect.Y1 > this.Y1) { this.Y1 = rect.Y1; } if (rect.Y2 < this.Y2) { this.Y2 = rect.Y2; } }
public void Union(idScreenRect rect) { if (rect.X1 < this.X1) { this.X1 = rect.X1; } if (rect.X2 > this.X2) { this.X2 = rect.X2; } if (rect.Y1 < this.Y1) { this.Y1 = rect.Y1; } if (rect.Y2 > this.Y2) { this.Y2 = rect.Y2; } }
public void Intersect(idScreenRect rect) { if(rect.X1 > this.X1) { this.X1 = rect.X1; } if(rect.X2 < this.X2) { this.X2 = rect.X2; } if(rect.Y1 > this.Y1) { this.Y1 = rect.Y1; } if(rect.Y2 < this.Y2) { this.Y2 = rect.Y2; } }
public void Union(idScreenRect rect) { if(rect.X1 < this.X1) { this.X1 = rect.X1; } if(rect.X2 > this.X2) { this.X2 = rect.X2; } if(rect.Y1 < this.Y1) { this.Y1 = rect.Y1; } if(rect.Y2 > this.Y2) { this.Y2 = rect.Y2; } }
private idScreenRect ScreenRectangleFromWinding(idWinding winding, ViewEntity space) { idScreenRect rect = new idScreenRect(); Vector3 v, ndc; View viewDef = idE.RenderSystem.ViewDefinition; for(int i = 0; i < winding.PointCount; i++) { idHelper.LocalPointToGlobal(space.ModelMatrix, winding[i], out v); idHelper.GlobalToNormalizedDeviceCoordinates(v, out ndc); float windowX = 0.5f * (1.0f + ndc.X) * (viewDef.ViewPort.X2 - viewDef.ViewPort.X1); float windowY = 0.5f * (1.0f + ndc.Y) * (viewDef.ViewPort.Y2 - viewDef.ViewPort.Y1); rect.AddPoint(windowX, windowY); } rect.Expand(); return rect; }
private void ParseInterAreaPortals(idLexer lexer) { lexer.ExpectTokenString("{"); _portalAreaCount = lexer.ParseInt(); if(_portalAreaCount < 0) { lexer.Error("ParseInterAreaPortals: bad portalAreaCount"); } _portalAreas = new PortalArea[_portalAreaCount]; _areaScreenRect = new idScreenRect[_portalAreaCount]; for(int i = 0; i < _portalAreaCount; i++) { _portalAreas[i] = new PortalArea(); _areaScreenRect[i] = new idScreenRect(); } // set the doubly linked lists SetupAreaReferences(); _interAreaPortalCount = lexer.ParseInt(); if(_interAreaPortalCount < 0) { lexer.Error("ParseInterAreaPortals: bad interAreaPortalCount"); } _doublePortals = new DoublePortal[_interAreaPortalCount]; for(int i = 0; i < _interAreaPortalCount; i++) { _doublePortals[i] = new DoublePortal(); int pointCount = lexer.ParseInt(); int a1 = lexer.ParseInt(); int a2 = lexer.ParseInt(); idWinding w = new idWinding(pointCount); for(int j = 0; j < pointCount; j++) { float[] tmp = lexer.Parse1DMatrix(3); w[j,0] = tmp[0]; w[j,1] = tmp[1]; w[j,2] = tmp[2]; // no texture coordinates w[j,3] = 0; w[j,4] = 0; } // add the portal to a1 Portal p = new Portal(); p.IntoArea = a2; p.DoublePortal = _doublePortals[i]; p.Winding = w; p.Plane = w.GetPlane(); p.Next = _portalAreas[a1].Portals; _portalAreas[a1].Portals = p; _doublePortals[i].Portals[0] = p; // reverse it for a2 p = new Portal(); p.IntoArea = a1; p.DoublePortal = _doublePortals[i]; p.Winding = w.Reverse(); p.Plane = w.GetPlane(); p.Next = _portalAreas[a2].Portals; _portalAreas[a2].Portals = p; _doublePortals[i].Portals[1] = p; } lexer.ExpectTokenString("}"); }
/// <summary> /// Finds viewLights and viewEntities by flowing from an origin through the visible portals. /// origin point can see into. The planes array defines a volume (positive /// sides facing in) that should contain the origin, such as a view frustum or a point light box. /// Zero planes assumes an unbounded volume. /// </summary> /// <param name="origin"></param> /// <param name="planes"></param> private void FlowViewThroughPortals(Vector3 origin, int planeCount, Plane[] planes) { View viewDef = idE.RenderSystem.ViewDefinition; PortalStack portalStack = new PortalStack(); portalStack.Rectangle = viewDef.Scissor; portalStack.PortalPlaneCount = planeCount; for(int i = 0; i < planeCount; i++) { portalStack.PortalPlanes[i] = planes[i]; } if(viewDef.AreaNumber < 0) { for(int i = 0; i < _portalAreaCount; i++) { _areaScreenRect[i] = viewDef.Scissor; } // if outside the world, mark everything for(int i = 0; i < _portalAreaCount; i++) { AddAreaReferences(i, portalStack); } } else { for(int i = 0; i < _portalAreaCount; i++) { _areaScreenRect[i] = new idScreenRect(); } // flood out through portals, setting area viewCount FloodViewThroughArea(origin, viewDef.AreaNumber, portalStack); } }
public void AddDrawSurface(Surface surface, ViewEntity space, RenderEntityComponent renderEntity, idMaterial material, idScreenRect scissor) { float[] materialParameters; float[] referenceRegisters = new float[idE.MaxExpressionRegisters]; float[] generatedMaterialParameters = new float[idE.MaxEntityMaterialParameters]; DrawSurface drawSurface = new DrawSurface(); drawSurface.Geometry = surface; drawSurface.Space = space; drawSurface.Material = material; drawSurface.ScissorRectangle = scissor; drawSurface.Sort = (float) material.Sort + _sortOffset; // bumping this offset each time causes surfaces with equal sort orders to still // deterministically draw in the order they are added _sortOffset += 0.000001f; // process the shader expressions for conditionals / color / texcoords float[] constantRegisters = material.ConstantRegisters; if(constantRegisters != null) { // shader only uses constant values drawSurface.MaterialRegisters = constantRegisters; } else { drawSurface.MaterialRegisters = new float[material.RegisterCount]; // a reference shader will take the calculated stage color value from another shader // and use that for the parm0-parm3 of the current shader, which allows a stage of // a light model and light flares to pick up different flashing tables from // different light shaders if(renderEntity.ReferenceMaterial != null) { // evaluate the reference shader to find our shader parms //renderEntity.ReferenceMaterial.EvaluateRegisters(ref referenceRegisters, renderEntity.MaterialParameters, this.ViewDefinition, renderEntity.ReferenceSound); idConsole.Warning("TODO: ref material"); /*MaterialStage stage = renderEntity.ReferenceMaterial.GetStage(0); memcpy( generatedShaderParms, renderEntity->shaderParms, sizeof( generatedShaderParms ) ); generatedShaderParms[0] = refRegs[ pStage->color.registers[0] ]; generatedShaderParms[1] = refRegs[ pStage->color.registers[1] ]; generatedShaderParms[2] = refRegs[ pStage->color.registers[2] ];*/ materialParameters = generatedMaterialParameters; } else { // evaluate with the entityDef's shader parms materialParameters = renderEntity.MaterialParameters; } float oldFloatTime = 0; int oldTime = 0; if((space.EntityDef != null) && (space.EntityDef.Parameters.TimeGroup != 0)) { oldFloatTime = this.ViewDefinition.FloatTime; oldTime = this.ViewDefinition.RenderView.Time; this.ViewDefinition.FloatTime = idE.Game.GetTimeGroupTime(space.EntityDef.Parameters.TimeGroup) * 0.001f; this.ViewDefinition.RenderView.Time = idE.Game.GetTimeGroupTime(space.EntityDef.Parameters.TimeGroup); } material.EvaluateRegisters(ref drawSurface.MaterialRegisters, materialParameters, idE.RenderSystem.ViewDefinition /* TODO: ,renderEntity->referenceSound*/); if((space.EntityDef != null) && (space.EntityDef.Parameters.TimeGroup != 0)) { this.ViewDefinition.FloatTime = oldFloatTime; this.ViewDefinition.RenderView.Time = oldTime; } } // check for deformations // TODO: R_DeformDrawSurf( drawSurf ); // skybox surfaces need a dynamic texgen // TODO: skybox /*switch( shader->Texgen() ) { case TG_SKYBOX_CUBE: R_SkyboxTexGen( drawSurf, tr.viewDef->renderView.vieworg ); break; case TG_WOBBLESKY_CUBE: R_WobbleskyTexGen( drawSurf, tr.viewDef->renderView.vieworg ); break; }*/ // check for gui surfaces // TODO: gui surface idUserInterface gui = null; if(space.EntityDef == null) { gui = material.GlobalInterface; } else { idConsole.Warning("TODO: global gui"); /*int guiNum = shader->GetEntityGui() - 1; if ( guiNum >= 0 && guiNum < MAX_RENDERENTITY_GUI ) { gui = renderEntity->gui[ guiNum ]; } if ( gui == NULL ) { gui = shader->GlobalGui(); }*/ } if(gui != null) { // force guis on the fast time float oldFloatTime = this.ViewDefinition.FloatTime; int oldTime = this.ViewDefinition.RenderView.Time; this.ViewDefinition.FloatTime = idE.Game.GetTimeGroupTime(1) * 0.001f; this.ViewDefinition.RenderView.Time = idE.Game.GetTimeGroupTime(1); idBounds ndcBounds; idConsole.Warning("TODO: precise cull + render gui surface"); /*if ( !R_PreciseCullSurface( drawSurf, ndcBounds ) ) { // did we ever use this to forward an entity color to a gui that didn't set color? // memcpy( tr.guiShaderParms, shaderParms, sizeof( tr.guiShaderParms ) ); R_RenderGuiSurf( gui, drawSurf ); }*/ this.ViewDefinition.FloatTime = oldFloatTime; this.ViewDefinition.RenderView.Time = oldTime; } _viewDefinition.DrawSurfaces.Add(drawSurface); // we can't add subviews at this point, because that would // increment tr.viewCount, messing up the rest of the surface // adds for this view }
/// <summary> /// Converts from SCREEN_WIDTH / SCREEN_HEIGHT coordinates to current cropped pixel coordinates /// </summary> /// <param name="renderView"></param> /// <returns></returns> public idScreenRect RenderViewToViewPort(idRenderView renderView) { idRectangle renderCrop = _renderCrops[_currentRenderCrop]; float widthRatio = (float) renderCrop.Width / idE.VirtualScreenWidth; float heightRatio = (float) renderCrop.Height / idE.VirtualScreenHeight; idScreenRect viewPort = new idScreenRect(); viewPort.X1 = (short) (renderCrop.X + renderView.X * widthRatio); viewPort.X2 = (short) ((renderCrop.X + idMath.Floor(renderView.X + renderView.Width) * widthRatio + 0.5f) - 1); viewPort.Y1 = (short) ((renderCrop.Y + renderCrop.Height) - idMath.Floor((renderView.Y + renderView.Height) * heightRatio + 0.5f)); viewPort.Y2 = (short) ((renderCrop.Y + renderCrop.Height) - idMath.Floor(renderView.Y * heightRatio + 0.5f) - 1); return viewPort; }