How to draw 2D smooth curve in opengl - opengl

I've searched about drawing splines in opengl, and the solutions I found use many vertices to draw it. Obviously, they are broken when scaled.
How can I draw smooth curve independent of scaling, like vector graphics? Is there any proper way to do it in opengl, or should it be software-rendering way?

You render a quad and pass the spline as uniforms. You will need to use a shader program. Your vertex shader will transform the quad and generate any extra information from your uniforms and and your fragment shader will test if the pixel is on the line.
https://www.shadertoy.com/view/MlfSRN

Related

Texture Mapping in GLSL

I am currently working on a project where I have to texture a cube using the reflection vector between the normal of a fragment and the camera.
I have the sampler2D picture, and I somehow have to implement it to a cube using reflection.
The question is: Can someone explain how this process goes. That would help me finish my project and further understand the process behind texturing.
The thing is that I can't use textureCube(), but texture2D(), so that the fragment shader is applicable to not only cubes but to every surface.
Thank you in advance for the answer!
The thing is that I can't use textureCube(), but texture2D(), so that the fragment shader is applicable to not only cubes but to every surface.
Why do you have to do this? Implementing this yourself with texture2D (...) is going to involve multiple texture lookups. textureCube (...) will leave the implementation details hidden and can even seamlessly filter stuff on supported hardware.
In all cases, the fact that it is called a cubemap means nothing about the surface you are mapping it onto, it is actually the texture itself that is a cube (six 2D textures define all of the cube faces).
When you sample a cubemap, you are shooting a ray through this virtual cube and the color or depth returned is where that ray intersects it. The sampled value will come from at least one of the six cube faces, possibly multiple cube faces depending on the texture filter setup.

GLSL Geometry Shaders and projection matrices

So from playing around with it so far, I gather that GLSL geometry shaders work after the input vertices are transformed by the projection/modelview matrices. In other words, the geometry shaders processes things on clip coordinate.
What if I was to use the geometry shader to transform GL_POINTS into, say, cubes made out of GL_TRIANGLES? When calculating things on clip coordinates, the resulting shape always seem to face you / ignore rotations/scaling etc.
Also, it seems that GL_TRIANGLES is not supported as one of the possible geometry output types. But I tried anyways, and it seems to work. I suppose this is video card dependent? Is it possible to make cubes if GL_TRIANGLES is not supported? Make zero width triangle strips in between spaces maybe??
You are using shaders: geometry shaders work on whatever the vertex shader passed them. If you want that to be clip-space values, then the geometry shader works on clip-space values. If your vertex shader passes them eye-space values, then the geometry shader must work on eye-space values.
What matters is what the final pre-rasterization shader stage outputs to gl_Position. That is what needs to be in homogeneous clip-space. A vertex shader that has a geometry shader behind it doesn't even need to write to gl_Position.
Also, it seems that GL_TRIANGLES is not supported as one of the possible geometry output types.
You must be using ARB_geometry_shader4, not the actual core geometry shader functionality. You probably should avoid that extension if you are able. Any hardware that has geometry shaders can run OpenGL 3.2.
In any case, the core feature doesn't support triangles as output. It supports points, line strips, and triangle strips.
Is it possible to make cubes if GL_TRIANGLES is not supported?
That's what EndPrimitive() is for. You call it when you are finished with a primitive; there's nothing that stops you from emitting a second primitive. Or third.
Also, you should be advised that this will probably be slow. Geometry shaders are not known for fast rendering performance.

Using the geometry shader for instancing

