AMD vertex shader tesselation

Started by
2 comments, last by Vilem Otte 15 years ago
Good day, finally AMD has implemented GL_ATI_vertex_shader_tesselator into OpenGL, so on Ati Radeon HD 2 series and up you're now able to use their hardware tesselation unit. All tesselation is done in vertex shader - for more informations: specs: http://www.opengl.org/registry/specs/AMD/vertex_shader_tessellator.txt AMD example (it's weak commented, though with a little thinking about that algo it's understandable): http://developer.amd.com/GPU/WGSDK/Pages/default.aspx I haven't still implemented it yet, but now I'm implementing it into my stuff. So if someone will have some question, I might try to answer it/post my code (after I complete it). Well it looks like AMD has some little advantage over NVidia right now in OpenGL.

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Advertisement
So now I hit dead end (pretty soon eh?),

my current card supports just GL_AMDX_vertex_shader_tessellator (which is present in demo, but it's not present in glext.h)

so I'll try to search if there are any new drivers on it (I hope), or contact AMD and ask, if they have (as they're member of Khronos) some older GLext with GL_AMDX extension).

#EDIT
Khronos (AMD) removed GL_AMDX_vertex_shader_tessellator from GLext, and added GL_AMD_vertex_shader_tessellator. Though on GPUs (all from HD 2 series to HD 4 series) whose have hardware tessellator is supported only AMDX extension (so another dumb-issue from AMD), anyway in their demo they're using fixed address of extension (so maybe that's the solution).

[Edited by - Vilem Otte on April 19, 2009 6:12:16 AM]

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Address? no way.
They are probably tokens.
#define amd_tttt 0xd794
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Ye, now I found it, thanks ...

my implementation now works (and I'm trying to play a little with it - meshsmoothing using bezier curves, displacement mapping, etc.

It's damn fast (comparing to geometry shaders it's much faster - framerate is very good even with tessellating model to several milions of triangles).

EDIT: And another problem is now up I can't solve normals, tangents, bitangents and texcoords for tessellated vertices (the solution described in OpenGL.org registry doesn't work ... woot???) ... e.g. I can tesselate just vertices.
I even have strange numbers for width and height for vertex texture fetches (my vertex field has 9 x 984, my texcoord field has 6 x 821 and they both should be same! ... this is absolutely illogical - this is though not issue of vertex shaders, but of vertex arrays - i still haven't found solution onto this). So I will keep trying to solve whole mystery around this extension (like if it has some kind of magic aura around it, which doesn't allow anyone to use it correctly :D).

here is my vertex shader code:
#extension GL_AMDX_vertex_shader_tessellator : require__samplerVertexAMDX vertexTex;__samplerVertexAMDX texcoordTex;varying vec4 texCoord;void main(){	gl_Vertex = vec4(0.0);	gl_MultiTexCoord1 = vec4(0.0);	for(int i = 0; i < 3; i++)	{		float weight = gl_BarycentricCoord;		gl_Vertex += weight * vertexFetchAMDX(vertexTex, gl_VertexTriangleIndex);		gl_MultiTexCoord1 += weight * vertexFetchAMDX(texcoordTex, gl_VertexTriangleIndex);	}	texCoord = gl_MultiTexCoord1;	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;}


this is how I setup tesselation (with two textures - for vertices and for texcoords)
	glActiveTexture(GL_TEXTURE0);	glBindTexture(GL_TEXTURE_2D, mdl_cliff.vertexTexture);	glActiveTexture(GL_TEXTURE1);	glBindTexture(GL_TEXTURE_2D, mdl_cliff.texCoordTexture);	glTessellationFactorAMDX(8.0f);	glTessellationModeAMDX(GL_CONTINUOUS_AMDX);


and this is how I compute my vertex arrays (don't look at me like that I know that they should be indexed, but my texcoord vertices differs from my vertices, damn)
	int numTris = 0;	int numberVert = 0;	int numberTexVert = 0;	for(int i = 0; i < this->objectnum; i++)	{		for(int j = 0; j < this->o.facenum; j++)		{			numberVert += 9;			numberTexVert += 12;			numTris++;		}	}	this->vertexArray = new float[numberVert];	this->texCoordArray = new float[numberTexVert];	int numeratorVert = 0;	int numeratorTex = 0;	for(i = 0; i < this->objectnum; i++)	{		for(int j = 0; j < this->o.facenum; j++)		{			this->vertexArray[numeratorVert + 0] = this->o.v[this->o.f[j].A].vertex.x;			this->vertexArray[numeratorVert + 1] = this->o.v[this->o.f[j].A].vertex.z;			this->vertexArray[numeratorVert + 2] = -this->o.v[this->o.f[j].A].vertex.y;			this->vertexArray[numeratorVert + 3] = this->o.v[this->o.f[j].B].vertex.x;			this->vertexArray[numeratorVert + 4] = this->o.v[this->o.f[j].B].vertex.z;			this->vertexArray[numeratorVert + 5] = -this->o.v[this->o.f[j].B].vertex.y;			this->vertexArray[numeratorVert + 6] = this->o.v[this->o.f[j].C].vertex.x;			this->vertexArray[numeratorVert + 7] = this->o.v[this->o.f[j].C].vertex.z;			this->vertexArray[numeratorVert + 8] = -this->o.v[this->o.f[j].C].vertex.y;			this->texCoordArray[numeratorTex + 0] = this->o.t[this->o.f[j].tA].coord.x;			this->texCoordArray[numeratorTex + 1] = -this->o.t[this->o.f[j].tA].coord.y;			this->texCoordArray[numeratorTex + 2] = 0.0f;			this->texCoordArray[numeratorTex + 3] = 0.0f;			this->texCoordArray[numeratorTex + 4] = this->o.t[this->o.f[j].tB].coord.x;			this->texCoordArray[numeratorTex + 5] = -this->o.t[this->o.f[j].tB].coord.y;			this->texCoordArray[numeratorTex + 6] = 0.0f;			this->texCoordArray[numeratorTex + 7] = 0.0f;			this->texCoordArray[numeratorTex + 8] = this->o.t[this->o.f[j].tC].coord.x;			this->texCoordArray[numeratorTex + 9] = -this->o.t[this->o.f[j].tC].coord.y;			this->texCoordArray[numeratorTex + 10] = 0.0f;			this->texCoordArray[numeratorTex + 11] = 0.0f;			numeratorVert += 9;			numeratorTex += 12;		}	}	int width;	glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGB32F_ARB, 3, numTris, 0, GL_RGB, GL_FLOAT, NULL);	glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); 	if(!width) 		MessageBox(hWnd, "Too large model for tesselation", "Error", MB_OK);	int MaxVertexTextureImageUnits;	glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &MaxVertexTextureImageUnits);	int MaxCombinedTextureImageUnits;	glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &MaxCombinedTextureImageUnits);	glActiveTexture(GL_TEXTURE0);	glGenTextures(1, &this->vertexTexture);	glBindTexture(GL_TEXTURE_2D, this->vertexTexture);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F_ARB, 3, numTris, 0, GL_RGB, GL_FLOAT, this->vertexArray);	glActiveTexture(GL_TEXTURE0);	glGenTextures(1, &this->texCoordTexture);	glBindTexture(GL_TEXTURE_2D, this->texCoordTexture);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F_ARB, 4, numTris, 0, GL_RGB, GL_FLOAT, this->texCoordArray);


Whoops it hidden the pluses (i hope you can see where they were :D)

[Edited by - Vilem Otte on April 19, 2009 9:51:00 AM]

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

This topic is closed to new replies.

Advertisement