gl_PointSize problem

I have been trying to write some code to draw lines and points with different sizes.

I have tried this in the vertex shader:
//Vertex shader
void main()
{
gl_Position = …;
gl_PointSize = 3.0;
}

if I modify the value of gl_PointSize anything happens (between 1 and 63), the points are always drawn in the same way. What am I doing wrong?

I see the same thing.

A bit of Googling suggests that there are known problems with ATI 2400/2600 series cards (Mailing List Archive), and I have an ATI 2400 on this machine – so if you have a similar card, that might be your problem.

If you have a different card, it might be worth checking that you’ve enabled point sizes:

    gl.enable(gl.POINT_SPRITE);
    gl.enable(gl.VERTEX_PROGRAM_POINT_SIZE);
    gl.drawArrays(gl.POINTS, 0, 3);

Thank you for your response, you have given me really helpful advice.
My card is NVidia Geforce 9400. I have tried your solution:
gl.enable(gl.POINT_SPRITE);
gl.enable(gl.VERTEX_PROGRAM_POINT_SIZE);
but It still does not work.

So I have made a little research and have found that:
gl.VERTEX_PROGRAM_POINT_SIZE (WebGL version) --> GL_VERTEX_PROGRAM_POINT_SIZE (OpenGL SE 2.0 specification)
is not yet implemented in WebToolKit, almost in the version I downloaded last week. It doesn’t mean you can not enable this feature, it only means that a handler has not yet been written.

The solution, until the code is updated, is easy, change:
gl.enable(gl.VERTEX_PROGRAM_POINT_SIZE); (will work in upgraded WebGL version, future)
to
gl.enable(0x8642); (my WebToolKit version)

This magic number can be found in the GL.h file of the sourcecode of OpenGL ES 2.0 which is the core behind WebGL. You can find similar numbers for gl.BLEND, etc, that are actually implemented.

About POINT_SPRITE feature I think (not completely sure) this only works for OpenGL, not for OpenGL ES. I have search the magic number for this number, in the same file, and I haven’t found anything.

I hope anybody could find this helpful until someone fix the issue.
Giles, thank you for pointing me to the right direction.

(Maybe at this time the WebToolKit has been already updated so this instructions are not really useful … :X)

Neither VERTEX_PROGRAM_POINT_SIZE nor POINT_SPRITE are defined in gl.h for OpenGL ES 2.0. Maybe ES 2.0 does not support them?

However, there is an extension GL_OES_point_sprite, which defines point sprites above ES 1.0.

Hi Coolcat,

You are completely right. I have check http://www.khronos.org/registry/gles/api/2.0/gl2.h and there is no reference to GL_VERTEX_PROGRAM_POINT_SIZE or GL_POINT_SPRITE.

The one I use was http://www.khronos.org/opengles/headers/2_0/GL.h, and in this file you can find:


/* Shaders */
#define GL_VERTEX_PROGRAM_POINT_SIZE      0x8642
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A

which is the ‘magic number’ I used to get gl_PointSize working.

The first file seems to be newer but If I do not enable GL_VERTEX_PROGRAM_POINT_SIZE with this code:

gl.enable(0x8642);

the size of the pixel are always 1 pixel (always refering to WebToolKit implementation of WebGL).

Maybe someone from Khronos group could give us more advice.

Hi,
I don’t know too much about how WebGL is layering on GL or GLES, but I can tell you that in GLES2.0 the only way to specify a point’s size is through the gl_PointSize variable in the GLSL ES. This differs from desktop GL, which has a piece of API state controlled through glPointSize, and an enable GL_VERTEX_PROGRAM_POINT_SIZE which determines whether the API state or the shader state is used. I suspect your problem relates to the mapping between the GLES and the GL ways of specifying the sizes of points.

Doubt this will help solve your problem, but a bit of information is never a bad thing…
Thanks
Ben

Interesting, it’s quite true that GL_POINT_SPRITE and GL_VERTEX_PROGRAM_POINT_SIZE aren’t part of the OpenGL ES 2.0 spec, I wonder why they’re included as constants in the WebGL context? Perhaps it was a case of copy/paste from somewhere.

I’ve checked my OpenGL ES book, which agrees entirely with what MrB says – that all you need to do to set the point size is set the gl_PointSize variable in the vertex shader, which is of course what you were originally doing!

gl_PointSize is always enabled/available on ES 2.0; implementations mapping WebGL to desktop GL should be unconditionally enabling GL_VERTEX_PROGRAM_POINT_SIZE. We do this in Firefox currently, though I admit I’ve never tested gl_PointSize – I’d be interested to hear if things are working as intended.

When I tried setting gl_PointSize on Firefox, the points still came out as 1px in size.

If I understand jgrarod correctly, he was getting the same effect in WebKit but was able to work around it by calling

gl.enable(0x8642);

Has anybody tried drawing point sprites recently? I’m using Minefield with “gl.enable(0x8642)” and it works fine - but it’s not defined anywhere in the current draft spec. After reading through this thread and looking through the specs for myself, I agree that we shouldn’t need to enable anything to be able to render point sprites, but when I comment out the “gl.enable(0x8642)”, my points disappear. Is anybody successfully rendering point sprites with code that conforms to the draft spec?

Yes, I was successful rendering point sprites. That glEnable-thing is not required. However, point sprites can only have a size of 1 pixel, which makes them useless.

For WGT I’m using a static VBO which is created as follows:

WebGLFloatArray wglVertices = WebGLFloatArray.create(pointCapacity * 3 * 4);
for (int idx=0; idx<pointCapacity; ++idx) {
	int i = idx*12;
	wglVertices.set(i+ 0, -1.0); wglVertices.set(i+ 1,  1.0); wglVertices.set(i+ 2, idx);
	wglVertices.set(i+ 3, -1.0); wglVertices.set(i+ 4, -1.0); wglVertices.set(i+ 5, idx);
	wglVertices.set(i+ 6,  1.0); wglVertices.set(i+ 7,  1.0); wglVertices.set(i+ 8, idx);
	wglVertices.set(i+ 9,  1.0); wglVertices.set(i+10, -1.0); wglVertices.set(i+11, idx);
}

These vertices are transformed in the vertexshader according to an uniform array containing the actual positions:

uniform mat4 uModelViewProjection;
uniform vec2 uRadius;
uniform vec3 uCoords[100];

attribute vec3 aPosition;
varying vec2 vTexCoord;
void main() {
	int index = int(aPosition.z);
	gl_Position = uModelViewProjection * vec4(uCoords[index], 1.0);
	gl_Position /= gl_Position.w;
	gl_Position.xy += uRadius * aPosition.xy;
	vTexCoord = aPosition.xy * 0.5 + 0.5;
}

This does work fine, the only problem is that the number of uniforms is limited. However, MAX_VERTEX_UNIFORM_VECTORS is at least 128, so it should be save to render 100 points at once. The render larger point clouds you could tried to use textures to store the coordinates. But, that’s complicated because float textures are not available.

Oh yeah…you’re right. Without the glEnable it does draw the sprites. I just couldn’t see them at 1 pixel until I looked really close. Thanks for your response, Coolcat.