OpenGL: lines dont get rendered - opengl

Using OpenGL I am trying to render a simple line between the points p1 and p2, but it doesnt work.
However, I am able to render cubes at these positions.
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat mat_ambient[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_flash[] = {0.0, 0.0, 1.0, 1.0};
GLfloat mat_flash_shiny[] = {50.0};
GLfloat light_position[] = {100.0,-200.0,200.0,0.0};
GLfloat ambi[] = {0.1, 0.1, 0.1, 0.1};
GLfloat lightZeroColor[] = {0.9, 0.9, 0.9, 0.1};
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(p1.x, p1.y, p1.z);
glutSolidCube(20);
glLoadIdentity();
glTranslatef(p2.x, p2.y, p2.z);
glutSolidCube(20);
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
I am using the following code for rendering the line. But I cant find the problem why it doesnt get rendered:
glDisable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glLoadIdentity();
glColor3f(1,0,0);
glLineWidth(10.0);
glBegin(GL_LINES); //doesnt work with GL_LINE either
glVertex3f(p1.x, p1.y, p1.z);
glVertex3f(p2.x, p2.y, p2.z);
glEnd();

I assume what happens is that the lines are actually rendered, but there's still a vertex normal set, pointing away from the light source, or being 0. Easy fix: Disable lighting when drawing lines.
While it is possible to "illuminate" lines, the whole operation makes no sense if one assumes the "regular" normal based illumination models. Lines don't have a normal direction, they have a normal plane (or in other words, a line it it's tangent itself).
So the proper way to illuminate a line is by tangent based shading. Fixed function OpenGL can't do it, but it is trivial to implement with a shader.

A couple of suggestions for you, w.r.t your second code snippet:
1) You probably don't need the 'glEnable(GL_COLOR_MATERIAL)', try commenting out that line.
2) You're passing int's to glColor3f(). Try using glColor3f(1.0f, 0.0f, 0.0f); instead.
Also, did you check the line drawing without the cube at the same position? (ie., is it being occluded or not)

Related

Lighting not working on OpenGL - Solid color

The lighting doesn't work, the object appears with solid color. The color itself changes with the material or lighting parameters but no shadow or anything just solid grey.
Here's part of the code:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glFrontFace(GL_CCW);
glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
GLfloat amb[] = {0.6, 0.6, 0.6, 1.0};
GLfloat dif[] = {0.8, 0.8, 0.8, 1.0};
GLfloat spec[] = {0.5, 0.5, 0.5, 1.0};
GLfloat pos[] = {0.0, 0.0, 30.0};
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
GLfloat co[4]={0.5, 0.5, 0.5, 0.5};
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, co);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
for(int i=0; i < numofTr; i++)
{
glBegin(GL_TRIANGLES);
glNormal3f(tr[i].v1->n.x, tr[i].v1->n.y, tr[i].v1->n.z);
glVertex3f(tr[i].v1->x, tr[i].v1->y, tr[i].v1->z);
glNormal3f(tr[i].v2->n.x, tr[i].v2->n.y, tr[i].v2->n.z);
glVertex3f(tr[i].v2->x, tr[i].v2->y, tr[i].v2->z);
glNormal3f(tr[i].v3->n.x, tr[i].v3->n.y, tr[i].v3->n.z);
glVertex3f(tr[i].v3->x, tr[i].v3->y, tr[i].v3->z);
glEnd();
}
I don't know what I'm missing, the normals look good when displayed along with the object.
You are using dim light on a gray object. Obviously the result is gray.
If you mean that faces are flat shaded, that's because of glShadeModel(GL_FLAT);. Change it to GL_SMOOTH to enable interpolation.
If the object is in 3D, I think that the fact you are only passing 3 floats as position might be relevant; default value is [0,0,1,0], and the function expects four floats (4th being the W coordinate, which should in most cases be equal to 1, or 0 for lights in infinite distance).
Also double check that the data you give to glVertex and glNormal is correct. When rendering a sphere at 0,0,0, the normal of every vertex is the normalized position of such vertex (only holds for spheres, obviously).
As a side note, this code is obviously outdated, and as a disclaimer I would ditch it alltoghether, if you are only learning, and switch to something that's relatively modern and uses programmable pipeline.

OpenGL lighting: half of triangles not lit

I'm using the marching cubes algorithm described here http://paulbourke.net/geometry/polygonise/ to turn a scalar field into a triangle mesh, and then displaying the mesh using OpenGL's GL_TRIANGLES mode. However, I'm having trouble with the lighting.
It seems like half the triangles are not being lit at all, and it's occurring in a distinct pattern.
In the program depicted below I've set the background to red, the front face color to green, and the back face color to blue. There is one light source with position (1.0, 1.0, 1.0, 0.0) and a sphere included for reference.
http://i.imgur.com/JutXhbb.png
And here it is with the triangles flipped, as in the drawing order of the last two vertices are switched:
http://i.imgur.com/iUgqm3N.png (back face color is blue)
Whats really confusing me is why the flipped version has color everywhere whereas the normal version doesn't. I figured that even if I drew stuff wrong, at least the flipped version should reflect the same error. Any idea what's happening?
Here is the complete lighting initialization code:
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat mat_color1[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat mat_color2[] = { 0.0, 1.0, 0.0, 1.0 };
glMaterialfv(GL_BACK, GL_DIFFUSE, mat_color1);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_color2);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_BACK, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);

OpenGL shading not working. Object looks solid colored

