Glut: how to generate constant time interval for uniform movement? - c++

I'm trying to rotate a red triangle and a green triangle one after another after a constant time interval. I tried the following code and the time interval is not constant.I can't figure out the problem.
static void display(void)
{
now=glutGet(GLUT_ELAPSED_TIME);
elapsedTime = now - interval;
if(flag)
{
if(now%3000==0)
{
flag=false;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0);
glRotatef(0.1,0.0,0.0,1.0);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5f, 0.5f, -5.0f);
glVertex3f(-1.0f, 1.5f, -5.0f);
glVertex3f(-1.5f, 0.5f, -5.0f);
glEnd();
glutSwapBuffers();
}
else
{
if(now%3000==0)
{
flag=true;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(0,1,0);
glRotatef(-0.1,0.0,0.0,1.0);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5f, 0.5f, -5.0f);
glVertex3f(-1.0f, 1.5f, -5.0f);
glVertex3f(-1.5f, 0.5f, -5.0f);
glEnd();
glutSwapBuffers();
}
}

Before anything, have you tried debug 101: print key variables? I am pretty confident that if do cout << now % 3000 << endl you can find the source of the problem yourself.
For the answer:
now % 3000 == 0
Does not seem like a good idea.
How can you be sure that glutGet(GLUT_ELAPSED_TIME) will increment as 1, 2, 3, ...? What if rendering one frame takes 2 ms and the following happens:
2998, 2999, 3001? You just lost one switch time.
Due to the unpredictable time taken to redraw, it is difficult to be perfectly precise on about rendering times.
In your case, a good approximation could be:
now % 6000 < 3000
This should work well because 3s is much larger than the frequency at which the display will be called.
In most applications however, we want continuous movement, and the best option is to make movement proportional to the actual time lapses with code like:
float dt;
int t, oldT;
t = glutGet(GLUT_ELAPSED_TIME);
dt = (t - oldT)/1000.0;
oldT = t;
drawTriangle(rotationSpeed * dt);

Related

Can't rotate object around its own center on mouse click OpenGL

