Point sprites w/ programmable renderer

I’m able to render point sprites just fine using the pointsAsTextures example, which uses glsl 1.2. However, I’d like to adapt the shader code to glsl 1.5 to use with a programmable renderer and I can’t get it to work.

Here’s the OF code:

ofPushMatrix();
ofEnableBlendMode(blendMode);
ofEnablePointSprites();

shader.begin();

texture.bind();
vbo.draw(GL_POINTS, 0, (int)points.size());
texture.unbind();

shader.end();

ofDisablePointSprites();
ofDisableBlendMode();

ofPopMatrix();

The vertex shader:

#version 150

uniform mat4 modelViewProjectionMatrix;
in vec4 position;
in vec3 normal;
in vec4 color;
in vec2 texcoord;

out vec4 vColor;
out vec2 texCoordVarying;

void main() {
texCoordVarying = texcoord;
gl_Position   = modelViewProjectionMatrix * position;
gl_PointSize  = normal.x;
vColor      = color;
}

The frag shader:

#version 150
uniform sampler2D tex;
in vec4 vColor;
in vec2 texCoordVarying;

out vec4 outputColor;

void main (void) {

outputColor = texture(tex, texCoordVarying) * vColor;
}

Everything compiles fine with no errors in the console but I’m getting no sprites at all. Can anyone help me understand what is wrong?

edit: if I use sampler2DRect instead of sampler2D I get black squares but no sprite image. The image size is a power of 2, which as I understand it should work with sampler2D. However using sampler2D yields nothing (not even black squares).

I havent tried it here, but in the fragment shader perhaps try the implicit gl_PointCoord as the texture coord https://www.opengl.org/wiki/Fragment_Shader#Inputs

2 Likes

That did it! Thanks very much! :smile:

I can’t seem to get this going (with a programmable renderer). Everything seems to be invisible. The image I’m using is a 128x128 pixels png image. It’s the same one used in the point texture example.

My code looks like this:

setup():

ofBackground(0);
int total = 100;
for (int i = 0; i < total; ++i) {
    vboMesh.addVertex(ofVec3f(ofRandomWidth(), (int) ofRandomHeight(), 0));
}
dot.loadImage("dot.png");
shader.load("shader");

draw():

ofPushMatrix();
ofPushMatrix();
ofEnableBlendMode(ofBlendMode::OF_BLENDMODE_ALPHA);
ofEnablePointSprites();

glPointSize(10);
shader.begin();

dot.getTextureReference().bind();
vboMesh.draw(ofPolyRenderMode::OF_MESH_POINTS);
dot.getTextureReference().unbind();

shader.end();

ofDisablePointSprites();
ofDisableBlendMode();

ofPopMatrix();

shader.vert:

// See http://stackoverflow.com/questions/17397724/point-sprites-for-particle-system
#version 330

uniform sampler2D tex0;

out vec4 fragColor;

void main() {
    fragColor = texture(tex0, gl_PointCoord) * vec4(1.0, 0, 0, 0);
}

shader.frag:

#version 330

uniform mat4 modelViewProjectionMatrix;

in vec4 position;

void main() {
    vec4 modifiedPosition = modelViewProjectionMatrix * position;
    gl_Position = modifiedPosition;
}

What am I doing wrong?

I’ve referred to this post and this post as well, but with no success.

Hi,

My guess is that this will fix it:

ofDisableArbTex();
dot.loadImage("dot.png");

OF has rectangle textures enabled by default, which gives you texture coordinates of 0…imageWidthInPixels, whereas gl_PointCoord is in the range of 0…1

https://www.opengl.org/registry/specs/ARB/texture_rectangle.txt

In case you for some other purposes want to sample a rectangle texture in a shader the uniform would look like this:
uniform sampler2DRect tex0;

and you’d read it using:

textureRect(tex0, vec2(x,y) );

Hey @hahakid, I did try that earlier (but didn’t know that’s what it meant).

Adding ofDisableArbTex() doesn’t help - even if I create a new ofImage instance after that line.

What else could it be?

Then I am stumped. If you don’t bind the shader, do you get anything on screen?

Actually, one thing you are doing in the shader is to multiply the color you grab from the texture by vec4(1.0, 0, 0, 0), which will set the alpha to 0.

1 Like

That was it! Correcting the colour fixed it. Thanks!

Did something change between core versions 330 and 400? Using the exact same code which I had posted here earlier (with modifications from @hahakid), the point sprites are invisible with of 0.9.8 on OSX.

Furthermore, to debug, I set my fragment shader to always output white (vec4(1.0, 1.0, 1.0, 1.0)), but nothing shows up on the screen at all :frowning:

Just to re-iterate, this is what my code looks like now (adapted for 0.9.8):
setup():

    ofSetLogLevel(OF_LOG_VERBOSE);
    ofBackground(0);
    int total = 100;
    for (int i = 0; i < total; ++i) {
        vboMesh.addVertex(ofVec3f(ofRandomWidth(), (int) ofRandomHeight(), 0));
    }
    ofDisableArbTex();
    ofLoadImage(texture, "dot.png");
    shader.load("shader");

draw():

    ofPushMatrix();
    ofEnableBlendMode(ofBlendMode::OF_BLENDMODE_ALPHA);
    ofEnablePointSprites();

    glPointSize(10);
    shader.begin();

    texture.bind();
    vboMesh.draw(ofPolyRenderMode::OF_MESH_POINTS);
    texture.unbind();

    shader.end();

    ofDisablePointSprites();
    ofDisableBlendMode();

    ofPopMatrix();

shader.vert:

#version 400

uniform mat4 modelViewProjectionMatrix;

in vec4 position;

void main() {
    vec4 modifiedPosition = modelViewProjectionMatrix * position;
    gl_Position = modifiedPosition;
}

shader.frag:

#version 400
uniform sampler2D tex0;

out vec4 fragColor;

void main() {
    fragColor = texture(tex0, gl_PointCoord) * vec4(1.0, 1.0, 1.0, 1.0);
}

Is this broken in the latest release?

Got this fixed! I just had to set gl_PointSize = 10; in the vertex shader (setting it outside didn’t help for some odd reason).