コード例 #1
0
nuiRect nuiPathGenerator::GetRect()
{
  float minx = 0, maxx = 0;
  float miny = 0, maxy = 0;
  bool first = true;

  nuiPath points;
  Tessellate(points, 0.01f);

  for (uint32 i = 0; i < points.GetCount(); i++)
  {
    const nuiPoint& rP = points[i];
    float x = rP.Elt[0];
    float y = rP.Elt[1];
    if (!first)
    {
      minx = MIN(minx,x);
      maxx = MAX(maxx,x);
      miny = MIN(miny,y);
      maxy = MAX(maxy,y);
    }
    else
    {
      minx = maxx = x;
      miny = maxy = y;
      first = false;
    }
  }

  return nuiRect(minx, miny, maxx, maxy, false);
}
コード例 #2
0
ファイル: nuiOutliner.cpp プロジェクト: YetToCome/nui3
bool nuiOutliner::Tessellate(nuiPath& rPoints, float Quality) const
{
  nuiPath Vertices;
  bool res = mpPath->Tessellate(Vertices, Quality);

  rPoints.Clear();

  if (!res)
    return false;

  uint total = Vertices.GetCount();

  uint offset = 0;
  uint count = total;

  //Find sub path:
  for (uint i = offset; i < total; i++)
  {
    uint ii = i+1;
    if (Vertices[i].GetType() == nuiPointTypeStop || ii == total)
    {
      count = ii - offset;
      if (Vertices[i].GetType() == nuiPointTypeStop)
        count--;
      Tessellate(rPoints, Vertices, offset, count, Quality);

      offset = ii;
    }
  }

  return res;
}
コード例 #3
0
//*************************************************************************************************************
void Event_KeyUp(unsigned char keycode)
{
	int numcurves = sizeof(curves) / sizeof(curves[0]);

	for( int i = 0; i < numcurves; ++i )
	{
		if( keycode == 0x31 + i )
		{
			ChangeCurve(i);
			Tessellate();
		}
	}

	switch( keycode )
	{
	case 0x46:
		fullscreen = !fullscreen;
		break;

	case 0x55:
		break;

	case 0x57:
		wireframe = !wireframe;
		break;

	case VK_ADD:
		numsegments = GLMin<GLuint>(numsegments + 10, MAX_NUM_SEGMENTS);
		Tessellate();
		break;

	case VK_SUBTRACT:
		numsegments = GLMax<GLuint>(numsegments - 10, 10);
		Tessellate();
		break;

	default:
		break;
	}
}
コード例 #4
0
//*************************************************************************************************************
void Event_MouseMove(int x, int y, short dx, short dy)
{
	mousex = x;
	mousey = y;

	mousedx += dx;
	mousedy += dy;

	if( mousedown == 1 )
	{
		if( !fullscreen )
		{
			if( UpdateControlPoints((float)mousex, (float)mousey) )
				Tessellate();
		}
	}
	else
		selectedcontrolpoint = -1;
}
コード例 #5
0
bool InitScene()
{
	SurfaceVertex*	svdata = 0;
	float			(*vdata)[4] = 0;
	GLushort*		idata = 0;
	GLuint*			idata32 = 0;

	OpenGLVertexElement decl[] =
	{
		{ 0, 0, GLDECLTYPE_FLOAT4, GLDECLUSAGE_POSITION, 0 },
		{ 0xff, 0, 0, 0, 0 }
	};

	OpenGLVertexElement decl2[] =
	{
		{ 0, 0, GLDECLTYPE_FLOAT4, GLDECLUSAGE_POSITION, 0 },
		{ 0, 16, GLDECLTYPE_FLOAT4, GLDECLUSAGE_NORMAL, 0 },
		{ 0xff, 0, 0, 0, 0 }
	};

	SetWindowText(hwnd, TITLE);
	Quadron::qGLExtensions::QueryFeatures(hdc);

	// calculate viewport sizes
	long maxw = screenwidth - 350; // assume 320x240 first
	long maxh = screenheight - 130 - 10; // text is fix
	
	splinevpsize = GLMin<long>(maxw, maxh);
	splinevpsize -= (splinevpsize % 10);

	surfvpwidth = screenwidth - splinevpsize - 30;
	surfvpheight = (surfvpwidth * 3) / 4;

	if( !Quadron::qGLExtensions::ARB_geometry_shader4 )
		return false;

	hascompute = Quadron::qGLExtensions::ARB_compute_shader;

#ifdef _DEBUG
	if( Quadron::qGLExtensions::ARB_debug_output )
	{
		glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE);
		glDebugMessageCallback(ReportGLError, 0);
	}