I succesfully managed to rotate my object but I need to right click on the object to stop its rotation. I don't know how to make the object to rotate just around its center and then stop, I'll attach the code to see exactly what's happening with this shape. The problem, I think, is with the spinDisplay() function... the thing is that I need to rotate around its center on left mouse click and on the right mouse click I should change the color of the object....
#include <stdlib.h>
#include <math.h>
#include "dependente\freeglut\freeglut.h"
#include "dependente\glfw\glfw3.h"
#include <stdio.h> //incluziuni librarii
float ORG[3] = { 0,0,0 };
static GLfloat spin = 0.0;
GLfloat viewangle = 0, tippangle = 0, traj[120][3]; //variabila pentru unghi camera
GLfloat d[3] = { 0.1, 0.1, 0.1 }; //vector directie
GLfloat xAngle = 0.0, yAngle = 0.0, zAngle = 0.0;
bool draw_triangle = false; //variabila desenat figuri
bool draw_square = false;
bool draw_decagon = false;
void Triangle(void) //draw the triangle shape
{
glBegin(GL_TRIANGLE_FAN);//triangles have a common vertex, which is the central vertex
glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); //V0(red)
glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); //V1(green)
glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(1.0f, -1.0f, 1.0f); //V2(blue)
glEnd();
}
void Square(void) {
glBegin(GL_QUADS);
glVertex2f(-1.0f, 1.0f); // top left
glVertex2f(1.0f, 1.0f); // top right
glVertex2f(1.0f, -1.0f); // bottom right
glVertex2f(-1.0f, -1.0f); // bottom left
glEnd();
}
void Decagon(void) //draw the decagon shape
{
glBegin(GL_POLYGON);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.72f,0.8f, 0.0f); //a1
glVertex3f(0.52f, 0.8f,0.0f); //z
glVertex3f(0.35f, 0.64f, 0.0f); //b1
glVertex3f(0.3f, 0.48f, 0.0f); //d1
glVertex3f(0.35f, 0.3f, 0.0f); //e1
glVertex3f(0.52f, 0.16f, 0.0f); //l1
glVertex3f(0.72f, 0.16f, 0.0f); //m1
glVertex3f(0.9f, 0.3f, 0.0f); //o1
glVertex3f(0.95f, 0.48f, 0.0f); //p1
glVertex3f(0.9f, 0.64f, 0.0f); //c1
glScalef(10, 10, 10);
glTranslatef(1, 2, 3);
glEnd();
}
void Keyboard(unsigned char key, int x, int y) //press a key to perform actions
{
switch (key) {
case 'd': d[0] += 0.1; break; //camera right
case 'a': d[0] -= 0.1; break; //camera left
case 'w': d[1] += 0.1; break; //camera up
case 's': d[1] -= 0.1; break; //camera down
case 'm': d[2] += 0.1; break; //magnify
case 'n': d[2] -= 0.1; break; //minify
case 't': draw_triangle = true; draw_decagon = false; break; //draw pyramid when key is pressed
case 'q': draw_square = true; draw_decagon = false; draw_triangle = false; break; //draw cube when key is pressed
case 'l': draw_decagon = true; draw_triangle = false; draw_square = false; break; //draw prism when key is pressed
case 'x': xAngle += 5; break; //modify x axis angle
case 'y': yAngle += 5; break; //modify y axis angle
case 'z': zAngle += 5; break; //modify z axis angle
default: printf(" Keyboard %c == %d", key, key); //see what key it's pressed
}
glutPostRedisplay();
}
void spinDisplay() //here it's the problematic function
{
spin = spin + 0.1;
if (spin > 360.0)
{
spin = 0.0;
}
glutPostRedisplay();
}
void mouse(int buton, int state, int x, int y)
{
switch (buton) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay);
break;
case GLUT_RIGHT_BUTTON: //here I don't know how to change the color of the shape
glutIdleFunc(NULL);
default:glutIdleFunc(NULL);
break;
}
}
void redraw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glLoadIdentity();
glTranslatef(0, 0, -3);
glRotatef(tippangle, 1, 0, 0); // Up and down arrow keys 'tip' view.
glRotatef(viewangle, 0, 1, 0); // Right/left arrow keys 'turn' view.
glDisable(GL_LIGHTING);
glPushMatrix();
glTranslatef(d[0], d[1], d[2]); // Move box down X axis.
glScalef(0.7f, 0.7f, 0.7f); //increase the object size
glRotatef(zAngle, 0, 0, 1);
glRotatef(yAngle, 0, 1, 0);
glRotatef(xAngle, 1, 0, 0);
glRotatef(spin, 0.0, 0.0, 1.0);
if (draw_triangle)
Triangle();
if (draw_decagon)
Decagon();
if (draw_square)
Square();
glPopMatrix();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(900, 600);
glutInitWindowPosition(300, 300);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("Figure Rotation");
glutDisplayFunc(redraw);
glutKeyboardFunc(Keyboard);
glutMouseFunc(mouse);
glClearColor(0.1, 0.0, 0.1, 1.0);
glMatrixMode(GL_PROJECTION);//specify which matrix is the current matrix, matrix that represents your camera's lens (aperture, far-field, near-field, etc).
gluPerspective(60, 1.5, 1, 10); //set up a perspective projection matrix
glMatrixMode(GL_MODELVIEW); //specify which matrix is the current matrix,matrix that represents your camera (position, pointing, and up vector).
glutMainLoop();
return 1;
}
Solely based on your code, the main problem is at Decagon() for its shape vertices definition.
As such vertices are defined not at the center of the shape itself but defined towards the top right, thus it won't rotate around itself but seem to orbit around the center although your sequence of matrix multiplications are working ok.
For simplicity, I would visualize centering it at 0,0 along xy plane, then define right half of its shape then mirror it back to the left one. You can take advantage of - minus sign. Implicitly take advantage of defining shape in NDC (Normalizd Device Coordinate) space.
Note: not exactly the same ratio as per your original definition, but to get you an idea. You can try swapping the following into yours, then it should rotate around itself.
glBegin(GL_POLYGON);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.25f, 0.5f, 0.0f);
glVertex3f(0.45f, 0.30f, 0.0f);
glVertex3f(0.55f, 0.0f, 0.0f);
glVertex3f(0.45f, -0.30f, 0.0f);
glVertex3f(0.25f, -0.5f, 0.0f);
glVertex3f(-0.25f, -0.5f, 0.0f);
glVertex3f(-0.45f, -0.30f, 0.0f);
glVertex3f(-0.55f, 0.0f, 0.0f);
glVertex3f(-0.45f, 0.30f, 0.0f);
glVertex3f(-0.25f, 0.5f, 0.0f);
//glScalef(10, 10, 10); // this won't have any effect on result
//glTranslatef(1, 2, -3);// the same
glEnd();
You have 2 options here
Completely change the vertices definition (only with Decagon to be similar to above relative to the origin). Other shapes are already good, it's defined relative to the origin.
Carefully determine the origin of the shape regardless of how your defined shape's vertices. Use such position to translate back the shape as part of matrix operation firstly before all other operations (please read on to know why).
Concept of rotation around itself
The concept of rotation around itself is that we need to do the following operations in order
Scale (in this case we don't have)
Rotation
Translation
Scaling although we don't have in this case, should be last otherwise it might affect other two operations.
If we translate first to the arbitrary position, then the rotation will happen around such point. In fact, rotation works relatively to the origin 0,0, thus we just need to do by any means to place the object back to origin first before we proceed, then we can rotate, translate to desire position it should be, and scale.
Let's see your matrix multiplication order
glScalef(0.7f, 0.7f, 0.7f); //increase the object size
glTranslatef(d[0], d[1], d[2]); // Move box down X axis.
glRotatef(zAngle, 0, 0, 1);
glRotatef(yAngle, 0, 1, 0);
glRotatef(xAngle, 1, 0, 0);
glRotatef(spin, 0.0, 0.0, 1.0);
This means we do the following in order
rotate around z-axis with spin angle
rotate around x-axis with xAngle angle
rotate around y-axis with yAngle angle
rotate around z-axis with zAngle angle
Although we could possibly combine the first and last together, but anyway it's ok.
Also you might want to further look at Euler Angles when we rotate around 3 cardinal axes like this, it can lead to Gimbal lock problem but it can be solved by limiting angles user can rotate around a certain axis.
The order is right. This is translated into mathematics terms as S * T * Rz * Ry * Rx * Rspin in which you can see it's inverse of the order in code. Rspin happen first, then Rx then so on.
Now what happen if Decagon shape is defined not relative to the origin, but defined to in the way that it translated to the right.
Take my vertices definition, but + 0.55f for all x position, we will have
glBegin(GL_POLYGON);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.80f, 0.5f, 0.0f);
glVertex3f(1.0f, 0.30f, 0.0f);
glVertex3f(1.10f, 0.0f, 0.0f);
glVertex3f(1.0f, -0.30f, 0.0f);
glVertex3f(0.80f, -0.5f, 0.0f);
glVertex3f(0.30f, -0.5f, 0.0f);
glVertex3f(0.10f, -0.30f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.1f, 0.30f, 0.0f);
glVertex3f(0.30f, 0.5f, 0.0f);
glEnd();
If you swap above code to your vertices definition, then it won't rotate around itself anymore. But we know that it takes -0.55f in x-axis to bring this shape back to origin, thus if we add glTranslatef(-0.55f, 0.0f, 0.0f) to be the first operation to execute then it will work the same.
We'd have
glScalef(0.7f, 0.7f, 0.7f);
glTranslatef(d[0], d[1], d[2]);
glRotatef(zAngle, 0, 0, 1);
glRotatef(yAngle, 0, 1, 0);
glRotatef(xAngle, 1, 0, 0);
glRotatef(spin, 0.0, 0.0, 1.0);
glTranslatef(-0.55f, 0.0f, 0.0f); // <------ add this
In short, translate target object to be at origin first before rotating (around itself), then proceed proper sequence as before.
If you desire to have such object to be located at the location you've defined the shape's vertices i.e. it's to the right +0.55f along x-axis and still rotate around itself. Then you use glTranslatef(d[0] + 0.55f, d[1], d[2]) instead.
Further Notes
The last two gl operations glScalef() and glTranslatef() won't have any effect as you already drew the shape. These two operations get discarded every frame when you call glLoadIdentity().
Just note that source code is still based on fixed-function pipeline of OpenGL. You might want to also take a look at modern programmable pipeline. This will allows you more flexibility in controlling virtual camera thus matrix operations are more clear cut and separated to the object itself whenever we need to move around. So this will make matrix operations easier to grasp, and to understand.
Edit
For additional control and satisfy application requirement as follows
Left click to rotate indefinitely, then left click again to stop
Right click to cycle through the color for rendered shape
We have to have control flags, and information for us to change at any frame time as follows.
bool isSpinning = false;
#define NUM_COLOR 4
int sCurrColor = 0;
GLfloat sColor[NUM_COLOR][3] = {
{1.0f, 1.0f, 1.0f},
{1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f}
};
So for colors, we have white, red, blue, and green. Total in 4 colors, each color has 3 component values for RGB. We start with white color as seen in sCurrColor for our index.
Now your mouse() function would looks like this
void mouse(int buton, int state, int x, int y)
{
switch (buton) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN && !isSpinning)
isSpinning = true;
else if (state == GLUT_DOWN && isSpinning)
isSpinning = false;
break;
case GLUT_RIGHT_BUTTON: //here I don't know how to change the color of the shape
if (state == GLUT_DOWN)
sCurrColor = (sCurrColor + 1) % NUM_COLOR;
break;
default:glutIdleFunc(NULL);
break;
}
}
We optimized moving glutIdleFunc(spinDisplay); to be called inside main() function just before glutMainLoop(). As your requirements, we don't have to change it every frame.
Thus, spinDisplay() is now changed to be
void spinDisplay() //here it's the problematic function
{
if (isSpinning)
{
spin = spin + 3.0;
if (spin > 360.0)
{
spin = 0.0;
}
}
glutPostRedisplay();
}
Probably better to change the name of function to something like display() as it's more generic to not confuse that we have to spin everytime. Anyway, I didn't change this for the sake of brevity and consistency of your code.
Now the last part is to plug in sColor to be used by all those shapes in rendering. For example for Decagon you can do this
glColor3f(sColor[sCurrColor][0], sColor[sCurrColor][1], sColor[sCurrColor][2]);
This will be the same for other shapes if you like to have the same effect by right clicking to cycle through the color.

