PDA

View Full Version : Shader buggy or graphic card too weak?


Hydrael
08-16-2005, 11:33 PM
Hello everyone,

I've been playing around with shaders for a few weeks now and I'm pretty amazed how powerful they are.
I've implemented a ground type blending shader which I use for rendering terrain.
I pass several textures to the shader as well as vertex alpha values (how much of groundtype n is visible on this vertex). The alpha values I pass via TexCoord unit 7, so that the values will get interpolated over a triangle.
First I tried blending together two groundtypes, which worked perfectly and looked very nice. But only two groundtypes are often just not enough, so I pumped it up to four grounddtypes.
And here lies the problem. As soon as I start my program with the 4 layer blender it almost freezes - I roughly get one frame rendered every 10-15 seconds.
I really can't explain why, because the shader code doesn't really differ from the 2-layer implementation.
I'm using a Radeon Mobility 9700 - this surely isn't a highend card, but I can't imagine that it is not powerful enough to use 4 multitexturing units.
Here is the code:

Vertex Shader:

/*
GroundBlender Shader Program
4 Layer support
---------Vertex Shader---------
*/

varying vec2 texCoords1;
varying vec2 texCoords2;
varying vec2 texCoords3;
varying vec2 texCoords4;
varying vec4 vertexalpha;


void main()
{
* *gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
*
* *texCoords1 * = gl_MultiTexCoord0.xy;
* *texCoords2 * = gl_MultiTexCoord1.xy;
* *texCoords3 * = gl_MultiTexCoord2.xy;
* *texCoords4 * = gl_MultiTexCoord3.xy;
* *vertexalpha *= gl_MultiTexCoord7;

}



Pixel Shader:

/*
GroundBlender Shader Program
4 Layer support
---------Pixel Shader---------
*/

varying vec2 texCoords1;
varying vec2 texCoords2;
varying vec2 texCoords3;
varying vec2 texCoords4;
varying vec4 vertexalpha;

uniform sampler2D GroundTexture1;
uniform sampler2D GroundTexture2;
uniform sampler2D GroundTexture3;
uniform sampler2D GroundTexture4;
*
void main()
{
* * * * * * * *vec4 col=vec4(0,0,0,1.0);
col+=texture2D(GroundTexture1,texCoords1)*vertexal pha.x;
col+=texture2D(GroundTexture2,texCoords2)*vertexal pha.y;
col+=texture2D(GroundTexture3,texCoords3)*vertexal pha.z;
col+=texture2D(GroundTexture4,texCoords4)*vertexal pha.w;
*
* * * gl_FragColor = col;
}



Calling OpenGL function:

void COpenGLWindow::DrawVertexBufferSolid(CFrustum *Frustum)
{
GLuint size=0;
GLuint from=0;

glEnable(GL_TEXTURE_2D);
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_NORMAL_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, VertexBuffer);
glNormalPointer(GL_FLOAT, 0, NormalBuffer);

//Activate Shader
GroundBlender->Activate();

//Layer 1
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glTexCoordPointer(2,GL_FLOAT,0,TexCoordBuffer);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

//Layer 2
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glTexCoordPointer(2,GL_FLOAT,0,TexCoordBuffer);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

//Layer 3
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glTexCoordPointer(2,GL_FLOAT,0,TexCoordBuffer);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

//Layer 4
glClientActiveTextureARB(GL_TEXTURE3_ARB);
glTexCoordPointer(2,GL_FLOAT,0,TexCoordBuffer);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

//Layer 8 -> VertexAlpha
glClientActiveTextureARB(GL_TEXTURE7_ARB);
glTexCoordPointer(4,GL_FLOAT,0,VertexAlpha);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

unsigned int ActTex0=Texture[0].Layer[0];
unsigned int ActTex1=Texture[0].Layer[1];
unsigned int ActTex2=Texture[0].Layer[2];
unsigned int ActTex3=Texture[0].Layer[3];

glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,BasicSpriteFile[ActTex0]->TexID);

glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D,BasicSpriteFile[ActTex1]->TexID);

glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_2D,BasicSpriteFile[ActTex2]->TexID);