So I want to draw lots of quads (or even cubes), and stumbled across this lovely thing called the geometry shader.
I kinda get how it works now, and I could probably manipulte it into drawing a cube for every vertex in the vertex buffer, but I'm not sure if it's the right way to do it. The geometry shader happens between the vertex shader and the fragment shader, so it works on the vertices in screen space. But I need them in world space to do transformations.
So, is it OK to have my vertex shader simply pipe the inputs to the geometry shader, and have the geometry shader multiply by the modelviewproj matrix after creating the primitives? It should be no problem with the unified shader architecture, but I still feel queasy when making the vertex shader redundant.
Are there alternatives? Or is this really the 'right' way to do it?
It is perfectly OK.
Aside from that, consider using instanced rendering (glDrawArraysInstanced,glDrawElementsInstanced) with vertex attribute divisor (glVertexAttribDivisor). This way you can accomplish the same task without geometry shader at all.
For example, you can have a regular cube geometry bound. Then you have a special vertex attribute carrying cube positions you want for each instance. You should bind it with a divisor=1, what will make it advance for each instance drawn. Then draw the cube using glDraw*Instanced, specifying the number of instances.
You can also sample input data from textures, using gl_VertexID or gl_InstanceID for coordinates.

Polygonal gradients with OpenGL

I'm wondering how I could create a gradient wuth multiple stops and a direction if I'm making polygons. Right now I'm creating gradients by changing the color of the verticies but this is limiting. Is there another way to do this?
Thanks
One option you may have is to render a simple polygon with a gradient to a texture, which you then use to texture your actual polygon.
Then you can rotate the source polygon and anything textured with its image will have its gradient rotate as well, without the actual geometry changing.
The most flexible way is probably to create a texture with the gradient you want, and then apply that to your geometry.
If you're using a shader, you can pass your vertex world positions into your vertex shader and they'll interpolate to your fragment shader, so for every fragment, you'll get where it is in world-space (of course you can use any space). Then it's just a matter of choosing whatever transfer function to change that value to a color. You can make any kind of elaborate algorithm using b-splines or whatever in your fragment shader.

Can I use a vertex shader to display a models normals?

I'm currently using a VBO for the texture coordinates, normals and the vertices of a (3DS) model I'm drawing with "glDrawArrays(GL_TRIANGLES, ...);". For debugging I want to (temporarily) show the normals when drawing my model. Do I have to use immediate mode to draw each line from vert to vert+normal -OR- stuff another VBO with vert and vert+normal to draw all the normals… -OR- is there a way for the vertex shader to use the vertex and normal data already passed in when drawing the model to compute the V+N used when drawing the normals?
No, it is not possible to draw additional lines from a vertex shader.
A vertex shader is not about creating geometry, it is about doing per vertex computation. Using vertex shaders, when you say glDrawArrays(GL_TRIANGLES,0,3), this is what specifies exactly what you will draw, i.e. 1 triangle. Once processing reaches the vertex shader, you can only alter the properties of the vertices of that triangle, not modify in any way, shape or form, the topology and/or count of the geometry.
What you're looking for is what OpenGL 3.2 defines as a geometry shader, that allows to output arbitrary geometry count/topology out of a shader. Note however that this is only supported through OpenGL 3.2, that not many cards/drivers support right now (it's been out for a few months now).
However, I must point out that showing normals (in most engines that support some kind of debugging) is usually done with the traditional line rendering, with an additional vertex buffer that gets filled in with the proper positions (P, P+C*N) for each mesh position, where C is a constant that represents the length you want to use to show the normals. It is not that complex to write...
You could approximate this by drawing the geometry twice. Once draw it as you normally would. The second time, draw the geometry as GL_POINTS, and attach a vertex shader which offsets each vertex position by the vertex normal.
This would result in your model having a set of points floating over the surface. Each point would show the direction of the normal from the vertex it corresponds to.
This isn't perfect, but might be sufficient, depending on what it is you're hoping to use it for.
UPDATE: AHA! And if you pass in a constant scaling factor to the vertex shader, and have your application interpolate that factor between 0 and 1 as time goes by, your points rendered by the vertex shader will animate over time, starting at the vertex they apply to, and then floating off in the direction of its normal.
It's probably possible to get more or less the right effect with a cleverly written vertex shader, but it'd be a lot of work. Since this is for debugging purposes anyway, it seems better to just draw a few lines; the performance hit will not be severe.