FireBreath plugin doesn't draw on all plugin instances

I'm building a browser plugin which will draw pictures as a slideshow inside browser windows, however the plugin I created only draws on first plugin instance. If I open multiple instances of the plugin, it keeps on drawing on the first plugin window overlapping each picture.
I'm using opengl to draw picture from the url.
Following is a code which draws dummy opengl tringles in a loop using a thread:
FB::PluginWindowWin *pluginWindowWin = dynamic_cast(pluginWindow);
EnableOpenGL(pluginWindowWin->getHWND(), &hDC, &hRC);
SetFocus(pluginWindowWin->getHWND());
//FB::
static int fps = 1;
GLfloat rotate = 0;
static double start = 0, diff, wait;
wait = 1 / fps;
//return 0;
while (true)
{
//lets check for keyboard input
try
{
FB::Rect pos = pluginWindow->getWindowPosition();
PAINTSTRUCT ps;
if (pluginWindowWin){
hDC = BeginPaint(pluginWindowWin->getHWND(), &ps);
pos.right -= pos.left;
pos.left = 0;
pos.bottom -= pos.top;
pos.top = 0;
rotate += 0.1f;
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(rotate, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(0.87f, -0.5f);
glColor3f(0.0f, 0.0f, 1.0f); glVertex2f(-0.87f, -0.5f);
glEnd();
glBegin(GL_QUADS); // Draw A Quad
glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.5f, 0.5f, 0.0f); // Top Left
glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(0.5f, 0.5f, 0.0f); // Top Right
glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(0.5f, -0.5f, 0.0f); // Bottom Right
glColor3f(0.0f, 0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.0f); // Bottom Left
glEnd(); // Done Drawing The Quad
glPopMatrix();
glRotatef(rotate, 0.0f, 1.0f, 0.0f);
SwapBuffers(hDC);
}
//rtri+=0.1f;
::SetTextAlign(hDC, TA_CENTER | TA_BASELINE);
LPCTSTR pszText = _T("FireBreath Plugin!\n:-)");
::TextOut(hDC, pos.left + (pos.right - pos.left) / 2, pos.top + (pos.bottom - pos.top) / 2, pszText, lstrlen(pszText));
if (pluginWindowWin) {
// Release the device context
EndPaint(pluginWindowWin->getHWND(), &ps);
}
}
catch (...)
{
return 0;
}
Sleep(10);
}//end of while run
Any thing I'm doing wrong here?
From what you've told me in the comments, your primary issue is that you're starting with a flawed example. Remember that every instance of the plugin starts up in the same process; the example you're using is a simplified one which does not use good practices for plugins. Most specifically, it uses several global variables.
In addition to that you are threading but don't seem to be doing any locks to make sure that you are totally threadsafe. You live in someone else's process, you don't own it -- the browser does. You need to be very careful with a lot of things.
Most likely your crash has to do with not shutting down cleanly or perhaps with a race condition in your threading code. The best way to troubleshoot that is to attach a debugger and find out where it's crashing, rather than just running around in circles asking "Why?? why???!?" (exagerating for effect, obviously). You'd be shocked how few people do that simple step -- attaching a debugger -- until I tell them to, but it should always be your first step in troubleshooting a crash.
Finally, it bears asking: Do you realize that you are building this on a technology which won't be available in 6 months? FireFox is removing support for NPAPI at the end of the year. I expect ActiveX to work a bit longer than that, but edge doesn't support it.
FireBreath 2 (in the 2.0 branch) is a major change from firebreath 1 but it supports Chrome via native messaging and will support FireFox as well. there are many trying to convince MS to add native messaging support to Edge, but we'll see how that goes. Feel free to follow that link and vote, since it would help you as well I suspect.
Thing is, you don't get SDL or SDL2 w/ native messaging; you'd have to use WebGL and do the dev on the javascript side, then pull data over native messaging. alternately you could look into using NaCL which does have some opengl / drawing stuff (maybe even SDL? not sure) but is sandboxed and may or may not have the networking things you need. Also, of course, it only works on Chrome.
Food for thought. Good luck.

