Currently, I'm drawing a big room, and it's all good and pretty:
But, it's blue, so I figure, ok, I'll just disable lighting first, and then draw the room, re-enable it later, and it'll work out fine, right?
I suppose not... It loses its "depth" entirely.
Can I not simply do:
glDisable(GL_LIGHTING);
glColor3f(51/255.0, 25/255.0,0.0);
drawstuffhere
glEnable(GL_LIGHTING);
Or is this influenced by my initial lighting setup?
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST); // Enable depth testing.
// Turn on OpenGL lighting.
glEnable(GL_LIGHTING);
// Light property vectors.
float lightAmb[] = { 0.0, 0.0, 0.0, 1.0 };
float lightDifAndSpec0[] = { 1.0, 1.0, 1.0, 1.0 };
float lightDifAndSpec1[] = { 1.0, 1.0, 0.0, 1.0 };
float globAmb[] = { 0.2, 0.2, 0.2, 1.0 };
// Light0 properties.
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDifAndSpec0);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightDifAndSpec0);
// Light1 properties.
glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDifAndSpec1);
glLightfv(GL_LIGHT1, GL_SPECULAR, lightDifAndSpec1);
glEnable(GL_LIGHT0); // Enable particular light source.
glEnable(GL_LIGHT1); // Enable particular light source.
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globAmb); // Global ambient light.
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); // Enable local viewpoint
// Cull back faces.
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
EDIT: Source code: http://pastebin.com/DKGpWiFB
///////////////////////////////////////////////////////////////////////////////////////////
// main.cpp
//
///////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#ifdef __APPLE__
# include <GLUT/glut.h>
#else
# include <GL/glut.h>
#endif
using namespace std;
//Structures
struct perspectives {
float ex,ey,ez,cx,cy,cz;
int x, y, z;
};
struct coordinates {
float x, y, z;
};
// Globals.
static float a = .1; // Blue ambient reflectance.
static float d = 1.0; // Blue diffuse reflectance.
static float s = 1.0; // White specular reflectance.
static float h = 50.0; // Shininess.
static float e = 0.0; // Blue emittance.
static float t = 0.0; // Quadratic attenuation factor.
static float zMove = 0.0; // z-direction component.
static char theStringBuffer[10]; // String buffer.
static long font = (long)GLUT_BITMAP_8_BY_13; // Font selection.
static bool cameraRotate = false;
struct perspectives camera = {0,0,12,0,0,0,0,1,0};
struct coordinates key = {0,0,11};
// Routine to draw a bitmap character string.
void writeBitmapString(void *font, char *string)
{
char *c;
for (c = string; *c != '\0'; c++) glutBitmapCharacter(font, *c);
}
// Routine to convert floating point to char string.
void floatToString(char * destStr, int precision, float val)
{
sprintf(destStr,"%f",val);
destStr[precision] = '\0';
}
//Routine to draw a ball of light
void drawMoon()
{//TODO
// Light position vectors.
float lightPos[] = { 3, 4, -.2, 1.0 };
glDisable(GL_LIGHTING);
// Light0 and its sphere positioned.
glPushMatrix();
glLightfv(GL_LIGHT1, GL_POSITION, lightPos);
glTranslatef(lightPos[0], lightPos[1], lightPos[2]);
glColor3f(1.0, 1.0, 1.0);
glutSolidSphere(2, 20, 20);
glPopMatrix();
glEnable(GL_LIGHTING);
}
//Routine to draw starry sky
void drawStars()
{
//TODO
}
void drawPumpkin()
{
//TODO
}
void drawKey()
{
//TODO
}
//Routine to draw walls
void drawWalls()
{
//glDisable(GL_LIGHTING);
glColor3f(51/255.0,25/255.0,0);
glPushMatrix();
//glRotatef(0,0,0,1);
glScalef(1,1,3);
glBegin(GL_QUADS);
/* Floor */
glVertex3f(-1,-1,-1);
glVertex3f(-1,-1,1);
glVertex3f(1,-1,1);
glVertex3f(1,-1,-1);
/* Ceiling */
glVertex3f(-1,1,-1);
glVertex3f(1,1,-1);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
/* Walls */
/* front outer */
/* left half */
glVertex3f(-1,-1,1);
glVertex3f(-.45,-1,1);
glVertex3f(-.45,1,1);
glVertex3f(-1,1,1);
/* right half */
glVertex3f(.45,-1,1);
glVertex3f(1,-1,1);
glVertex3f(1,1,1);
glVertex3f(.45,1,1);
/* top half */
glVertex3f(-1,.5,1);
glVertex3f(1,.5,1);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
/* end front outer */
/* front door */
//TODO
/* end front door */
/* back inner */
/* left half */
glVertex3f(-1,-1,-1);
glVertex3f(-.45,-1,-1);
glVertex3f(-.45,1,-1);
glVertex3f(-1,1,-1);
/* right half */
glVertex3f(.45,-1,-1);
glVertex3f(1,-1,-1);
glVertex3f(1,1,-1);
glVertex3f(.45,1,-1);
/* top half */
glVertex3f(-1,.5,-1);
glVertex3f(1,.5,-1);
glVertex3f(1,1,-1);
glVertex3f(-1,1,-1);
/* end inner */
glVertex3f(1,1,1);
glVertex3f(1,1,-1);
glVertex3f(1,-1,-1);
glVertex3f(1,-1,1);
glVertex3f(-1,1,1);
glVertex3f(-1,-1,1);
glVertex3f(-1,-1,-1);
glVertex3f(-1,1,-1);
glEnd();
glPopMatrix();
//glEnable(GL_LIGHTING);
}
void drawLight()
{
// Light position vectors.
float lightPos0[] = { 0.0, .75, -.5, 1.0 };
glDisable(GL_LIGHTING);
// Light0 and its sphere positioned.
glPushMatrix();
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
glTranslatef(lightPos0[0], lightPos0[1], lightPos0[2]);
glColor3f(1.0, 1.0, 1.0);
glutWireSphere(0.05, 8, 8);
glPopMatrix();
glEnable(GL_LIGHTING);
}
// Initialization routine.
void setup(void)
{
//Set globals
a = 1- abs(camera.ez/15.0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST); // Enable depth testing.
// Turn on OpenGL lighting.
glEnable(GL_LIGHTING);
// Light property vectors.
float lightAmb[] = { 0.0, 0.0, 0.0, 1.0 };
float lightDifAndSpec0[] = { 1.0, 1.0, 1.0, 1.0 };
float lightDifAndSpec1[] = { 1.0, 1.0, 0.0, 1.0 };
float globAmb[] = { 0.2, 0.2, 0.2, 1.0 };
// Light0 properties.
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDifAndSpec0);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightDifAndSpec0);
// Light1 properties.
glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDifAndSpec1);
glLightfv(GL_LIGHT1, GL_SPECULAR, lightDifAndSpec1);
glEnable(GL_LIGHT0); // Enable particular light source.
glEnable(GL_LIGHT1); // Enable particular light source.
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globAmb); // Global ambient light.
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); // Enable local viewpoint
// Cull back faces.
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
// Drawing routine.
void drawScene()
{
// Material property vectors.
float matAmb[] = {0.0, 0.0, a, 1.0};
float matDif[] = {0.0, 0.0, d, 1.0};
float matSpec[] = { s, s, s, 1.0 };
float matShine[] = { h };
float matEmission[] = {0.0, 0.0, e, 1.0};
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// Light quadratic attenuation factor.
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, t);
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, t);
//gluLookAt(0.0, ey, ez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
gluLookAt(camera.ex,camera.ey, camera.ez,
camera.cx,camera.cy,camera.cz,
camera.x,camera.y,camera.z);
//gluLookAt(0,0,0,0,0,0,0,1,0);
// Draw light source spheres after disabling lighting.
drawLight();
// Material properties of sphere.
glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
glMaterialfv(GL_FRONT, GL_SHININESS, matShine);
glMaterialfv(GL_FRONT, GL_EMISSION, matEmission);
// Sphere.
glTranslatef(0.0, 0.0, zMove); // Move the sphere.
//glutSolidCube(1.5);
drawWalls();
drawMoon();
glutSwapBuffers();
}
// OpenGL window reshape routine.
void resize (int w, int h)
{
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (float)w/(float)h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
int mod = glutGetModifiers();
if (mod!=0)
{
switch(mod)
{
//Shift key
case 1 : cameraRotate=true; break;
//ALT key
case 4 : ; break;
mod = 0;
}
}
switch (key)
{
case 27:
exit(0);
break;
case 'a':
if (a > 0.0) a -= 0.05;
glutPostRedisplay();
break;
case 'A':
if (a < 1.0) a += 0.05;
glutPostRedisplay();
break;
case 'd':
if (d > 0.0) d -= 0.05;
glutPostRedisplay();
break;
case 'D':
if (d < 1.0) d += 0.05;
glutPostRedisplay();
break;
case 's':
if (s > 0.0) s -= 0.05;
glutPostRedisplay();
break;
case 'S':
if (s < 1.0) s += 0.05;
glutPostRedisplay();
break;
case 'e':
if (e > 0.0) e -= 0.05;
glutPostRedisplay();
break;
case 'E':
if (e < 1.0) e += 0.05;
glutPostRedisplay();
break;
case 'h':
if (h > 0.0) h -= 1.0;
glutPostRedisplay();
break;
case 'H':
if (h < 128.0) h += 1.0;
glutPostRedisplay();
break;
case 't':
if (t > 0.0) t -= 0.005;
glutPostRedisplay();
break;
case 'T':
t += 0.005;
glutPostRedisplay();
break;
default:
break;
}
}
// Callback routine for non-ASCII key entry.
void specialKeyInput(int key, int x, int y)
{
if (key == GLUT_KEY_UP){
if(camera.ez - .1 >= 0)
{camera.ez += -0.1;
camera.ex += 0;}
}
if (key == GLUT_KEY_DOWN){
camera.ez += 0.1;
camera.ex += 0;
}
if (key == GLUT_KEY_LEFT){
camera.cx -= .1;
}
if (key == GLUT_KEY_RIGHT){
camera.cx += .1;
}
printf("This is my ez %f\n", camera.ez);
a = 1- abs(camera.ez/5.0);
glutPostRedisplay();
}
// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
}
// Main routine.
int main(int argc, char **argv)
{
printInteraction();
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (600, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow ("scaryRoom.cpp");
setup();
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(keyInput);
glutSpecialFunc(specialKeyInput);
glutMainLoop();
return 0;
}
OpenGL is a state based drawing API. Once you've drawn something OpenGL doesn't remember it. Everything happens at the time of drawing, and if there's no lighting setup at the moment of drawing, that's it.
I have no idea why your room comes out blue; I'd have to see the full code for that. However I can give you the advice, that you should not try to "initialize" things at a certain time, and then "live" with that. OpenGL is a state machine, meant to have every attribute that matters being set right before you actually need it. So I suggest you move the lighting and color setup as close to the actual drawing as possible.
Update
You're setting material state in your drawScene function. Those will effect on everything drawn after setting those states until you change them. You intended them to affect only the sphere, but it will affect also the other stuff. Take note that glColor won't have an effect on illuminated drawing, unless you enable and set a so called color material state.
However I strongly suggest you don't bother with the arcane fixed function pipeline at all. You've run into a few pitfalls already :) I suggest you learn modern OpenGL, which also avoids all those weird peculiarities. A very good tutorial can be found at http://arcsynthesis.org/gltut
Related
I am currently trying to position a light starting from the bottom left of my screen and illuminating towards the center of my screen but my light source does not appear circular (light does not seem to be coming from a single point).
After moving the light source it shines on the entire object but the desired effect is for the lightsource to only shine (based on a point) towards the right.
void init()
{
camPos[0]= -(size/2)*.1;
camPos[1]= size*.1;
camPos[2]= -(size/2)*.1;
zoom = size/10;
glClearColor(0,0,0,0);
glColor3f(1, 1, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//Enable backface culling
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);
//Enable Lighting
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
light_pos[0] = 1;
light_pos[1] = 10;
light_pos[2] = 1;
light_pos[3] = 1;
gluPerspective(45, 1, 1, 100);
};
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Camera
radians = float(pi*(angle-90.0f)/180.0f);
//initialize look
look[0] = (size/2)*.1;
look[1] = 1;
look[2] = (size/2)*.1;
camPos[0] = look[0] + sin(radians)*zoom;
camPos[1] = size/10;
camPos[2] = look[2] + cos(radians)*zoom;
gluLookAt(camPos[0], camPos[1], camPos[2], look[0],look[1],look[2], 0,1,0);
//lighting
//glColor3f(1,1,1);
float m_amb[] = {0.2, 0.2, 0.2, 1.0};
float m_dif[] = {1, 1, 1, 1.0};
float m_spec[] = {1, 1, 1, 1.0};
float shiny = 27;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m_amb);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m_dif);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m_spec);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shiny);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
glShadeModel(GL_SMOOTH);
drawTerrain(terrainA, size);
glutSwapBuffers();
};
int main (int argc, char** argv)
{
srand(time(NULL));
//When program starts enter value
printf("Enter an int between 50 and 300: ");
scanf("%i",&size);
if ( size < 50 || size > 300){
printf("Invalid size! Please re-run \n");
return 0;
}
populateArray();
//Starts glut
glutInit(&argc, argv);
//Init display
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 800);
glutInitWindowPosition(600, 100);
glutCreateWindow("Terrain");glEnable(GL_DEPTH_TEST);
//Registering Callbacks
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glEnable(GL_DEPTH_TEST);
init();
glutMainLoop();
return 0;
};
The general practic is to define light attenuation factors as a coeficients of light equation.
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.5);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.5);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.2);
where kc is constant attenuation factor, kl - linear attenuation factor, kq - quadratic attenuation factor, d - distance to light source. You can modify this coeficients to achive the effect you want.
This example could not works correctly so I suggest to build your own light destribution function using shaders, it will be simple to achive desired effect and more effective (and will always work).
I have to make a program which is doing the collision between two spheres. I made this but when the spheres collide everything is blocked. I can't move the sphere anymore. I made only the sphere1 to move and the other to be static. The code is written in VB/ C++.
#include "GLOS.H"
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <glaux.h>
GLfloat max1=0,max2=0,v,v1;
FLOAT d,distanta=0;
int i,j;
void myinit(void);
void CALLBACK display(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
void CALLBACK MutaStanga(void);
void CALLBACK MutaDreapta(void);
int k=0,k1=0;
int dist_ramasa;
static float dx1=200,dy1=300,dz1=0;
int deplasare=100;
float rez;
static int flag=1;
float pxc,pyc,pzc,sum,suma_raze;
void myinit (void) { //iluminating
glClearColor(1.0, 1.0, 1.0, 1.0);
GLfloat mat_ambient[] = { 0.3, 0.3, 0.3, 1.0 };
GLfloat mat_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 100.0 };
GLfloat light_ambient[] = { 0.4, 0.4, 0.4, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 0.0, 0.0 };
GLfloat lmodel_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glEnable(GL_LIGHTING); // activare iluminare
glEnable(GL_LIGHT0); // activare sursa 0
glColorMaterial(GL_FRONT,GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
}
struct sfera //the spheres
{
GLfloat raza, xcentru, ycentru, zcentru; //the radius and the centers
GLfloat xd1,xd2,yd1,yd2,zd1,zd2;
}sf[2];
void initRaza(){ //radius init
sf[0].raza=100;
sf[1].raza=100;
}
int conditie(void){ //this is where I verify if collide
initRaza();
double xac1,yac1,zac1,xac2,yac2,zac2;//the new centers after the movement
xac1=sf[0].xcentru+dx1;
yac1=sf[0].ycentru+dy1;
zac1=sf[0].zcentru+dz1;
//static sphere
xac2=sf[1].xcentru+700;
yac2=sf[1].ycentru+300;
zac2=sf[1].zcentru;
pxc = pow((xac1-xac2),2);
pyc = pow((yac1-yac2),2);
pzc = pow((zac1-zac2),2);
sum=(pxc + pyc + pzc);
distanta=sqrt(sum); //the distance between the centers
//the sum of the radiuses
suma_raze=sf[0].raza+sf[1].raza;
dist_ramasa=distanta-sf[0].raza-sf[1].raza;
// we compare the distance and the sum of radiuses
//if the distance is lower than the sum -> collide
if(distanta>suma_raze)
return 1;
else
return 0;
}
void CALLBACK MutaStanga(void) //movement left
{
if(conditie()==1){
if(dist_ramasa<deplasare)
dx1=dx1-dist_ramasa;
else
dx1=dx1-deplasare;
}
}
void CALLBACK MutaDreapta(void) //movement right
{
if(conditie()==1){
if(dist_ramasa<deplasare)
dx1=dx1+dist_ramasa;
else
dx1=dx1+deplasare;
}
}
void CALLBACK MutaSus(void) //movement up
{
if(conditie()==1){
if(dist_ramasa<deplasare)
dy1=dy1+dist_ramasa;
else
dy1=dy1+deplasare;
}
}
void CALLBACK MutaJos(void) //movement down
{
if(conditie()==1){
if(dist_ramasa<deplasare)
dy1=dy1-dist_ramasa;
else
dy1=dy1-deplasare;
}
}
void drawBall1() //the first sphere
{
glPushMatrix();
glColor3f(0,1,0);
glTranslatef(dx1, dy1, 0.0);
glRotatef(30,1,0,0);
auxSolidSphere(sf[0].raza);
glPopMatrix();
}
void drawBall2() //the second sphere
{
glPushMatrix();
glColor3f(1,0,0);
glTranslatef(700,300,0);
glRotatef(30,1,0,0);
auxWireSphere(sf[1].raza);
glPopMatrix();
}
void CALLBACK display (void)
{
initRaza();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
drawBall1();
drawBall2();
auxSwapBuffers();
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
if (!h) return;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho (0, 800.0, 0*(GLfloat)h/(GLfloat)w,
-860.0*(GLfloat)h/(GLfloat)w, -200.0, 200.0);
else
glOrtho (0*(GLfloat)w/(GLfloat)h,
900.0*(GLfloat)w/(GLfloat)h, 0, 900.0, -500.0, 500.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB | AUX_DEPTH16);
auxInitPosition (0, 0, 900, 700);
auxInitWindow ("Bounding sphere collision");
myinit ();
auxKeyFunc (AUX_LEFT, MutaStanga);
auxKeyFunc (AUX_RIGHT, MutaDreapta);
auxKeyFunc (AUX_UP, MutaSus);
auxKeyFunc(AUX_DOWN,MutaJos);
auxReshapeFunc (myReshape);
auxMainLoop(display);
return(0);
}
I don't know what is not working. When they collide I want to reject each other . I hope you can help me.
Once the spheres collide, your function conditie will return 1. All your keypress functions check this before modifying the sphere's position, thus, once they collide, you can no longer move the sphere.
I'm trying to move a cube drawn wit OpenGL in a QGLWidget. Here is part of the code:
void Hologram::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawBox();
}
void Hologram::drawBox() {
for (int i = 0; i < 6; i++) {
glBegin(GL_QUADS);
glNormal3fv(&n[i][0]);
glVertex3fv(&v[faces[i][0]][0]);
glVertex3fv(&v[faces[i][1]][0]);
glVertex3fv(&v[faces[i][2]][0]);
glVertex3fv(&v[faces[i][3]][0]);
glEnd();
}
qDebug() << "drawing box";
}
void Hologram::initializeGL() {
/* Enable a single OpenGL light. */
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
/* Use depth buffering for hidden surface elimination. */
glEnable(GL_DEPTH_TEST);
/* Setup the view of the cube. */
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);
// qDebug() << "vx:" << vx << "vy:" << vy << "vz:" << vz;
gluLookAt(0.0, 0.0, 5.0, // eye position
0.0, 0.0, 0.0, // center
0.0, 1.0, 0.); // up vector
// Adjust cube position
glTranslatef(0.0, 0.0, -1.0);
}
void Hologram::animate() {
glTranslatef(0.0, 0.0, -0.1);
updateGL();
}
I've implemented a timer that periodically calls animate() via a signal&slot connection. Shouldn't it add -0.1 to the z-coordinate every time when animate() is executed and therefore move the cube in z-direction? Depending on the value I choose, the cube is either not moving (for values approx. <-0.3) or I cannot see it at all (values approx. >0.4). First I thought it either might move very fast and disappear or it moves very slow and therefore I couldn't see any changes. But playing around with z value always ended up in one of the above mentioned cases... Isn't that strange? What am I doing wrong?
Problem solved: The correct way to do it is
void Hologram::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0, 0.0, -dz);
drawBox();
}
The reason why I got the strange behaviour described above is due to the fact that the object was clipped by the near/far planes of the perspective set with gluPerspective()...
I am a beginner at using openGL.
I have used a program which I found over the internet to draw a cube on the screen and translate, scale and rotate it according to certain keyboard strokes.
Bellow, I have attached the code for doing this:
#define RADDEG 57.29577951f
float XUP[3] = {1,0,0}, XUN[3] = {-1, 0, 0},
YUP[3] = {0,1,0}, YUN[3] = { 0,-1, 0},
ZUP[3] = {0,0,1}, ZUN[3] = { 0, 0,-1},
ORG[3] = {0,0,0};
GLfloat viewangle = 0, tippangle = 0, traj[120][3];
GLfloat d[3] = {0.1, 0.1, 0.1};
GLfloat xAngle = 0.0, yAngle = 0.0, zAngle = 0.0;
GLfloat scaleF = 0.2;
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
// Use arrow keys to rotate entire scene !!!
void Special_Keys (int key, int x, int y)
{
switch (key) {
case GLUT_KEY_LEFT : viewangle -= 5; break;
case GLUT_KEY_RIGHT: viewangle += 5; break;
case GLUT_KEY_UP : tippangle -= 5; break;
case GLUT_KEY_DOWN : tippangle += 5; break;
default: printf (" Special key %c == %d\n", key, key);
}
glutPostRedisplay();
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
void Keyboard (unsigned char key, int x, int y)
{
switch (key) {
case 'j' : d[0] += 0.1; break;
case 'k' : d[0] -= 0.1; break;
case 'n' : d[1] += 0.1; break;
case 'm' : d[1] -= 0.1; break;
//case 'l' : d[2] += 0.1; break;
case 'z' : xAngle += 5; break;
case 'x' : yAngle += 5; break;
case 'c' : zAngle += 5; break;
case 'q' : scaleF += 0.1; break;
case 'w' : scaleF -= 0.1; break;
default: cout<< "Redo a valid keystroke;"<<endl;
}
glutPostRedisplay();
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
void Triad (void)
{
glColor3f (1.0, 1.0, 1.0);
glBegin (GL_LINES);
glVertex3fv (ORG); glVertex3fv (XUP);
glVertex3fv (ORG); glVertex3fv (YUP);
glVertex3fv (ORG); glVertex3fv (ZUP);
glEnd ();
glRasterPos3f (1.1, 0.0, 0.0);
glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, 'X');
glRasterPos3f (0.0, 1.1, 0.0);
glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, 'Y');
glRasterPos3f (0.0, 0.0, 1.1);
glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, 'Z');
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
void Draw_Box (void)
{
glBegin (GL_QUADS);
glColor3f(1,0,0);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
glVertex3f(-1,-1,1);
glVertex3f(1,-1,1);
glColor3f(0,1,1);
glVertex3f(1,1,-1);
glVertex3f(-1,1,-1);
glVertex3f(-1,-1,-1);
glVertex3f(1,-1,-1);
glColor3f(0,1,0);
glVertex3f(1,1,1);
glVertex3f(1,-1,1);
glVertex3f(1,-1,-1);
glVertex3f(1,1,-1);
glColor3f(1,0,1);
glVertex3f(-1,1,1);
glVertex3f(-1,-1,1);
glVertex3f(-1,-1,-1);
glVertex3f(-1,1,-1);
glColor3f(0,0,1);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
glVertex3f(-1,1,-1);
glVertex3f(1,1,-1);
glColor3f(1,1,0);
glVertex3f(1,-1,1);
glVertex3f(-1,-1,1);
glVertex3f(-1,-1,-1);
glVertex3f(1,-1,-1);
glEnd();
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
void redraw (void)
{
int v;
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);
Triad ();
glPushMatrix ();
glTranslatef (d[0], d[1], d[2]); // Move box down X axis.
glScalef (scaleF, scaleF, scaleF);
glRotatef (zAngle, 0,0,1);
glRotatef (yAngle, 0,1,0);
glRotatef (xAngle, 1,0,0);
Draw_Box ();
glPopMatrix ();
glutSwapBuffers();
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
void wait ( int seconds )
{
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC ;
while (clock() < endwait) {}
}
int main (int argc, char **argv)
{
glutInit (&argc, argv);
glutInitWindowSize (900, 600);
glutInitWindowPosition (300, 300);
glutInitDisplayMode (GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow ("Orbital Font Demo");
glutDisplayFunc ( redraw );
glutKeyboardFunc ( Keyboard );
//glutSpecialFunc (Special_Keys);
glClearColor (0.1, 0.0, 0.1, 1.0);
glMatrixMode (GL_PROJECTION);
gluPerspective (60, 1.5, 1, 10);
glMatrixMode (GL_MODELVIEW);
glutPostRedisplay();
glutMainLoop ();
return 1;
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
The thing is that I want to copy this code into another C++ program where I am using openCV libraries to connect my VGA camera. Based on the movements performed in front of the camera, I am classifying the performed movements using a SVM model.
I want to use the output of the SVM model which is basically a integer value and pass it to the openGL code in order to move the cube in the window.
In the above mentioned code, this procedure is performed by using keystrokes, and implicitly the glKeyboardFunc function. What functions should I use in order to connect the output of the SVM model to the redraw function of the above mentioned code?
You should use glutIdle to check whether there is a new frame. If there is you should update textures with new image using glTexSubImage2D*.
*You should use a texture to display a custom image.
I was trying to make a small wave generator in OpenGL with C++, using an evaluator.
However, I haven't had much luck since my evaluator only gets partially lit.
Why does this happen?
Below I include full source code for completeness' sake, you'll probably only have to look at init(), display() and the constants at the top of the file.
#include <gl/glui.h>
#include <math.h>
const int DIMX = 500;
const int DIMY = 500;
const int INITIALPOS_X = 200;
const int INITIALPOS_Y = 200;
// Aspect ratio (calculated on the fly)
float xy_aspect;
// UI aux. matrices
float view_rotate[16] = { 1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1 };
float obj_pos[] = { 0.0, 0.0, 0.0 };
float obj_pan[] = { 0.0, 0.0, 0.0 };
// Referential axis
double axis_radius_begin = 0.2;
double axis_radius_end = 0.0;
double axis_lenght = 16.0;
int axis_nslices = 8;
int axis_nstacks = 1;
// Light 0 properties
float light0_position[] = {5.0, 5.0, 5.0, 0.0};
float light0_ambient[] = {0.0, 0.0, 0.0, 1.0};
float light0_diffuse[] = {0.6, 0.6, 0.6, 1.0};
float light0_specular[] = {1.0, 1.0, 1.0, 1.0};
float light0_kc = 0.0;
float light0_kl = 1.0;
float light0_kq = 0.0;
double light0x = 5.0;
double light0y = 5.0;
double light0z = 5.0;
double symb_light0_radius = 0.2;
int symb_light0_slices = 8;
int symb_light0_stacks =8;
// Ambient light source properties
float light_ambient[] = {0.5, 0.5, 0.5, 1.0}; /* Set the background ambient lighting. */
// Windowing related variables
int main_window;
GLUquadric* glQ;
GLUI *glui;
const unsigned int gridSize = 40;
float grid[gridSize][gridSize][3];
const int uSize = gridSize;
const int vSize = gridSize;
GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
GLfloat position[] = {0.0, 0.0, 2.0, 1.0};
GLfloat mat_diffuse[] = {0.6, 0.6, 0.6, 1.0};
GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
float mat_shininess[] = {50.0};
void display(void) {
static float value = 0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glFrustum( -xy_aspect*.04, xy_aspect*.04, -.04, .04, .1, 50.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( obj_pos[0], obj_pos[1], -obj_pos[2]-25 );
glTranslatef( obj_pan[0], obj_pan[1], obj_pan[2] );
glRotated( 20.0, 1.0,0.0,0.0 );
glRotated(-45.0, 0.0,1.0,0.0 );
glMultMatrixf( view_rotate );
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glColor3f(1.0,0.0,0.0);
glPushMatrix();
glRotated(90.0, 0.0,1.0,0.0 );
gluCylinder(glQ, axis_radius_begin, axis_radius_end,
axis_lenght, axis_nslices, axis_nstacks);
glPopMatrix();
glColor3f(0.0,1.0,0.0);
glPushMatrix();
glRotated(-90.0, 1.0,0.0,0.0 );
gluCylinder(glQ, axis_radius_begin, axis_radius_end,
axis_lenght, axis_nslices, axis_nstacks);
glPopMatrix();
glColor3f(0.0,0.0,1.0);
glPushMatrix();
gluCylinder(glQ, axis_radius_begin, axis_radius_end,
axis_lenght, axis_nslices, axis_nstacks);
glPopMatrix();
light0_position[0] = light0x;
light0_position[1] = light0y;
light0_position[2] = light0z;
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
glColor3f(1.0,1.0,0.0);
gluQuadricOrientation( glQ, GLU_INSIDE);
glPushMatrix();
glTranslated(light0x,light0y,light0z);
gluSphere(glQ, symb_light0_radius, symb_light0_slices, symb_light0_stacks);
glPopMatrix();
gluQuadricOrientation( glQ, GLU_OUTSIDE);
gluQuadricDrawStyle(glQ, GLU_FILL);
gluQuadricNormals(glQ, GLU_SMOOTH);
gluQuadricOrientation(glQ, GLU_OUTSIDE);
gluQuadricTexture(glQ, GL_FALSE);
for (unsigned int y = 0; y < vSize; ++y) {
for (unsigned int x = 0; x < uSize; ++x) {
float xVal = 5*3.14/gridSize*x;
float yVal = 5*3.14/gridSize*y;
grid[y][x][0] = (float) x/gridSize*10.0;
grid[y][x][1] = sin(xVal + value) + sin(yVal + value);
grid[y][x][2] = (float) y/gridSize*10.0;
}
}
glMap2f(GL_MAP2_VERTEX_3, 0, 1 , 3, uSize, 0, 1, uSize * 3, vSize, &grid[0][0][0]);
glEvalMesh2(GL_FILL, 0, gridSize, 0, gridSize);
value += 3.14/25;
if (value > 3.14*2)
value = 0;
// swapping the buffers causes the rendering above to be shown
glutSwapBuffers();
glFlush();
}
/* Mouse handling */
void processMouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
}
glutPostRedisplay();
}
void processMouseMoved(int x, int y)
{
// pedido de refrescamento da janela
glutPostRedisplay();
}
void processPassiveMouseMoved(int x, int y)
{
// pedido de refrescamento da janela
glutPostRedisplay();
}
void reshape(int w, int h)
{
int tx, ty, tw, th;
GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th );
glViewport( tx, ty, tw, th );
xy_aspect = (float)tw / (float)th;
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27: // tecla de escape termina o programa
exit(0);
break;
}
}
void glut_idle( void )
{
if ( glutGetWindow() != main_window )
glutSetWindow(main_window);
glutPostRedisplay();
}
void init()
{
glQ = gluNewQuadric();
glFrontFace(GL_CCW); // Front faces defined using a counterclockwise rotation
glDepthFunc(GL_LEQUAL); // Por defeito e GL_LESS
glEnable(GL_DEPTH_TEST); // Use a depth (z) buffer to draw only visible objects
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
// Face Culling para aumentar a velocidade
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); // GL_FRONT, GL_BACK, GL_FRONT_AND_BACK
// Define que modelo de iluminacao utilizar; consultar o manual de referencia
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_ambient); // define luz ambiente
glLightModelf (GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
// por defeito a cor de fundo e o preto
// glClearColor(1.0,1.0,1.0,1.0); // cor de fundo a branco
// declaracoes para a fonte luz GL_LIGHT0
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, light0_kc);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, light0_kl);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, light0_kq);
// NOTA: a direccao e a posicao de GL_LIGHT0 estao na rotina display(), pelo
// que as isntrucoes seguntes nao sao necessarias
//glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 90.0);
//glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
//glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_MAP2_VERTEX_3);
glMapGrid2f(gridSize, 0.0, 1.0, gridSize, 0.0, 1.0);
glShadeModel(GL_SMOOTH);
glPolygonMode(GL_FRONT, GL_FILL);
//glPolygonMode(GL_FRONT, GL_LINE);
}
void do_nothing(int key, int x, int y) {}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize (DIMX, DIMY);
glutInitWindowPosition (INITIALPOS_X, INITIALPOS_Y);
main_window = glutCreateWindow (argv[0]);
glutDisplayFunc(display);
GLUI_Master.set_glutReshapeFunc(reshape);
GLUI_Master.set_glutKeyboardFunc (keyboard);
GLUI_Master.set_glutMouseFunc(processMouse);
glutMotionFunc(processMouseMoved);
glutPassiveMotionFunc(processPassiveMouseMoved);
GLUI_Master.set_glutSpecialFunc( do_nothing );
/*** Create the bottom subwindow ***/
glui = GLUI_Master.create_glui_subwindow( main_window, GLUI_SUBWINDOW_BOTTOM );
glui->set_main_gfx_window( main_window );
GLUI_Rotation *view_rot = glui->add_rotation( "Rotation", view_rotate );
view_rot->set_spin( 1.0 );
glui->add_column( false );
GLUI_Translation *trans_z = glui->add_translation( "Zoom", GLUI_TRANSLATION_Z, &obj_pos[2] );
trans_z->set_speed( .1 );
glui->add_column(false);
GLUI_Translation *trans_pan = glui->add_translation("Pan", GLUI_TRANSLATION_XY, &obj_pan[0]);
trans_pan->set_speed(.1);
GLUI_Master.set_glutIdleFunc( glut_idle );
init();
glutMainLoop();
return 0;
}
You say OpenGL evaluators don't need normals to set. This is only partly true. You only don't need to set normals if you enable automatically generated normals for evaluators by calling:
glEnable(GL_AUTO_NORMAL);
Just enabling GL_NORMALIZE won't do it.
But you can of course also specify your own normals by providing control points for GL_MAP2_NORMAL in the same way like for GL_MAP2_VERTEX_3.
And the answer won't be complete without mentioning that OpenGL evaluators are highly deprecated and most probably implemented in softare by the driver. So just rolling your own Bezier evaluation code (which is not very hard) and generating a simple mesh grid drawn as GL_TRIANGLES will surely be a better idea.