Example #1
0
void OcclusionBuffer::DrawTriangle(Vector4* vertices)
{
    unsigned clipMask = 0;
    unsigned andClipMask = 0;
    bool drawOk = false;
    Vector3 projected[3];
    
    // Build the clip plane mask for the triangle
    for (unsigned i = 0; i < 3; ++i)
    {
        unsigned vertexClipMask = 0;
        
        if (vertices[i].x_ > vertices[i].w_)
            vertexClipMask |= CLIPMASK_X_POS;
        if (vertices[i].x_ < -vertices[i].w_)
            vertexClipMask |= CLIPMASK_X_NEG;
        if (vertices[i].y_ > vertices[i].w_)
            vertexClipMask |= CLIPMASK_Y_POS;
        if (vertices[i].y_ < -vertices[i].w_)
            vertexClipMask |= CLIPMASK_Y_NEG;
        if (vertices[i].z_ > vertices[i].w_)
            vertexClipMask |= CLIPMASK_Z_POS;
        if (vertices[i].z_ < 0.0f)
            vertexClipMask |= CLIPMASK_Z_NEG;
        
        clipMask |= vertexClipMask;
        
        if (!i)
            andClipMask = vertexClipMask;
        else
            andClipMask &= vertexClipMask;
    }
    
    // If triangle is fully behind any clip plane, can reject quickly
    if (andClipMask)
        return;
    
    // Check if triangle is fully inside
    if (!clipMask)
    {
        projected[0] = ViewportTransform(vertices[0]);
        projected[1] = ViewportTransform(vertices[1]);
        projected[2] = ViewportTransform(vertices[2]);
        
        if (CheckFacing(projected[0], projected[1], projected[2]))
        {
            DrawTriangle2D(projected);
            drawOk = true;
        }
    }
    else
    {
        bool triangles[64];
        
        // Initial triangle
        triangles[0] = true;
        unsigned numTriangles = 1;
        
        if (clipMask & CLIPMASK_X_POS)
            ClipVertices(Vector4(-1.0f, 0.0f, 0.0f, 1.0f), vertices, triangles, numTriangles);
        if (clipMask & CLIPMASK_X_NEG)
            ClipVertices(Vector4(1.0f, 0.0f, 0.0f, 1.0f), vertices, triangles, numTriangles);
        if (clipMask & CLIPMASK_Y_POS)
            ClipVertices(Vector4(0.0f, -1.0f, 0.0f, 1.0f), vertices, triangles, numTriangles);
        if (clipMask & CLIPMASK_Y_NEG)
            ClipVertices(Vector4(0.0f, 1.0f, 0.0f, 1.0f), vertices, triangles, numTriangles);
        if (clipMask & CLIPMASK_Z_POS)
            ClipVertices(Vector4(0.0f, 0.0f, -1.0f, 1.0f), vertices, triangles, numTriangles);
        if (clipMask & CLIPMASK_Z_NEG)
            ClipVertices(Vector4(0.0f, 0.0f, 1.0f, 0.0f), vertices, triangles, numTriangles);
        
        // Draw each accepted triangle
        for (unsigned i = 0; i < numTriangles; ++i)
        {
            if (triangles[i])
            {
                unsigned index = i * 3;
                projected[0] = ViewportTransform(vertices[index]);
                projected[1] = ViewportTransform(vertices[index + 1]);
                projected[2] = ViewportTransform(vertices[index + 2]);
                
                if (CheckFacing(projected[0], projected[1], projected[2]))
                {
                    DrawTriangle2D(projected);
                    drawOk = true;
                }
            }
        }
    }
    
    if (drawOk)
        ++numTriangles_;
}
Example #2
0
void BattleGesture::RenderHints()
{
	glm::mat4 transform = ViewportTransform(_battleView->GetFrame());

	vertexbuffer<plain_vertex> shape;
	shape._mode = GL_LINES;

	for (UnitCounter* unitMarker : _battleView->GetUnitCounters())
	{
		bounds2f bounds = GetUnitCurrentBounds(unitMarker->_unit);

		shape._vertices.push_back(plain_vertex(bounds.p11()));
		shape._vertices.push_back(plain_vertex(bounds.p12()));
		shape._vertices.push_back(plain_vertex(bounds.p12()));
		shape._vertices.push_back(plain_vertex(bounds.p22()));
		shape._vertices.push_back(plain_vertex(bounds.p22()));
		shape._vertices.push_back(plain_vertex(bounds.p21()));
		shape._vertices.push_back(plain_vertex(bounds.p21()));
		shape._vertices.push_back(plain_vertex(bounds.p11()));

		bounds = GetUnitFutureBounds(unitMarker->_unit);
		if (!bounds.is_empty())
		{
			shape._vertices.push_back(plain_vertex(bounds.p11()));
			shape._vertices.push_back(plain_vertex(bounds.p12()));
			shape._vertices.push_back(plain_vertex(bounds.p12()));
			shape._vertices.push_back(plain_vertex(bounds.p22()));
			shape._vertices.push_back(plain_vertex(bounds.p22()));
			shape._vertices.push_back(plain_vertex(bounds.p21()));
			shape._vertices.push_back(plain_vertex(bounds.p21()));
			shape._vertices.push_back(plain_vertex(bounds.p11()));
		}

		bounds = GetUnitModifierBounds(unitMarker->_unit);
		if (!bounds.is_empty())
		{
			shape._vertices.push_back(plain_vertex(bounds.p11()));
			shape._vertices.push_back(plain_vertex(bounds.p12()));
			shape._vertices.push_back(plain_vertex(bounds.p12()));
			shape._vertices.push_back(plain_vertex(bounds.p22()));
			shape._vertices.push_back(plain_vertex(bounds.p22()));
			shape._vertices.push_back(plain_vertex(bounds.p21()));
			shape._vertices.push_back(plain_vertex(bounds.p21()));
			shape._vertices.push_back(plain_vertex(bounds.p11()));
		}
	}

	renderers::singleton->_plain_renderer->get_uniform<glm::mat4>("transform").set_value(transform);
	renderers::singleton->_plain_renderer->get_uniform<float>("point_size").set_value(1);
	renderers::singleton->_plain_renderer->get_uniform<glm::vec4>("color").set_value(glm::vec4(0, 0, 0, 0.2f));
	renderers::singleton->_plain_renderer->render(shape);


	/*PlainLineRenderer renderer;
	renderer.Reset();
	for (UnitCounter* unitMarker : _battleView->GetBattleSimulator()->_unitMarkers)
	{
		glm::vec2 center = !unitMarker->_unit->command.path.empty() ? unitMarker->_unit->command.path.back() : unitMarker->_unit->state.center;
		float facing = unitMarker->_unit->command.facing;

		glm::vec2 p1 = center + MODIFIER_AREA_RADIUS_MAX * vector2_from_angle(facing - 0.5f * glm::half_pi<float>());
		glm::vec2 p2 = center + MODIFIER_AREA_RADIUS_MAX * vector2_from_angle(facing + 0.5f * glm::half_pi<float>());

		renderer.AddLine(_battleView->GetPosition(center), _battleView->GetPosition(p1));
		renderer.AddLine(_battleView->GetPosition(center), _battleView->GetPosition(p2));

		for (int i = 1; i <= 10; ++i)
		{
			float a1 = facing + ((i - 1) / 10.0f - 0.5f) * glm::half_pi<float>();
			float a2 = facing + (i / 10.0f - 0.5f) * glm::half_pi<float>();

			p1 = center + MODIFIER_AREA_RADIUS_MIN * vector2_from_angle(a1);
			p2 = center + MODIFIER_AREA_RADIUS_MIN * vector2_from_angle(a2);
			renderer.AddLine(_battleView->GetPosition(p1), _battleView->GetPosition(p2));

			p1 = center + MODIFIER_AREA_RADIUS_MAX * vector2_from_angle(a1);
			p2 = center + MODIFIER_AREA_RADIUS_MAX * vector2_from_angle(a2);
			renderer.AddLine(_battleView->GetPosition(p1), _battleView->GetPosition(p2));
		}
	}
	renderer.Draw(_battleView->GetTransform(), glm::vec4(0, 0, 0, 0.2f));*/
}
Example #3
0
void GenerateSnapshot (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	ALERROR error;
	int i;

	//	Get some parameters

	int iInitialUpdateTime = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("initialUpdate"), 0, -1, 10);
	int iUpdateTime = pCmdLine->GetAttributeInteger(CONSTLIT("wait"));
	bool bObjOnly = pCmdLine->GetAttributeBool(CONSTLIT("objOnly"));

	//	Criteria

	CString sNode = pCmdLine->GetAttribute(CONSTLIT("node"));
	CString sCriteria = pCmdLine->GetAttribute(CONSTLIT("criteria"));

	//	Number of snapshots

	int iTotalCount = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1);

	//	Output

	int cxWidth;
	int cyHeight;
	if (pCmdLine->FindAttributeInteger(CONSTLIT("size"), &cxWidth))
		{
		cyHeight = cxWidth;
		}
	else
		{
		cxWidth = 1024;
		cyHeight = 1024;
		}

	//	Paint flags

	DWORD dwPaintFlags = 0;
	if (pCmdLine->GetAttributeBool(CONSTLIT("noStars")))
		dwPaintFlags |= CSystem::VWP_NO_STAR_FIELD;

	//	Output file

	CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output"));
	if (!sFilespec.IsBlank())
		sFilespec = pathStripExtension(sFilespec);

	//	Output image

	CG32bitImage Output;
	Output.Create(cxWidth, cyHeight);

	//	Update context

	SSystemUpdateCtx Ctx;
	Ctx.bForceEventFiring = true;
	Ctx.bForcePainted = true;

	RECT rcViewport;
	rcViewport.left = 0;
	rcViewport.top = 0;
	rcViewport.right = cxWidth;
	rcViewport.bottom = cyHeight;

	//	Loop over all systems until we find what we're looking for

	int iLoops = 20;
	int iNodeIndex = 0;
	int iSnapshotIndex = 0;
	CTopologyNode *pNode = Universe.GetTopologyNode(iNodeIndex);
	while (true)
		{
		//	Create the system

		CSystem *pSystem;
		if (error = Universe.CreateStarSystem(pNode, &pSystem))
			{
			printf("ERROR: Unable to create star system.\n");
			return;
			}

		//	If this is the node we want, then search

		CSpaceObject *pTarget;
		if (sNode.IsBlank() || strEquals(sNode, pNode->GetID()))
			{
			printf("Searching %s...\n", pNode->GetSystemName().GetASCIIZPointer());

			//	Set the POV

			CSpaceObject *pPOV = pSystem->GetObject(0);
			Universe.SetPOV(pPOV);
			pSystem->SetPOVLRS(pPOV);

			//	Prepare system

			Universe.UpdateExtended();
			Universe.GarbageCollectLibraryBitmaps();

			//	Update for a while

			for (i = 0; i < iInitialUpdateTime; i++)
				{
				Universe.Update(Ctx);
				Universe.PaintPOV(Output, rcViewport, 0);
				}

			//	Compose the criteria

			CSpaceObject::Criteria Criteria;
			CSpaceObject::ParseCriteria(pPOV, sCriteria, &Criteria);

			//	Get the list of all objects in the system that match the criteria

			CSpaceObject::SCriteriaMatchCtx Ctx(Criteria);
			TArray<CSpaceObject *> Results;
			for (i = 0; i < pSystem->GetObjectCount(); i++)
				{
				CSpaceObject *pObj = pSystem->GetObject(i);
				if (pObj && pObj->MatchesCriteria(Ctx, Criteria))
					Results.Insert(pObj);
				}

			//	Pick the appropriate object from the list

			if (Results.GetCount() == 0)
				pTarget = NULL;
			else if (Criteria.bNearestOnly || Criteria.bFarthestOnly)
				pTarget = Ctx.pBestObj;
			else
				pTarget = Results[mathRandom(0, Results.GetCount() - 1)];
			}
		else
			pTarget = NULL;

		//	If we found the target, then output

		if (pTarget)
			{
			Universe.SetPOV(pTarget);

			//	Wait a bit
			//
			//	NOTE: After we update, pTarget could be invalid (i.e., destroyed)
			//	so we can't use it again.

			CString sTargetName = pTarget->GetNounPhrase(0);

			for (i = 0; i < iUpdateTime; i++)
				{
				if ((i % 100) == 99)
					printf(".");

				Universe.Update(Ctx);
				Universe.PaintPOV(Output, rcViewport, 0);
				}

			if (iUpdateTime >= 99)
				printf("\n");

			//	Paint

			if (bObjOnly)
				{
				SViewportPaintCtx Ctx;
				Ctx.pObj = Universe.GetPOV();
				Ctx.XForm = ViewportTransform(Universe.GetPOV()->GetPos(), 
						g_KlicksPerPixel, 
						cxWidth / 2, 
						cyHeight / 2);
				Ctx.XFormRel = Ctx.XForm;
				Ctx.fNoRecon = true;
				Ctx.fNoDockedShips = true;
				Ctx.fNoSelection = true;
				Ctx.fNoStarfield = true;

				CSpaceObject *pPOV = pSystem->GetObject(0);
				CSpaceObject::Criteria Criteria;
				CSpaceObject::ParseCriteria(pPOV, sCriteria, &Criteria);

				//	Paint all objects that match the criteria

				CSpaceObject::SCriteriaMatchCtx CriteriaCtx(Criteria);
				for (i = 0; i < pSystem->GetObjectCount(); i++)
					{
					CSpaceObject *pObj = pSystem->GetObject(i);
					if (pObj && pObj->MatchesCriteria(CriteriaCtx, Criteria))
						{
						Ctx.pObj = pObj;
						int xObj;
						int yObj;
						Ctx.XForm.Transform(pObj->GetPos(), &xObj, &yObj);

						pObj->Paint(Output, xObj, yObj, Ctx);
						}
					}
				}
			else
				{
			
				Universe.PaintPOV(Output, rcViewport, 0);
				}

			//	Write to file

			if (!sFilespec.IsBlank())
				{
				CString sBmpFilespec;
				if (iTotalCount > 100)
					sBmpFilespec = pathAddExtensionIfNecessary(strPatternSubst(CONSTLIT("%s%03d"), sFilespec, iSnapshotIndex + 1), CONSTLIT(".bmp"));
				else if (iTotalCount > 1)
					sBmpFilespec = pathAddExtensionIfNecessary(strPatternSubst(CONSTLIT("%s%02d"), sFilespec, iSnapshotIndex + 1), CONSTLIT(".bmp"));
				else
					sBmpFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp"));

				CFileWriteStream OutputFile(sBmpFilespec);
				if (OutputFile.Create() != NOERROR)
					{
					printf("ERROR: Unable to create '%s'\n", sBmpFilespec.GetASCIIZPointer());
					return;
					}

				Output.WriteToWindowsBMP(&OutputFile);
				OutputFile.Close();
				printf("Found %s: Saved to %s\n", sTargetName.GetASCIIZPointer(), sBmpFilespec.GetASCIIZPointer());
				}

			//	Otherwise, clipboard

			else
				{
				if (error = Output.CopyToClipboard())
					{
					printf("ERROR: Unable to copy image to clipboard.\n");
					return;
					}

				printf("Found %s: Copied to clipboard.\n", sTargetName.GetASCIIZPointer());
				}

			//	Reset maximum loops

			iLoops = 20;

			//	Done

			iSnapshotIndex++;
			if (iSnapshotIndex >= iTotalCount)
				break;
			}

		//	Done with old system

		Universe.DestroySystem(pSystem);

		//	Loop to the next node

		do
			{
			iNodeIndex = ((iNodeIndex + 1) % Universe.GetTopologyNodeCount());
			pNode = Universe.GetTopologyNode(iNodeIndex);
			}
		while (pNode == NULL || pNode->IsEndGame());

		//	If we're back to the first node again, restart

		if (iNodeIndex == 0)
			{
			if (--iLoops > 0)
				{
				//	Reinitialize

				Universe.Reinit();
				CString sError;
				if (Universe.InitGame(0, &sError) != NOERROR)
					{
					printf("ERROR: %s\n", sError.GetASCIIZPointer());
					return;
					}

				iNodeIndex = 0;
				pNode = Universe.GetTopologyNode(iNodeIndex);
				}
			else
				{
				printf("ERROR: Specified target could not be found.\n");
				return;
				}
			}
		}
	}