How to get the whole scene rotate around itself? (my code has a little bug which just lets the objects rotate around themselves)

What must be changed to let me see the impression of flying around the whole fixed scene? My current code just lets me look from a fixed viewpoint at objects each one rotating around itself. Enabling glLoadIdentity() just stops their rotation. Note that 3dWidget::paintGL() is permanently called by a timer every 20ms.
void 3dWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTranslatef(0.5f, 0.5f, 0.5f);
glRotatef(3.0f, 1.0f, 1.0f, 1.0f);
glTranslatef(-0.5f, -0.5f, -0.5f);
glPushMatrix();
//glLoadIdentity();
for (int i = 0; i < m_cubes.count(); i++) {
m_cubes[i]->render();
}
glPopMatrix();
}
void Cube::render() {
glTranslatef(m_x, m_y, m_z); // local position of this object
glCallList(m_cubeId); // render code is in createRenderCode()
glTranslatef(-m_x, -m_y, -m_z);
}
void Cube::createRenderCode(int cubeId) {
m_cubeId = cubeId;
glVertexPointer(3, GL_FLOAT, 0, m_pCubePoints);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, m_pCubeColors);
glNewList(m_cubeId, GL_COMPILE);
{
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, m_numPoints);
glDisableClientState(GL_COLOR_ARRAY);
}
glEndList();
}
void 3dWidget::init(int w, int h)
{
...
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float aspect = w/(float)(h ? h : 1);
glFrustum(-aspect, aspect, -1, 1, 10, 100);
glTranslatef(0., 0., -12);
glMatrixMode(GL_MODELVIEW);
}
EDIT: It seems it's important to know that 2 cubes are created with the following 3D position coordinates (m_x, m_y, m_z):
void 3dWidget::createScene()
{
Cube* pCube = new Cube;
pCube->create(0.5 /*size*/, -0.5 /*m_x*/, -0.5 /*m_y*/, -0.5 /*m_z*/);
pCube = new Cube;
pCube->create(0.5 /*size*/, +0.5 /*m_x*/, +0.5 /*m_y*/, +0.5 /*m_z*/);
}
Use gluLookAt to position the camera. You apply it to the modelview matrix before any object transforms.
Obviously, you'll have to figure out a path for the camera to follow. That's up you and how you want the "flight" to proceed.
EDIT: Just to be clear, there's no camera concept, as such, in OpenGL. gluLookAt is just another transform that (when applied to the modelview matrix) has the effect of placing a camera at the prescribed location.
If you really are just trying to rotate the world, your code seems to perform the transforms in a reasonable order. I can't see why your objects rotate around themselves rather than as a group. It might help to present a SSCCE using glut.
Now I've found the reason by myself. It works as soon as I change method paintGL() to
void 3dWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#if 0 // not working
glTranslatef(0.5f, 0.5f, 0.5f);
glRotatef(3.0f, 1.0f, 1.0f, 1.0f);
glTranslatef(-0.5f, -0.5f, -0.5f);
#else // this works properly, they rotate horizontally around (0,0,0)
glRotatef(3.0f, 0.0f, 1.0f, 0.0f);
#endif
for (int i = 0; i < m_cubes.count(); i++) {
m_cubes[i]->render();
}
}
I don't get it exactly why, but it obviously appeared that some transformations had compensated in a way that the objects just rotate around itself. Thanks for your help anyway.
I think it's always better to let the scene rotate than to move by gluLookAt (beside the issue that finding the right formula for the angle of view is more difficult).