I am currently trying to get into OpenGL shading and lighting to display a 3D model exported from Blender in a simple GLUT window.
I tried to display the typical glutSolidTeapot to validate my OpenGL settings.
With the Teapot everything looks perfectly fine as can be seen in the pic below.
If I now want to replace the teapot with my own Blender-exported model, the shading doesn't work. The model ( a car rim ) just looks solid-colored.
The color changes when the model is rotated, but it stays solid all the time.
What does glutSolidTeapot do under the hood to draw the teapot model?
Here's the code I'm using to set up OpenGL :
void SetupRC()
{
glClearColor(0.4, 0.4, 0.4, 1.0);
// Enable lighting and the light we have set up
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
//Set lighting parameters
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT,light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Enable shading
glShadeModel(GL_SMOOTH);
// Set up the projection parameters
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
}
And the code to repaint the frames :
void RenderScene(void)
{
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0, 0.0, -2.5f);
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set input data to arrays
glVertexPointer(3, GL_FLOAT, 0, BlenderGuru_CarWheelVerts);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
GLfloat ambConst[] = { 0.24725, 0.1995, 0.0745, 1.0};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambConst);
GLfloat diffConst[] = { 0.75164, 0.60648, 0.22648, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffConst);
GLfloat specConst[] = { 0.628281, 0.555802, 0.366065, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specConst);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 51.2);
// draw data
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, BlenderGuru_CarWheelNumVerts);
glDisableClientState(GL_VERTEX_ARRAY);
glFlush();
}
Since you are exporting from Blender, your exported data will most likely also contain normals. If not, make sure you generate them for your model and export them. You need normal data for your lighting to work.
The call to glEnable(GL_AUTO_NORMAL); does not do what you might think it does. It will only
generate normal vectors when either GL_MAP2_VERTEX_3 or GL_MAP2_VERTEX_4 is used to generate vertices.
So export normal data yourself and use this, or perhaps calculate the normals from the mesh data that is available to you.
Your code lacks loading/setting normal data. Without normals, lighting doesn't work.

Making a light source visible in OpenGL

I want to move my light source in my OpenGL-Scene, which is working. But to actually I want to see thee light source as well.
How can I do this?
...
glPushMatrix();
GLfloat lightPos[] = {0, 0, 200, 1};
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
GLfloat ambientLight[] = { 0.2, 0.2, 0.2, 1.0};
GLfloat lightColor[] = { 0.5, 0.5, 0.5, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightColor);
glutSolidSphere(5,50,50);
glPopMatrix();
...
A light source is not a visible object, per se. If you want to "see" a light, you have to place some object at the position that your light is. Maybe use a sphere, a sprite, an arrow (pointing in the direction the light is pointing in, if it's a directional light), etc.

OpenGL alpha blending issue with back face visible

I'm trying to display "transparent" surfaces (not closed volumes) with both the front face and back face are visible (not culled).
For example displaying a cone or cylinder where the transparency is applied on both sides.
There are some visible artifacts where some part of the surface does not seems to be handling the alpha values correctly.
The issue it seems is when I (opengl) is trying to apply the alpha from the front side of the surface to the backside of the surface. (when both the inside/outside of the surface is visible).
void init()
{
glMatrixMode(GL_PROJECTION);
gluPerspective( /* field of view in degree */ 40.0,
/* aspect ratio */ 1.0,
/* Z near */ 1.0, /* Z far */ 10.0);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */
0.0, 0.0, 0.0, /* center is at (0,0,0) */
0.0, 1.0, 0.); /* up is in positive Y direction */
glTranslatef(0.0, 0.6, -1.0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_diffuse);
glLightfv(GL_LIGHT2, GL_POSITION, light2_position);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
//glEnable(GL_CULL_FACE);
glFrontFace( GL_CW );
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void draw ()
{
static GLfloat amb[] = {0.4f, 0.4f, 0.4f, 0.0f};
static GLfloat dif[] = {1.0f, 1.0f, 1.0f, 0.0f};
static GLfloat back_amb[] = {0.4f, 0.4f, 0.4f, 1.0f};
static GLfloat back_dif[] = {1.0f, 1.0f, 1.0f, 1.0f};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_LIGHT1);
glDisable(GL_LIGHT2);
amb[3] = dif[3] = 0.5f;// cos(s) / 2.0f + 0.5f;
glMaterialfv(GL_FRONT, GL_AMBIENT, amb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, dif);
glMaterialfv(GL_BACK, GL_AMBIENT, back_amb);
glMaterialfv(GL_BACK, GL_DIFFUSE, back_dif);
glPushMatrix();
glTranslatef(-0.3f, -0.3f, 0.0f);
glRotatef(angle1, 1.0f, 5.0f, 0.0f);
glutSolidCone(1.0, 1.0, 50, 2 );
glPopMatrix();
///...
SwapBuffers(wglGetCurrentDC()); // glutSwapBuffers();
}
The code is based on : http://www.sgi.com/products/software/opengl/examples/glut/examples/source/blender.c
tinyurled links to 2 images on flickr showing the issue (but from out production code, not the above code, but both have the same kind of problems):
http://flic.kr/p/99soxy and http://flic.kr/p/99pg18
Thanks.
Max.
Your problem is probably a mix of two problems.
as your depth test is enabled, and all polygons write to depth buffer, the polygons that are further away cannot contribute to the pixel color if they are drawn after the nearest polygons. You should try to disable your depth test.
alphablending is a non-commutative operation, so the order is which the triangles are drawn is important and changes the result. To have a consistent result, you'd have to draw the triangles in consistent order. In your code, this order may vary, depending on the viewpoint for instance. As your objects are convex, you could draw your object in two passes, both with culling enabled, the first pass drawing the backfacing triangles (that are the most distant to the camera), then the frontfacing triangles (that are nearest)
More generally, correct blending for arbitrary geometry is a hard problem, you may want to look at Order Independent Transparency algorithms (depth peeling, ...) if you want to go further.