Пример #1
0
void Renderer::RenderFrame(float time) {
  time_ = time;

  SetupFrame();

  // draw scene
  Setup3DRendering();

  glBindBuffer(GL_ARRAY_BUFFER, world.map_->vboId);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, world.map_->iboId);
  glEnableVertexAttribArray(2);
  for (unsigned int i = 0; i < renderables_.size(); ++i) {
    RenderFace(renderables_[i]);
  }

  RenderModel();
  // draw gui and overlays
  // Setup2DRendering();

  // font.PrintString("<Q3 BSP RENDERER>", glm::vec2(10.0f, 10.0f),
  // glm::vec4(1.0, 0.0, 0.0, 1.0));

  //  if (delta == 0) delta = 1;
  //
  //    std::stringstream fps;
  //    fps << "frametime in ms: " << delta << " fps: " << 1000 / delta;
  //    font.PrintString(fps.str(), glm::vec2(10.0f,
  //    (float)screen_height_-20.0f), glm::vec4(1.0, 1.0, 1.0, 1.0));
}
Пример #2
0
void Quake3BSP_GL::RenderLevel(unsigned int bufferID)
{
	// Get the number of faces in our level
	int i = m_numOfLeafs;
	int leafIndex;

	if(!Camera::GetInstance().getVisibilityState()){
		// Finding the leaf the camera is in
		m_cameraPos = Camera::GetInstance().GetCamEye();
		leafIndex = FindLeaf(0,m_cameraPos);
		// Once the leaf is found, reset the bools for leaf searching
		m_foundLeaf=false;
		m_foundIndex=0;
	} else {
		// We are in a frozen state for visibility, so use the last stored camera position,
		// don't get the updated one.
		leafIndex = FindLeaf(0,m_cameraPos);
		// Once the leaf is found, reset the bools for leaf searching
		m_foundLeaf=false;
		m_foundIndex=0;
	}

	// Getting the cluster that leaf is assigned to
	int cluster = m_pLeafs[leafIndex].cluster;

	// Go through the BSP tree checking to draw only what is visible from our
	// current cluster and what is visible within the frustum
	while(i--)
	{
		// Getting the current leaf to check with our camera's leaf
		BSPLeaf *pLeaf = &(m_pLeafs[i]);

		// Cluster Visiblity check
		if(!IsClusterValid(cluster, pLeaf->cluster)) 
			continue;

		// Frustum visibility check
		if(!ViewFrustum::GetInstance().RectangleIntersect((float)pLeaf->min.x, (float)pLeaf->min.y, (float)pLeaf->min.z,
														  (float)pLeaf->max.x, (float)pLeaf->max.y, (float)pLeaf->max.z)){
			continue;
		}
		
		// The leaf must be valid to draw, set the counter for his number
		// of faces, then call RenderFaces to draw them all.
		int faceTotal = pLeaf->numOfLeafFaces;

		// Loop through and render all of the faces in this leaf
		while(faceTotal--)
		{
			int faceIndex = m_pLeafFaces[pLeaf->leafface + faceTotal];

			// Check if this is a valid face to draw
			if(m_pFaces[faceIndex].type != FACE_POLYGON)
				continue;

			RenderFace(bufferID, faceIndex);
		}
	}
}
Пример #3
0
void CQuake3BSP::RenderLevel(const CVector3 &vPos)
{
    // Reset our bitset so all the slots are zero.
    m_FacesDrawn.ClearAll();

    // Grab the leaf index that our camera is in
    int leafIndex = FindLeaf(vPos);

    // Grab the cluster that is assigned to the leaf
    int cluster = m_pLeafs[leafIndex].cluster;

    // Initialize our counter variables (start at the last leaf and work down)
    int i = m_numOfLeafs;
    g_VisibleFaces = 0;

    // Go through all the leafs and check their visibility
    while(i--)
    {
        // Get the current leaf that is to be tested for visibility from our camera's leaf
        tBSPLeaf *pLeaf = &(m_pLeafs[i]);

        // If the current leaf can't be seen from our cluster, go to the next leaf
        if(!IsClusterVisible(cluster, pLeaf->cluster))
            continue;

        // If the current leaf is not in the camera's frustum, go to the next leaf
        if(!g_Frustum.BoxInFrustum((float)pLeaf->min.x, (float)pLeaf->min.y, (float)pLeaf->min.z,
                                   (float)pLeaf->max.x, (float)pLeaf->max.y, (float)pLeaf->max.z))
            continue;

        // If we get here, the leaf we are testing must be visible in our camera's view.
        // Get the number of faces that this leaf is in charge of.
        int faceCount = pLeaf->numOfLeafFaces;

        // Loop through and render all of the faces in this leaf
        while(faceCount--)
        {
            // Grab the current face index from our leaf faces array
            int faceIndex = m_pLeafFaces[pLeaf->leafface + faceCount];

            // Before drawing this face, make sure it's a normal polygon
            if(m_pFaces[faceIndex].type != FACE_POLYGON) continue;

            // Since many faces are duplicated in other leafs, we need to
            // make sure this face already hasn't been drawn.
            if(!m_FacesDrawn.On(faceIndex))
            {
                // Increase the rendered face count to display for fun
                g_VisibleFaces++;

                // Set this face as drawn and render it
                m_FacesDrawn.Set(faceIndex);
                RenderFace(faceIndex);
            }
        }
    }
}
Пример #4
0
void RenderSide (CSegment *segP, short nSide)
{
	CSide			*sideP = segP->m_sides + nSide;
	tFaceProps	props;

#if LIGHTMAPS
#define	LMAP_SIZE	(1.0 / 16.0)

	static tUVL	uvl_lMaps [4] = {
	 {F2X (LMAP_SIZE), F2X (LMAP_SIZE), 0}, 
	 {F2X (1.0 - LMAP_SIZE), F2X (LMAP_SIZE), 0}, 
	 {F2X (1.0 - LMAP_SIZE), F2X (1.0 - LMAP_SIZE), 0}, 
	 {F2X (LMAP_SIZE), F2X (1.0 - LMAP_SIZE), 0}
	};
#endif

props.segNum = segP->Index ();
props.sideNum = nSide;
#if DBG
if ((props.segNum == nDbgSeg) && ((nDbgSide < 0) || (props.sideNum == nDbgSide)))
	segP = segP;
#endif
props.widFlags = segP->IsDoorWay (props.sideNum, NULL);
if (!(gameOpts->render.debug.bWalls || IsMultiGame) && IS_WALL (segP->WallNum (props.sideNum)))
	return;
switch (gameStates.render.nType) {
	case -1:
		if (!(props.widFlags & WID_RENDER_FLAG) && (SEGMENTS [props.segNum].m_nType < SEGMENT_IS_WATER))		//if (WALL_IS_DOORWAY(segP, props.sideNum) == WID_NO_WALL)
			return;
		break;
	case 0:
		if (segP->m_children [props.sideNum] >= 0) //&& IS_WALL (WallNumP (segP, props.sideNum)))
			return;
		break;
	case 1:
		if (!IS_WALL (segP->WallNum (props.sideNum)))
			return;
		break;
	case 2:
		if ((SEGMENTS [props.segNum].m_nType < SEGMENT_IS_WATER) &&
			 (SEGMENTS [props.segNum].m_owner < 1))
			return;
		break;
	case 3:
		if ((IsLight (sideP->m_nBaseTex) || (sideP->m_nOvlTex && IsLight (sideP->m_nOvlTex))))
			RenderCorona (props.segNum, props.sideNum, 1, 20);
		return;
	}
#if LIGHTMAPS
if (gameStates.render.bDoLightmaps) {
		float	Xs = 8;
		float	h = 0.5f / (float) Xs;

	props.uvl_lMaps [0].u =
	props.uvl_lMaps [0].v =
	props.uvl_lMaps [1].v =
	props.uvl_lMaps [3].u = F2X (h);
	props.uvl_lMaps [1].u =
	props.uvl_lMaps [2].u =
	props.uvl_lMaps [2].v =
	props.uvl_lMaps [3].v = F2X (1-h);
	}
#endif
props.nBaseTex = sideP->m_nBaseTex;
props.nOvlTex = sideP->m_nOvlTex;
props.nOvlOrient = sideP->m_nOvlOrient;

	//	========== Mark: Here is the change...beginning here: ==========

#if LIGHTMAPS
	if (gameStates.render.bDoLightmaps) {
		memcpy (props.uvl_lMaps, uvl_lMaps, sizeof (tUVL) * 4);
#if LMAP_LIGHTADJUST
		props.uvls [0].l = props.uvls [1].l = props.uvls [2].l = props.uvls [3].l = I2X (1) / 2;
#	endif
		}
#endif

#if DBG //convenient place for a debug breakpoint
if (props.segNum == nDbgSeg && props.sideNum == nDbgSide)
	props.segNum = props.segNum;
if (props.nBaseTex == nDbgBaseTex)
	props.segNum = props.segNum;
if (props.nOvlTex == nDbgOvlTex)
	props.segNum = props.segNum;
#	if 0
else
	return;
#	endif
#endif

if (!FaceIsVisible (props.segNum, props.sideNum))
	return;
if (sideP->m_nType == SIDE_IS_QUAD) {
	props.vNormal = sideP->m_normals [0];
	props.nVertices = 4;
	memcpy (props.uvls, sideP->m_uvls, sizeof (tUVL) * 4);
	memcpy (props.vp, SEGMENTS [props.segNum].Corners (props.sideNum), 4 * sizeof (ushort));
	RenderFace (&props);
	}
else {
	// new code
	// non-planar faces are still passed as quads to the renderer as it will render triangles (GL_TRIANGLE_FAN) anyway
	// just need to make sure the vertices come in the proper order depending of the the orientation of the two non-planar triangles
	props.vNormal = sideP->m_normals [0] + sideP->m_normals [1];
	props.vNormal *= (I2X (1) / 2);
	props.nVertices = 4;
	if (sideP->m_nType == SIDE_IS_TRI_02) {
		memcpy (props.uvls, sideP->m_uvls, sizeof (tUVL) * 4);
		memcpy (props.vp, SEGMENTS [props.segNum].Corners (props.sideNum), 4 * sizeof (ushort));
		RenderFace (&props);
		}
	else if (sideP->m_nType == SIDE_IS_TRI_13) {	//just rendering the fan with vertex 1 instead of 0
		memcpy (props.uvls + 1, sideP->m_uvls, sizeof (tUVL) * 3);
		props.uvls [0] = sideP->m_uvls [3];
		memcpy (props.vp + 1, SEGMENTS [props.segNum].Corners (props.sideNum), 4 * sizeof (ushort));
		props.vp [0] = props.vp [4];
		RenderFace (&props);
		}
	else {
		Error("Illegal CSide nType in RenderSide, nType = %i, CSegment # = %i, CSide # = %i\n", sideP->m_nType, segP->Index (), props.sideNum);
		return;
		}
	}
}
Пример #5
0
void CQuake3BSP::RenderLevel(const CVector3 &vPos)
{
	// Reset our bitset so all the slots are zero.
	m_FacesDrawn.ClearAll();


/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

	// In this new revision of RenderLevel(), we do things a bit differently.
	// Instead of looping through all the faces, we now want to loop through
	// all of the leafs.  Each leaf stores a list of faces assign to it.
	// We call FindLeaf() to find the current leaf index that our camera is
	// in.  This leaf will then give us the cluster that the camera is in.  The
	// cluster is then used to test visibility between our current cluster
	// and other leaf clusters.  If another leaf's cluster is visible from our 
	// current cluster, the leaf's bounding box is checked against our frustum.  
	// Assuming the bounding box is inside of our frustum, we draw all the faces
	// stored in that leaf.  

	// Grab the leaf index that our camera is in
	int leafIndex = FindLeaf(vPos);

	// Grab the cluster that is assigned to the leaf
	int cluster = m_pLeafs[leafIndex].cluster;

	// Initialize our counter variables (start at the last leaf and work down)
	int i = m_numOfLeafs;
	g_VisibleFaces = 0;

	// Go through all the leafs and check their visibility
	while(i--)
	{
		// Get the current leaf that is to be tested for visibility from our camera's leaf
		tBSPLeaf *pLeaf = &(m_pLeafs[i]);

		// If the current leaf can't be seen from our cluster, go to the next leaf
		if(!IsClusterVisible(cluster, pLeaf->cluster)) 
			continue;

		// If the current leaf is not in the camera's frustum, go to the next leaf
		if(!g_Frustum.BoxInFrustum((float)pLeaf->min.x, (float)pLeaf->min.y, (float)pLeaf->min.z,
		  	 				       (float)pLeaf->max.x, (float)pLeaf->max.y, (float)pLeaf->max.z))
			continue;
		
		// If we get here, the leaf we are testing must be visible in our camera's view.
		// Get the number of faces that this leaf is in charge of.
		int faceCount = pLeaf->numOfLeafFaces;

		// Loop through and render all of the faces in this leaf
		while(faceCount--)
		{
			// Grab the current face index from our leaf faces array
			int faceIndex = m_pLeafFaces[pLeaf->leafface + faceCount];

			// Before drawing this face, make sure it's a normal polygon
			if(m_pFaces[faceIndex].type != FACE_POLYGON) continue;

			// Since many faces are duplicated in other leafs, we need to
			// make sure this face already hasn't been drawn.
			if(!m_FacesDrawn.On(faceIndex)) 
			{
				// Increase the rendered face count to display for fun
				g_VisibleFaces++;

				// Set this face as drawn and render it
				m_FacesDrawn.Set(faceIndex);
				RenderFace(faceIndex);
			}
		}			
	}

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

}