OpenGL illumination and shining

I have to put illumination in a OpenGL picture but i don't know how to put a correct point light illumination like in the following picture:
For now i had tried different mode of illumination, but the result is the following :(
I attach you the code that I used for my result. What is wrong?
float specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };
// Light values and coordinates
float ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f };
float diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f };
float specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
float lightPos[] = { 0.0f, -150.0f, -150.0f, 1.0f };
glEnable ( GL_LIGHTING ) ;
glLightfv(GL_LIGHT0,GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,specref);
glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,128);
glEnable ( GL_COLOR_MATERIAL ) ;
glClearColor (1.0, 1.0, 1.0, 1.0);
glColor3f(0.0,0.0,0.0);
Edit 04/11/2011 0.39 CET
I attach also my display() function called by glutDisplayFunc(display);
void display(void)
{
[...]
//Draw polygons in 3d
glColor3f(0.0,1.0,1.0);
glBegin(GL_QUADS);
for(i=0;i<NVERT-1;i++) {
for (j=0;j<NVERT-1;j++) {
glVertex3f( (GLfloat)((sb[i*NVERT+j]).x()),
(GLfloat)((sb[i*NVERT+j]).y()),
(GLfloat)((sb[i*NVERT+j]).z()));
glVertex3f( (GLfloat)((sb[i*NVERT+j+1]).x()),
(GLfloat)((sb[i*NVERT+j+1]).y()),
(GLfloat)((sb[i*NVERT+j+1]).z()));
glVertex3f( (GLfloat)((sb[(i+1)*NVERT+j+1]).x()),
(GLfloat)((sb[(i+1)*NVERT+j+1]).y()),
(GLfloat)((sb[(i+1)*NVERT+j+1]).z()));
glVertex3f( (GLfloat)((sb[(i+1)*NVERT+j]).x()),
(GLfloat)((sb[(i+1)*NVERT+j]).y()),
(GLfloat)((sb[(i+1)*NVERT+j]).z()));
}
}
glEnd();
glFlush();
}
In practice with display I write the small areas that compose the 2° figure that i represented (I omitted the algorithm for the calculation of the points of each area because is it working).
My goal is to have a result similar to figure 1 for the lightning and rendering of the figure but I only obtained the result in figure 2.
I don't know how to put correctly the light and how to setup my figure in order to have this render (like mirror).
You're missing normals. You either need to provide one normal per vertex (glNormal) or you could enable GL_AUTO_NORMALS if you use glMap2 (which you are not). There's an article on how to compute normals for a triangle or polygons on opengl.org that you probably will find useful.
Begin Function CalculateSurfaceNormal (Input Polygon) Returns Vector
Set Vertex Normal to (0, 0, 0)
Begin Cycle for Index in [0, Polygon.vertexNumber)
Set Vertex Current to Polygon.verts[Index]
Set Vertex Next to Polygon.verts[(Index plus 1) mod Polygon.vertexNumber]
Set Normal.x to Sum of Normal.x and (multiply (Current.y minus Next.y) by (Current.z plus Next.z))
Set Normal.y to Sum of Normal.y and (multiply (Current.z minus Next.z) by (Current.x plus Next.x))
Set Normal.z to Sum of Normal.z and (multiply (Current.x minus Next.x) by (Current.y plus Next.y))
End Cycle
Returning Normalize(Normal)
End Function
From the image you posted of the results it seems you are calculating and drawing the normals (red arrows), just not applying them.
Can't really figure out what's happening with your code. I hope your cordinates are between -1 to +1. I'd suggest you to work with lighting with simple primitives. the work on with your surface generation. The lighting source's position and calculating normals are the most important points.
http://www.falloutsoftware.com/tutorials/gl/gl8.htm
http://glprogramming.com/red/chapter05.html

