How to draw point sprites of different sizes in OpenGL? - macos

I'm making a small OpenGL Mac app that uses point sprites. I'm using a vertex array to draw them, and I want to use a similar "array" function to give them all different sizes.
In OpenGL ES, there is a client state called GL_POINT_SIZE_ARRAY_OES, and a corresponding function glPointSizePointerOES() which do exactly what I want, but I can't seem to find an equivalent in standard OpenGL.
Does OpenGL support this in any way?

To expand a little on Fen's answer, the fixed function OpenGL pipeline can't do exactly what you want. It can do 'perspective' points which get smaller as the Z distance increases, but that's all.
For arbitrary point size at each vertex you need a custom vertex shader to set the size for each. Pass the point sizes either as an attribute array (re-use surface normals or tex coords, or use your own attribute index) or in a texture map, say a 1D texture with width equal to size of points array. The shader code example referred to by Fen uses the texture map technique.

OpenGL does not support this Apple extension, but you can do it other other way:
For fixed pipeline: (opengl 1.4 and above)
You need to setup point parameters:
float attenuation[3] = {0.0f, 1.0f, 0.0f};
glPointParameterfvEXT(GL_POINT_DISTANCE_ATTENUATION, attenuation);
glPointParameterfEXT(GL_POINT_SIZE_MIN, 1.0f);
glPointParameterfEXT(GL_POINT_SIZE_MAX, 128.0f);
glEnable(GL_POINT_SPRITE);
OpenGL will calculate point size for you that way
Shaders
Here is some info for rendering using shaders:
http://en.wikibooks.org/wiki/OpenGL_Programming/Scientific_OpenGL_Tutorial_01

If by "Does OpenGL support this", you mean "Can I do something like that in OpenGL", absolutely.
Use shaders. Pass a 1-dimensional generic vertex attribute that represents your point size. And in your vertex shader, set that point size as the gl_PointSize output from the vertex shader. It's really quite simple.
If you meant, "Does fixed-function OpenGL support this," no.

Related

OpenGL 2d (orthographic) rendering for GUI, the modern way

I want to render GUI components in my OpenGL program. They are still just simple textured (vbo) rectangles.
I would like to get the following things done, the right way.
Drawing using screen coordinates, or at least using a coordinate system that's not based on perspective-like floating points. For example: now the coordinate system is from -1f to 1f (left to right of the screen). It would be more logical to use screen/pixel coordinates.
If it's easy to do, I'd like that the GUI doesn't stretch when the window (viewport) resizes.
I know, previously you could do a lot using the deprecated function glOrtho. But since I want to do it the modern way, which is hopefully also better for performance, I don't know how to start.
After searching on the internet, I came to the conclusion that I have to use a shader. I'm not very familiar with shaders.
And another question: does performance increase when doing this using a shader?
What you do with modern OpenGL is essentially the same as using glOrtho to setup a orthographic projection matrix: Create a transformation (matrix) that maps coordinates 1:1 into viewport coordinates and use that to transform the coordinates.
For example you could create a vec2 uniform viewport and set that to the viewport width/height. Then in the vertex shader you can use that to transform your vertex pixel coordinate positions into the range [-1,1], like this
gl_Position = vec4(2*vpos.xy / viewport.xy - 1, 0, 1);

GLES fragment shader, get 0-1 range when using TextureRegion - libGDX

I have a fragment shader in which I use v_texCoords as a base for some effects. This works fine if I use a single Texture, as v_texCoords always ranges from 0 - 1, so the center point is always (0.5, 0.5) for example. If I am drawing from part of a TextureRegion though, my shader messes up because v_texCoords no longer ranges from 0-1. Is there any methods or variabels I can use to get a consistent 0-1 range in my fragment shader? I want to avoid setting uniforms as this would mean I need to flush the batch for every draw.
Thanks!
Nothing like this exists at the shader level - TextureRegions are entirely a libgdx construct that doesn't exist at all at the OpenGL ES API level.
Honestly for what you are trying I'd simply suggest not overloading the texture coordinate for two orthogonal purposes, and just add a separate vertex attribute which provides the 0-to-1 number.

How do I render a custom set of screen coordinates in Opengl

Is there any way to render a different set of screen coordinates than the standard equidistant grid between -1,-1 to 1,1?
I am not talking about a transformation that can be accomplished by transformations in the vertex shader.
Specifically ES2 would be nice, but any version is fine.
Is this even directly OpenGl related or is the standard grid typically provided by plumbing libraries?
No, there isn't any other way. The values you write to gl_Position in the vertex (or tesselation or geometry) shader are clip space coordinates. The GPU will convert these to normalized device space (the "[-1,1] grid") by dividing by the w coordinate (after the actual primitive clipping, of course) and will finally use the viewport parameters to transform the results to window space.
There is no way to directly use window coordinates when you want to use the rendering pipeline. There are some operations which bypass large parts of that pipeline, like frambuffer blitting, which provides a limited way to draw some things directly to the framebuffer.
However, working with pixel coordinates isn't hard to achieve. You basically have to invert the transformations the GPU will be doing. While typically "ortho" matrices are used for this, the only required operations are a scale and a translation, which boils down to a fused multiply-add per component, so you can implement this extremely efficient in the vertex shader.

Efficiently sending values to GLSL shader

I am trying to write my particle system for OpenGL ES 2.0. Each particle is made up of 4 vertexes, forming the little square where a transparent texture is drawn.
The problem is: each particle has its own properties (color, position, size), that are constant across the 4 vertexes of that particle. The only variation for each vertex is what corner of the square it is.
If I am to send the properties of the particle via uniform variables, I must do:
for(each particle) { // do maaaany times
glUniform*(...);
glDrawArray(...); // only draw 4 vertexes
};
this is clearly inefficient, since I will only draw 4 vertexes per glDrawArray call.
If I send this properties via attribute variables, I must fill the same information 4 times for each fragment in the attribute buffer:
struct particle buf[n];
for(each particle) {
struct particle p;
p = ...; // Update particle
buf[i+0] = buf[i+1] = buf[i+2] = buf[i+3] = p;
};
glBufferData(..., buf, ...);
// then draw everithing once afterwards...
what is memory inefficient and seems very ugly to me. So what is the solution to this problem? What is the right way to pass parameters that change for each few vertexes to the shader?
Use point sprites. The introduction is very explicit about how to solve your problem.
You can also combine the use of point sprites with another extension, point_size_array.
...
As Christian Rau has commented, the point_size_array is no more usefull using programmable pipeline: set the maximum point size as usual, then discard fragments basing on their distance from the point center, derived from texture coordinates generated by OpenGL. The particle size shall be sent via additional attribute.
GL ES doesn't really have a good solution to this. Desktop OpenGL allows for instancing and various other tricks, but ES just doesn't have those.
You can use a Uniform Buffer Object. Note that this feature is only available on D3D10+ hardware.
Send the information via a texture. I'm not sure that texture sampling is supported in opengl-es 2.0 vertex shaders, but if it is, then that would be optimal.

OpenGL ES set Texture matrix for different Texturing units

with
glMatrixMode(GL_TEXTURE);
..some matrix operations...
i can change the current texture transformation matrix. However - it seems it affects not all texture units (i'm using multitexturing)
how can i change the texture matrix for different texture units?
thanks!
Try using glActiveTexture to select the appropriate texture matrix stack. This works for OpenGL, and I assume that it should also work for OpenGL ES.

Resources