[2011][waterdrop]triangle strip

triangle strip好于triangle list:

  • 省index buffer
  • triangle setup速度更快

所以通常意义上,能用strip就strip吧。

 

尤其是在程序生成的地方应该使用triangle strip的。

 

限制就是直接使用是需要带状的,任意形状需要用degenerate triangle来做,也就是使用有重复点的triangle。

(ABCDDFFEDC, which would be interpreted as triangles ABC CBD CDD DDF DFF FFE FED DEC)

 

需要注意的就是vertex shader里对于有同样点的triangle仍旧会做计算,当然如果cache hit就直接过,在rasterization阶段会对无面积的triangle干掉。

 

cache 命中的地方,大家都熟悉了,使用id3dxmesh::optimize会有不错的cache效率提升。

 

 

 

google的时候看见一个用triangle strip以螺旋的方式来做sphere construction的,挺有意思,贴它的代码吧:

#include <cmath>
#include <vector>
#include <gl/glut.h>
const float PI = 3.14159265358979323846f;
#pragma pack(1)
template <typename TYPE>
class GeometryVector
{	
public:		
	GeometryVector(const TYPE x_ = TYPE(), const TYPE y_ = TYPE(), const TYPE z_ = TYPE());		
	const TYPE x;		
	const TYPE y;		
	const TYPE z;
};
#pragma pack()
template <typename TYPE>GeometryVector<TYPE>::GeometryVector(const TYPE x_, const TYPE y_, const TYPE z_)	
:	x(x_),	y(y_),	z(z_)
{}
class StackedSphere
{	
public:		
	StackedSphere(const float radius = 1.0f, const unsigned int stacks = 8, const unsigned int slices = 16);		
	void render() const;	
private:		
	std::vector<GeometryVector<float> > geometryData_;		
	std::vector<unsigned short> indexData_;
};
StackedSphere::StackedSphere(const float radius, const unsigned int stacks, const unsigned int slices)
{	
	for (unsigned int stackNumber = 0; stackNumber <= stacks; ++stackNumber)	
	{		
		for (unsigned int sliceNumber = 0; sliceNumber < slices; ++sliceNumber)		
		{			
			float theta = stackNumber * PI / stacks;			
			float phi = sliceNumber * 2 * PI / slices;			
			float sinTheta = std::sin(theta);			
			float sinPhi = std::sin(phi);			
			float cosTheta = std::cos(theta);			
			float cosPhi = std::cos(phi);			
			geometryData_.push_back(GeometryVector<float>(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta));		
		}	
	}	
	
	for (unsigned int stackNumber = 0; stackNumber < stacks; ++stackNumber)	
	{		
		for (unsigned int sliceNumber = 0; sliceNumber <= slices; ++sliceNumber)		
		{			
			indexData_.push_back((stackNumber * slices) + (sliceNumber % slices));			
			indexData_.push_back(((stackNumber + 1) * slices) + (sliceNumber % slices));		
		}	
	}
}
void StackedSphere::render() const
{	
	glVertexPointer(3, GL_FLOAT, 0, &geometryData_[0]);	glEnableClientState(GL_VERTEX_ARRAY);	
	glDrawElements(GL_TRIANGLE_STRIP, indexData_.size(), GL_UNSIGNED_SHORT, &indexData_[0]);
}
class SpiralSphere
{	
public:		
	SpiralSphere(const float radius = 1.0f, const unsigned int loops = 8, const unsigned int segmentsPerLoop = 16);		
	void render() const;	
private:		
	std::vector<GeometryVector<float> > geometryData_;		
	std::vector<unsigned short> indexData_;
};
SpiralSphere::SpiralSphere(const float radius, const unsigned int loops, const unsigned int segmentsPerLoop)
{	
	for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)	
	{		
		float theta = 0;		
		float phi = loopSegmentNumber * 2 * PI / segmentsPerLoop;		
		float sinTheta = std::sin(theta);		
		float sinPhi = std::sin(phi);		
		float cosTheta = std::cos(theta);		
		float cosPhi = std::cos(phi);		
		geometryData_.push_back(GeometryVector<float>(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta));			
	}	
	
	for (unsigned int loopNumber = 0; loopNumber <= loops; ++loopNumber)	
	{		
		for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)		
		{			
			float theta = (loopNumber * PI / loops) + ((PI * loopSegmentNumber) / (segmentsPerLoop * loops));			
			if (loopNumber == loops)			
			{				
				theta = PI;			
			}			
			float phi = loopSegmentNumber * 2 * PI / segmentsPerLoop;			
			float sinTheta = std::sin(theta);			
			float sinPhi = std::sin(phi);			
			float cosTheta = std::cos(theta);			
			float cosPhi = std::cos(phi);			
			geometryData_.push_back(GeometryVector<float>(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta));					
		}	
	}	
	
	for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)	
	{		
		indexData_.push_back(loopSegmentNumber);		
		indexData_.push_back(segmentsPerLoop + loopSegmentNumber);	
	}	
	
	for (unsigned int loopNumber = 0; loopNumber < loops; ++loopNumber)	
	{		
		for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)		
		{			
			indexData_.push_back(((loopNumber + 1) * segmentsPerLoop) + loopSegmentNumber);			
			indexData_.push_back(((loopNumber + 2) * segmentsPerLoop) + loopSegmentNumber);		
		}	
	}
}
void SpiralSphere::render() const
{	
	glVertexPointer(3, GL_FLOAT, 0, &geometryData_[0]);	
	glEnableClientState(GL_VERTEX_ARRAY);	
	glDrawElements(GL_TRIANGLE_STRIP, indexData_.size(), GL_UNSIGNED_SHORT, &indexData_[0]);
}
StackedSphere sphere1(4, 8, 16);SpiralSphere sphere2(4, 8, 16);
int r = 0;
void reshape(int width, int height)
{	
	if (height == 0)	
	{		
		height = 1;	
	}	
	glMatrixMode(GL_PROJECTION);	
	glLoadIdentity();	
	glViewport(0, 0, width, height);	
	gluPerspective(45.0f, GLfloat(width) / GLfloat(height), 0.1f, 50.0f);	
	glMatrixMode(GL_MODELVIEW);	
	glLoadIdentity();
}
void display()
{	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
	glLoadIdentity();	
	glTranslatef(0, 0, -25);	
	glPushMatrix();		
	glTranslatef(-5, 0, 0);		
	glRotatef(r, 0, 1, 0);		
	sphere1.render();	
	glPopMatrix();	
	glPushMatrix();		
	glTranslatef(5, 0, 0);		
	glRotatef(r, 0, 1, 0);		
	sphere2.render();	
	glPopMatrix();	
	glutSwapBuffers();	
	r++;
}
int main(int argc, char** argv)
{	
	glutInit(&argc, argv);	
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);	
	glutInitWindowPosition(0, 0);	
	glutInitWindowSize(512,512);	
	glutCreateWindow("Sphere Test");	
	glutReshapeFunc(reshape);	
	glutDisplayFunc(display);	
	glutIdleFunc(display);	
	glPolygonMode(GL_FRONT, GL_LINE);	
	glPolygonMode(GL_BACK, GL_LINE);	
	glutMainLoop();
	return 0;
}
 

 

 

 

 


原文链接: http://blog.csdn.net/ccanan/article/details/6561549

你可能感兴趣的:([2011][waterdrop]triangle strip)