Rendering smooth spheres and cylinder with gluSphere() and gluCylinder() - c++

I am using OpenGL with C++ (but without shaders and GLSL) and drawing spheres (the pool ball) and cylinders (the cue stick) using the glu library functions to draw them. I am using glBindTexture() to bind the texture and loading the texture using the SOIL library.
As you can see from the screenshots there are jagged edges to both the cylinder and the sphere. Calling the following glHint() How do I get rid of the jagged edges. The gluSphere() has 25 stacks and slices, and the gluCylinder() has 100 stacks and slices. Increasing the stacks and slices does not improve the image quality.
Using freeglut for the rest of the drawing
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); //Smooth polygons
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Best perspective corrections
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); //Smooth points
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); //Smooth lines

First of all your question is related to aliasing term, this is what is happen when tringles and some other primitives (these are very basic objects which create whole scene) are rasterized (based on geometric description some pixels on the screen are colored or not).
Try to look for "How to turn on antialiasing" - here is many usefull informations about this and some related topics: http://www.glprogramming.com/red/chapter06.html.
In your case it will be probably glEnable for GL_POLYGON_SMOOTH and GL_BLEND for sure.
eg.
glEnable (GL_POLYGON_SMOOTH);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint (GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE);
If you plan to use lines there will be GL_LINE_SMOOTH and GL_LINE_SMOOTH_HINT.
For future projects try to not use so complex models if they are far from viewer (making as many slices for sphere), this will cause loss of performance.

Related

How to avoid z-fighting in OpenGL when drawing both the mesh surface and the polygon edges?

Consider the following image:
It has both the mesh surface and the polygon edges visualized. What's more, even though the edges and the faces should have the same z-coordinates on the places where they are drawn and cause z-fighting, in this image, the polygon edges are always visible as long as they are not covered by a (non-adjacent) polygon, and there is no visible z-fighting. How can this be achieved in OpenGL?
I usually just enable some MSAA on the frame buffer I'm rendering to, and then just do:
glDepthFunc(GL_LESS);
drawShadededMesh();
glDepthFunc(GL_LEQUAL);
drawWireMesh();
That usually works well enough in most cases. Failing that(as mentioned in the comments) you can experiment with glPolygonOffset.
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0, 1.0); ///< may need adjustment for your use case
glDepthFunc(GL_LESS);
drawShadededMesh();
glDisable(GL_POLYGON_OFFSET_FILL);
glDepthFunc(GL_LEQUAL);
drawWireMesh();

Is there any way to make front face of gluCylinder() transparent?

I am using gluCylinder() to create a cylinder in openGL and then plotting points inside the cylinder with Depth Test On .
When i see the front view of the cylinder, the points inside the cylinder are obstructed by front face.
To make front face of the cylinder translucent i am using Blending.
I am using below functions.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
But whatever coloring or alpha value i assign to the cylinder the front face is not looking transparent due to its back face.
Tell whether it is possible to do with blending only or else i need to introduce lighting for both the faces of Cylinder.Here it clearly visible the change in the color of front face and back face of cylinder. And the points inside the cylinder are not visible due to being obstructed by front face of cylinder.
You should be able to accomplish this by drawing the cylinder twice, while culling the front faces the first time, and culling the back faces the second time. This way, you can draw the front and back parts differently, e.g. by making the front part transparent.
The code sequence could look like this:
// Draw back part of cylinder, opaque.
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
gluCylinder(...);
// Draw points.
// Draw front part of cylinder, transparent.
glCullFace(GL_BACK);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gluCylinder(...);
glDisable(GL_BLEND);
If I understand you right then no, you can't do it with blending alone.
If the cylinder's normals all point outward then you also won't be able to see the cylinder's internal parts no matter what you do.
I do something similar to show characters behind walls and it goes like this - render your scene normally and save it all to a framebuffer. Then render what you want shown behind with the buffer contents on top, using a custom shader to make a bubble of transparency around the thing you want shown behind.
Not sure if I am explaining it well or not but it unfortunately requires multiple steps to get the results you want.
Your problem is still a bit unclear to me despite the image but I will attempt to answer based on my perception of your issue.
You are drawing a cylinder and have geometry (lines or other models) inside the cylinder. You want the cylinder to look translucent so the inner objects are visible. Here is one way to do it. Assuming your render functions are drawCylinder() and drawPoints().
init()
{
...
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
...
}
drawScene()
{
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
drawCylinder();
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
drawPoints();
}
doing so will make sure that the points are drawn regardless of the cylinder. Try using lower values of alpha for your cylinder color.
Please note this is one way to do it. I suggest using shaders to have more control over blending as well as exploring fragment/pixel discard options.