Begun learning OpenGL, need help figuring out this problem

So I have begun learning OpenGL, reading from the book "OpenGL Super Bible 5 ed.". It's explains things really well, and I have been able to create my first gl program myself! Just something simple, a rotating 3d pyramid.
Now for some reason one of the faces are not rendering. I checked the vertecies (plotted it on paper first) and it seemed to be right. Found out if I changed the shader to draw a line loop, it would render. However it would not render a triangle. Can anyone explain why?
void setupRC()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
shaderManager.InitializeStockShaders();
M3DVector3f vVerts1[] = {-0.5f,0.0f,-0.5f,0.0f,0.5f,0.0f,0.5f,0.0f,-0.5f};
M3DVector3f vVerts2[] = {-0.5f,0.0f,-0.5f,0.0f,0.5f,0.0f,-0.5f,0.0f,0.5f};
M3DVector3f vVerts3[] = {-0.5f,0.0f,0.5f,0.0f,0.5f,0.0f,0.5f,0.0f,0.5f};
M3DVector3f vVerts4[] = {0.5f,0.0f,0.5f,0.0f,0.5f,0.0f,0.5f,0.0f,-0.5f};
triangleBatch1.Begin(GL_LINE_LOOP, 3);
triangleBatch1.CopyVertexData3f(vVerts1);
triangleBatch1.End();
triangleBatch2.Begin(GL_TRIANGLES, 3);
triangleBatch2.CopyVertexData3f(vVerts2);
triangleBatch2.End();
triangleBatch3.Begin(GL_TRIANGLES, 3);
triangleBatch3.CopyVertexData3f(vVerts3);
triangleBatch3.End();
triangleBatch4.Begin(GL_TRIANGLES, 3);
triangleBatch4.CopyVertexData3f(vVerts4);
triangleBatch4.End();
glEnable(GL_CULL_FACE);
}
float rot = 1;
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
GLfloat vRed[] = {1.0f, 0.0f, 0.0f, 0.5f};
GLfloat vBlue[] = {0.0f, 1.0f, 0.0f, 0.5f};
GLfloat vGreen[] = {0.0f, 0.0f, 1.0f, 0.5f};
GLfloat vWhite[] = {1.0f, 1.0f, 1.0f, 0.5f};
M3DMatrix44f transformMatrix;
if (rot >= 360)
rot = 0;
else
rot = rot + 1;
m3dRotationMatrix44(transformMatrix,m3dDegToRad(rot),0.0f,1.0f,0.0f);
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformMatrix, vRed);
triangleBatch1.Draw();
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformMatrix, vBlue);
triangleBatch2.Draw();
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformMatrix, vGreen);
triangleBatch3.Draw();
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformMatrix, vWhite);
triangleBatch4.Draw();
glutSwapBuffers();
glutPostRedisplay();
Sleep(10);
}
You've most likely defined the vertices in clockwise order for the triangle that isn't showing, and in counterclockwise order (normally the default) for those that are. Clockwise winding essentially creates an inward facing normal and thus OpenGL won't bother to render it when culling is enabled.
The easiest way to check this is to set glCullFace(GL_FRONT)--that should toggle it so you see the missing triangle and no longer see the other three.
The only thing I see that affects polygons here is glEnable(GL_CULL_FACE);.
You shouldn't have that, because if you plot your vertices backwards, the polygon won't render.
Remove it or actually call glDisable(GL_CULL_FACE); to be sure.
In your case, it's not likely that you want to draw a polygon that you can see from one side only.