#endif

	glClearColor(0.0f, 0.125f, 0.3f, 1.0f);
	glClearDepth(1.0);

	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);

	glDepthFunc(GL_LEQUAL);
	glEnable(GL_DEPTH_TEST);

	// create grid & control poly
	if( !GLCreateMesh(44 + numcontrolvertices, numcontrolindices, GLMESH_DYNAMIC, decl, &supportlines) )
	{
		MYERROR("Could not create mesh");
		return false;
	}

	supportlines->LockVertexBuffer(0, 0, GLLOCK_DISCARD, (void**)&vdata);
	supportlines->LockIndexBuffer(0, 0, GLLOCK_DISCARD, (void**)&idata);

	// grid points
	for( GLuint i = 0; i < 22; i += 2 )
	{
		vdata[i][0] = vdata[i + 1][0] = (float)(i / 2);
		vdata[i][2] = vdata[i + 1][2] = 0;
		vdata[i][3] = vdata[i + 1][3] = 1;

		vdata[i][1] = 0;
		vdata[i + 1][1] = 10;

		vdata[i + 22][1] = vdata[i + 23][1] = (float)(i / 2);
		vdata[i + 22][2] = vdata[i + 23][2] = 0;
		vdata[i + 22][3] = vdata[i + 23][3] = 1;

		vdata[i + 22][0] = 0;
		vdata[i + 23][0] = 10;
	}

	// curve indices
	for( GLuint i = 0; i < numcontrolindices; i += 2 )
	{
		idata[i] = 44 + i / 2;
		idata[i + 1] = 44 + i / 2 + 1;
	}

	supportlines->UnlockIndexBuffer();
	supportlines->UnlockVertexBuffer();

	OpenGLAttributeRange table[] =
	{
		{ GLPT_LINELIST, 0, 0, 0, 0, 44 },
		{ GLPT_LINELIST, 1, 0, numcontrolindices, 44, numcontrolvertices }
	};

	supportlines->SetAttributeTable(table, 2);

	// create spline mesh
	if( !GLCreateMesh(maxsplinevertices, maxsplineindices, GLMESH_32BIT, decl, &curve) )
	{
		MYERROR("Could not create curve");
		return false;
	}

	OpenGLAttributeRange* subset0 = curve->GetAttributeTable();

	subset0->PrimitiveType = GLPT_LINELIST;
	subset0->IndexCount = 0;

	// create surface
	if( !GLCreateMesh(maxsurfacevertices, maxsurfaceindices, GLMESH_32BIT, decl2, &surface) )
	{
		MYERROR("Could not create surface");
		return false;
	}

	// load effects
	if( !GLCreateEffectFromFile("../media/shadersGL/color.vert", "../media/shadersGL/renderpoints.geom", "../media/shadersGL/color.frag", &renderpoints) )
	{
		MYERROR("Could not load point renderer shader");
		return false;
	}

	if( !GLCreateEffectFromFile("../media/shadersGL/color.vert", "../media/shadersGL/renderlines.geom", "../media/shadersGL/color.frag", &renderlines) )
	{
		MYERROR("Could not load line renderer shader");
		return false;
	}

	if( !GLCreateEffectFromFile("../media/shadersGL/rendersurface.vert", 0, "../media/shadersGL/rendersurface.frag", &rendersurface) )
	{
		MYERROR("Could not load surface renderer shader");
		return false;
	}

	if( !GLCreateEffectFromFile("../media/shadersGL/basic2D.vert", 0, "../media/shadersGL/basic2D.frag", &basic2D) )
	{
		MYERROR("Could not load basic 2D shader");
		return false;
	}

	if( hascompute )
	{
		if( !GLCreateComputeProgramFromFile("../media/shadersGL/tessellatecurve.comp", &tessellatecurve) )
		{
			MYERROR("Could not load compute shader");
			return false;
		}

		if( !GLCreateComputeProgramFromFile("../media/shadersGL/tessellatesurface.comp", &tessellatesurface) )
		{
			MYERROR("Could not load compute shader");
			return false;
		}
	}

	screenquad = new OpenGLScreenQuad();

	// tessellate for the first time
	ChangeCurve(0);
	Tessellate();

	// text
	GLCreateTexture(800, 130, 1, GLFMT_A8R8G8B8, &text1);
	UpdateText();

	float angles[2] = { M_PI / 2, 0.5f };
	cameraangle = angles;

	return true;
}
コード例 #6
0
ファイル: RoamMeshDrawer.cpp プロジェクト: Arkazon/spring
/**
 * Retessellates the current terrain
 */
