PDA

View Full Version : Point Sprites and texture manipulation..



scratt
08-15-2008, 03:55 AM
I had a theory that by playing with the TEXTURE_MATRIX and then carrying those values through to the fragment shader from the vertex shader thus:

gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;

I would be able to rotate, stretch the texture etc.
I have been able to select sections of a texture pack this way before in RECTangular textures in shaders.

But it doesn't seem to work.
I get some flickering, but basically the texture stays planted on the sprite pretty much in it's default position.

I also tried blending using the mix command and that will hang the GPU completely.

Anyone else had any success with this?

Xmas
08-15-2008, 05:33 AM
If you want to rotate the texture on a point sprite you have to do it in the fragment shader.

arekkusu
08-15-2008, 02:51 PM
If you have a reproducible case that hangs the GPU completely, file a bug. (http://bugreporter.apple.com). Or at least post the code somewhere.

scratt
08-17-2008, 09:06 PM
'tis done..

6152163

scratt
08-19-2008, 04:09 AM
This is an email I have sent to the Apple OpenGL mailing list..
I thought I'd duplicate it here in case anyone can show me what I am doing wrong..

I've been again thrashing around with rotating Point Sprites for the last day or so on an x1600.
I can confirm this is not a problem on non-ATI hardware I have.
I have also filed a Bug Report.

Basically I am using a slightly modified version of the Philip Rideout's GLSLShowpiece Fragment Shader for the particle fountain.
I use interleaved arrays (GL_C3F_V3F) to draw anywhere from 100 to 1000 point sprites in multiple instances.

glInterleavedArrays(GL_C3F_V3F, 0, particles);
glDrawArrays(GL_POINTS, 0, m_nParticleCount);

The modification to the shader is simply to pass an angle uniform float into the vertex shader which creates a varying mat2 to rotate the texture coordinates. In the fragment shader I take the mat2 and multiply it by gl_TexCoord[0].st and store it in a vec2.

Thus..
vec2 rot = mat * gl_TexCoord[0].st
I then apply some scaling to the resultant vec2 with some simple division and addition.

I also use mix to combine a calculated colour from the vertex shader with the texture colour obtained.
Thus..

vec4 col = texture2D(tex,rot.st);
vec4 col2 = mix(col, Color, 0.5);

With either the mix command in the shader, or the vec2 rot = mat * gl_TexCoord[0].st line the shader will cause my 17" MBP to lock up after a random time period of the particle system being on screen.
Basically a very hard and fast GPU crash.

Other than that it does what I expect.. Lots of independently rotating point sprites. Looks yummy!

I have tested the shader in the OpenGL Shader Builder, and also parsed it in my program and dumped the results.
In both cases it's a valid hardware accelerated shader.

I have tried disabling the shader completely and everything is fine.
I get a block of point sprites at each location I request, without animation etc.
Thus I feel I have confirmed there are no errant bound buffers, or client states left hanging causing access violations etc.

I have gone one step further and taken the glDrawArrays and broken it down into a glBegin(GL_POINTS) for .. next loop.
I have tried this with the shader enabled and without.
The shader still causes a hard lockup when enabled.

Strangely if I approach the particle fountain at different viewing angles I get different results in how long it takes to hang the machine.
This could be nothing but I felt is was worth mentioning.

Debugging any further is almost impossible as anything apart from removing those two lines will cause a lockup in all cases.
XCode, the OpenGL profiler etc. etc. are unable to run this in debug mode, or to profile it in any way without the entire machine locking up.

Without the shader enabled they both flag no errors at all with the code.
No software fallback, no OpenGL errors and so on...
Even with the shader enabled there is never any error flagged prior to the machine locking up.

This is most certainly a serious OpenGL driver bug, and it has stopped me in my tracks as I need to get this to work.

Can anyone give me some feedback on this...

Any suggestions as to how I might work around it, research it further?

Or would anyone be willing to test it on their machines to confirm the problem?

Thanks.
Stephen.

I have stuck the shader code below if anyone has the time to look it over for anything dumb I am doing.


Vertex Shader

uniform float time;
uniform float angle; // TODO : Perhaps pass in sin and cos of angle
varying vec4 Color;
varying mat2 mat;

const float maxy = 1.85;
const float rad = 1.75;
const float radius = 2.2;

void main(void)
{
// gl_PointSize = time / 2.0;

float t = time / 10.0;
t = clamp(t - gl_Vertex.x, 0.0, 10000.0);
t = mod(t, 1.0);
vec4 vertex = gl_Vertex;
vertex.x = rad * gl_Color.y * t * sin(gl_Color.x * 6.28);
vertex.z = rad * gl_Color.y * t * cos(gl_Color.x * 6.28);
float miny = ((gl_Color.y * t) > 1.0) ? -5000.0 : -1.0;
float h = gl_Color.z * maxy;
vertex.y = - (t - h) * (t - h) + h * h - 1.0;
vertex.y = clamp(vertex.y, miny, 100.0);
gl_Position = gl_ModelViewProjectionMatrix * vertex;

// Point Size
vec4 camera_pos = gl_ModelViewMatrixInverse[3];
float dist = distance(gl_Position.xyz, camera_pos.xyz);
float psize = (radius * 10.0) / dist;
gl_PointSize = psize;

// Colour settings
Color.r = 0.5 + (h / maxy / 2.0);
Color.g = h / maxy;
Color.b = 0.0;
Color.a = 1.0 - t / 1.75;

// Texture rotations
gl_TexCoord[0] = gl_MultiTexCoord0;
float aa = angle * (gl_Color.y - 0.5); // Bidirectional spin.
float cc = cos(aa);
float ss = sin(aa);
mat = mat2(cc, -ss, ss, cc);
}

Fragment Shader

varying vec4 Color;
varying mat2 mat;
uniform sampler2D tex;

void main (void)
{
vec2 rot = mat * gl_TexCoord[0].st; // This causes a hard lockup.
// vec2 rot = gl_TexCoord[0].st; // This works. No rotation though.

rot.s = ((rot.s + 1.0) / 2.0);
rot.t = ((rot.t + 1.0) / 2.0);

vec4 col = texture2D(tex, rot.st);
vec4 col2 = mix(col,Color,0.5); // This causes a hard lockup.
gl_FragColor = col2;
// gl_FragColor.a = 1.0;
}