glActiveTextureARB(GL_TEXTURE3_ARB);
glBindTexture(GL_TEXTURE_2D,BasicSpriteFile[ActTex3]->TexID);

IncrementSun(0);

//Pass uniform variables to Vertex Shader
glUniform1iARB(glGetUniformLocationARB(GroundBlend er->Program(),"GroundTexture1"),0);
glUniform1iARB(glGetUniformLocationARB(GroundBlend er->Program(),"GroundTexture2"),1);
glUniform1iARB(glGetUniformLocationARB(GroundBlend er->Program(),"GroundTexture3"),2);
glUniform1iARB(glGetUniformLocationARB(GroundBlend er->Program(),"GroundTexture4"),3);

float radius=0;
int count=0;
BOOL change=FALSE;
if(LU)
{
*for(int x=0;x<LUCount*LUCount;x++)
*{
* radius=LURadius+LUDiff[x];
* if(Frustum->SphereInFrustum(LUMid[x].GetX(),LUMid[x].GetY(),LUMid[x].GetZ(),radius))
* {
* *size=LUSpecificSize[x];
* *from=LUArray[x];
* *int Offset=0;
* *count=0;
* *change=FALSE;
* *for(unsigned int i=0;i<size;i+=6)
* *{
* * if(TextureChanges())
* * {
* * *if(i!=0)
* * * glDrawElements(GL_TRIANGLES,count,GL_UNSIGNED_INT, &LUPointer[from+Offset]);
* * *count=6;

* * *ActTex0=Texture[LUPointer[from+i]].Layer[0];
* * *ActTex1=Texture[LUPointer[from+i]].Layer[1];
* * *ActTex2=Texture[LUPointer[from+i]].Layer[2];
* * *ActTex3=Texture[LUPointer[from+i]].Layer[3];

* * *glActiveTextureARB(GL_TEXTURE0_ARB);
* * *glBindTexture(GL_TEXTURE_2D,BasicSpriteFile[ActTex0]->TexID);

* * *glActiveTextureARB(GL_TEXTURE1_ARB);
* * *glBindTexture(GL_TEXTURE_2D,BasicSpriteFile[ActTex1]->TexID);

* * *glActiveTextureARB(GL_TEXTURE2_ARB);
* * *glBindTexture(GL_TEXTURE_2D,BasicSpriteFile[ActTex2]->TexID);

* * *glActiveTextureARB(GL_TEXTURE3_ARB);
* * *glBindTexture(GL_TEXTURE_2D,BasicSpriteFile[ActTex3]->TexID);

* * *glUniform1iARB(glGetUniformLocationARB(GroundBlen der->Program(),"GroundTexture1"),0);
* * *glUniform1iARB(glGetUniformLocationARB(GroundBlen der->Program(),"GroundTexture2"),1);
* * *glUniform1iARB(glGetUniformLocationARB(GroundBlen der->Program(),"GroundTexture3"),2);
* * *glUniform1iARB(glGetUniformLocationARB(GroundBlen der->Program(),"GroundTexture4"),3);

* * *change=TRUE;
* * *Offset=i;
* * }
* * else
* * *count+=6;
* *}
* *if(!change)
* * glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_INT,&LUPointer[from]);
* *else
* * glDrawElements(GL_TRIANGLES,count,GL_UNSIGNED_INT, &LUPointer[from+Offset]);
* *
* }
*}
}

glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_NORMAL_ARRAY );
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);

//Deactivate Shader
GroundBlender->Deactivate();
}




The outer LUCount loop is somewhat simlilar to a quadtree and only used to minimize visibility checks.

Can anyone spot something I did wrong?

Thanks for any help in advance

Chris

Hydrael
08-17-2005, 07:48 AM
Never mind - I solved it.
The problem was those vec2 texcoord values I passed to the shader.
After checking the info log, I've found out, that the fragment shader was running in software mode because it didn't like those values being vec2. After changing them to vec4 it ran perfectly ;)

Reedbeta
08-17-2005, 10:07 PM
Glad you figured it out.

I've found that ATI's support for GLSL is very spotty. There are dozens of weird bugs similiar to this. Just a note in case you plan to keep going with GLSL.