Shader transparancy not working with one half

glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
and used this in the fragment shader.
I've used Alpha blend to get the transparency working however it only seems to work from one side.
Not sure what the problem is, am new to programming and shading.
http://imgur.com/WDK4qjc Link to see the picture
I think you see 2 distant faces blending where color is darker.
Maybe Culling is not activated.
Face culling is the ability to discard face drawing upon certain condition.
To achieve what you want, You have to discard faces not facing the camera which is call backface culling. You do this:
glEnableGL(GL_CULL_FACE); //(enable face culling)
glCullFace(GL_BACK); //(discard back faces)
Everything is fine. It's called Transparency Sorting.
Some more info:
http://www.opengl.org/archives/resources/faq/technical/transparency.htm
Rendering transparent objects in OpenGL
opengl z-sorting transparency

Anti-aliasing with GL_TRIANGLE_FAN

I'm not getting any anti-aliasing when using drawing GL_TRIANGLE_FANs with this code:
glDisable(GL_DEPTH_TEST);
// Blended points, lines, and polygons.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
What am I doing wrong?
Edge antialiasing is always a hint, the implementation (you don't specify which) is free to ignore it per the spec. For various reasons (e.g. the inability to handle intersecting polygons, bad interactions with framebuffer blending) this sort of antialiasing has fallen out of favor and been replaced by multisample-based algorithms that work at the framebuffer level. There is an ARB multisample extension to control this (I believe it's default in recent versions of the spec, actually). Or often the drivers have ways to enable it globally without source code modification.

Generate texture from polygon (openGL)

I have a quad and I would like to use the gradient it produces as a texture for another polygon.
glPushMatrix();
glTranslatef(250,250,0);
glBegin(GL_POLYGON);
glColor3f(255,0,0);
glVertex2f(10,0);
glVertex2f(100,0);
glVertex2f(100,100);
glVertex2f(50,50);
glVertex2f(0,100);
glEnd(); //End quadrilateral coordinates
glPopMatrix();
glBegin(GL_QUADS); //Begin quadrilateral coordinates
glVertex2f(0,0);
glColor3f(0,255,0);
glVertex2f(150,0);
glVertex2f(150,150);
glColor3f(255,0,0);
glVertex2f(0,150);
glEnd(); //End quadrilateral coordinates
My goal is to make the 5 vertex polygon have the gradient of the quad (maybe a texture is not the best bet)
Thanks
Keep it simple!
It is very simple to create a gradient texture in code, e.g.:
// gradient white -> black
GLubyte gradient[2*3] = { 255,255,255, 0,0,0 };
// WARNING: check documentation, I am not quite sure about syntax and order:
glTexture1D( GL_TEXTURE_1D, 0,3, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, gradient );
// setup texture parameters, draw your polygon etc.
The graphics hardware and/or the GL will create a sweet looking gradient from color one to color two for you (remember: that's one of the basic advantages of having hardware accelerated polygon drawing, you don't have to do interpolation work in software).
Your real problem is: which texture coordinates do you use on the 5 vertex polygon. But that was not your question... ;-)
To do that, you'd have to do a render-to-texture. While this is commonplace and supported by practically every board, it's typically used for quite elaborate effects (e.g. mirrors).
If it's really just a gradient, I'd try to create the gradient in am app like Paint.Net. If you really need to create them at run-time, use a pixel shader to implement render-to-texture. However, I'm afraid explaining pixel shaders in a few words is a bit tough - there are lots of tutorials on this on the net, however.
With the pixel shader, you gain a lot of control over the graphic card. This allows you to render your scene to a temporary buffer and then apply that buffer as a texture quite easily, plus a lot more functionality.