void CRoamMeshDrawer::Update()
{
	//FIXME this retessellates with the current camera frustum, shadow pass and others don't have to see the same patches!

	//const CCamera* cam = (inShadowPass)? camera: cam2;
	CCamera* cam = cam2;

	// Update Patch visibility
	Patch::UpdateVisibility(cam, m_Patches, numPatchesX);

	// Check if a retessellation is needed
#define RETESSELLATE_MODE 1
	bool retessellate = false;
	{ //SCOPED_TIMER("ROAM::ComputeVariance");
		for (int i = 0; i < (numPatchesX * numPatchesY); ++i) {
			Patch& p = m_Patches[i];
		#if (RETESSELLATE_MODE == 2)
			if (p.IsVisible()) {
				if (!visibilitygrid[i]) {
					visibilitygrid[i] = true;
					retessellate = true;
				}
				if (p.IsDirty()) {
					//FIXME don't retessellate on small heightmap changes?
					p.ComputeVariance();
					retessellate = true;
				}
			} else {
				visibilitygrid[i] = false;
			}
		#else
			if (p.IsVisible() != visibilitygrid[i]) {
				visibilitygrid[i] = p.IsVisible();
				retessellate = true;
			}
			if (p.IsVisible() && p.IsDirty()) {
				//FIXME don't retessellate on small heightmap changes?
				p.ComputeVariance();
				retessellate = true;
			}
		#endif
		}
	}

	// Further conditions that can cause a retessellation
#if (RETESSELLATE_MODE == 2)
	static const float maxCamDeltaDistSq = 500.0f * 500.0f;
	retessellate |= ((cam->pos - lastCamPos).SqLength() > maxCamDeltaDistSq);
#endif
	retessellate |= forceRetessellate;
	retessellate |= (lastGroundDetail != smfGroundDrawer->GetGroundDetail());

	// Retessellate
	if (retessellate) {
		{ //SCOPED_TIMER("ROAM::Tessellate");
			//FIXME this tessellates with current camera + viewRadius
			//  so it doesn't retessellate patches that are e.g. only vis. in the shadow frustum
			Reset();
			Tessellate(cam->pos, smfGroundDrawer->GetGroundDetail());
		}

		{ //SCOPED_TIMER("ROAM::GenerateIndexArray");
			#pragma omp parallel for
			for (int i = m_Patches.size() - 1; i >= 0; --i) {
				Patch* it = &m_Patches[i];
				if (it->IsVisible()) {
					it->GenerateIndices();
				}
			}
		}

		{ //SCOPED_TIMER("ROAM::Upload");
			for (std::vector<Patch>::iterator it = m_Patches.begin(); it != m_Patches.end(); ++it) {
				if (it->IsVisible()) {
					it->Upload();
				}
			}
		}

		/*{
			int tricount = 0;
			for (std::vector<Patch>::iterator it = m_Patches.begin(); it != m_Patches.end(); it++) {
				if (it->IsVisible()) {
					tricount += it->GetTriCount();
				}
			}
		
			LOG_L(L_DEBUG, "ROAM dbg: Framechange, fram=%i tris=%i, viewrad=%i, cd=%f, camera=(%5.0f, %5.0f, %5.0f) camera2=  (%5.0f, %5.0f, %5.0f)",
				globalRendering->drawFrame,
				tricount,
				smfGroundDrawer->viewRadius,
				(cam->pos - lastCamPos).SqLength();,
				camera->pos.x,
				camera->pos.y,
				camera->pos.z,
				cam2->pos.x,
				cam2->pos.y,
				cam2->pos.z
				);
		}*/

		lastGroundDetail = smfGroundDrawer->GetGroundDetail();
		lastCamPos = cam->pos;
		forceRetessellate = false;
	}
}