Adding Shadow in OpenGL [closed] - c++

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have a very simple code, that just draws a building, I want to add the shadow of the building. I have tried many code samples, but either they are too complicated with a lit of objects drawn. or just too vague. How can I get the shadow of my building?
#include "GLee/GLee.h" //GL header file, including extensions
#include "glut.h"
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include "tga.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
char g_SelectedColor = 'w';
int g_Width;
int g_Height;
int a=0.0 ,b=0.0, c=500, d=0.0, e=0.0, f=0.0,g=0.0,h=1.0,i=0.0;
static int rotationAngle=0;
void init();
void myMouseFunction( int button, int state, int mouseX, int mouseY );
void myKeyboardFunction( unsigned char key, int mouseX, int mouseY );
void Reshape( int width, int height );
void timer( int val );
void display();
void drawBuilding();
void menu(int);
// Assign a default value
float light_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
float light_ambient[] = { 0.1, 1.1, 0.0, 0.0 };
float light_specular[] = { 0.5, 0.5, 0.9, 1.0 };
float light_position[] = { 0.0, 10.0, 0.0, 1.0 };
void selectMessage( int val )
{
if(val==2)
{
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,0.0);
glVertex3f(0.0,200.0,0.0);
glVertex3f(200.0,200.0,0.0);
glVertex3f(200.0,0.0,0.0);
glVertex3f(0.0,0.0,0.0);
glEnd();
}
}
int main(int argc, char** argv)
{
glutCreateMenu(menu);
glutAddMenuEntry("View1", 1);
glutAddMenuEntry("View2", 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
g_Width =1200; g_Height = 600;
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
// glutInitWindowSize( g_Width, g_Height );
//glutFullScreen();
glutInitWindowPosition( 50, 50 );
glutCreateWindow( "CHECK" );
init();
glutMouseFunc( myMouseFunction );
glutKeyboardFunc( myKeyboardFunction );
glutReshapeFunc( Reshape );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}
void init(void)
{
glutAttachMenu(GLUT_RIGHT_BUTTON);
glClearColor( 1.0, 1.0, 1.0, 1.0 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 50.0, 1.0, 200, 1000 );
//glOrtho( -5.0, +5.0, -5.0, +5.0, +5.0, -5.0 );
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient );
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular );
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glShadeModel(GL_SMOOTH);
//glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
//glCullFace(GL_FRONT_AND_BACK );
glDisable(GL_CULL_FACE );
glMatrixMode( GL_MODELVIEW );
if ( loadTGA ("im1.tga", 10 ) == false )
printf ("\nError: File myQuakeTexture.tga not found!");
if ( loadTGA ("im2.tga", 11 ) == false )
printf ("\nError: File myQuakeTexture.tga not found!");
}
void myMouseFunction( int button, int state, int mouseX, int mouseY )
{
}
void myKeyboardFunction( unsigned char key, int mouseX, int mouseY )
{
switch( key )
{
case 'r':
{
glClearColor( 0.0, 0.0, 1.0, 1.0 );
glRotatef( rotationAngle++, 0.0, 1.0, 0.0 );
// drawBuilding();
//display();
}
case 'R':
case 'g':
case 'G':
case 'b':
case 'B':
case 'w':
case 'W':
g_SelectedColor = key;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
break;
case 27: // Esc key
exit(0);
break; // redundant
default:
break;
}
}
void Reshape( int width, int height )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
g_Width = width;
g_Height = height;
glViewport (0, 0, g_Width, g_Height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective( 50.0, 1.0, 200, 1000 );
//glOrtho( -5.0, +5.0, -5.0, +5.0, +5.0, -5.0 );;
}
void timer( int val )
{
display();
}
static float firstAngle=0;
void drawBuilding()
{
float DoorMaterial[4] = { 0.5, 0.2, 1.3, 1.0 };
//
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D ,10);
glTranslatef(30,-180,0);
//Building 1
//Front
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,0.0);
glTexCoord2d(1,1);
glVertex3f(0.0,400.0,0.0);
glTexCoord2d(0,1);
glVertex3f(70.0,400.0,0.0);
glTexCoord2d(0,0);
glVertex3f(70.0,0.0,0.0);
glTexCoord2d(1,0);
glVertex3f(0.0,0.0,0.0);
glEnd();
//Back
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,-50.0);
glTexCoord2d(1,1);
glVertex3f(0.0,400.0,-50.0);
glTexCoord2d(0,1);
glVertex3f(70.0,400.0,-50.0);
glTexCoord2d(0,0);
glVertex3f(70.0,0.0,-50.0);
glTexCoord2d(1,0);
glVertex3f(0.0,0.0,-50.0);
glEnd();
//Left
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,0.0);
glTexCoord2d(1,1);
glVertex3f(0.0,400.0,0.0);
glTexCoord2d(0,1);
glVertex3f(0.0,400.0,-50.0);
glTexCoord2d(0,0);
glVertex3f(0.0,0.0,-50.0);
glTexCoord2d(1,0);
glVertex3f(0.0,0.0,0.0);
glEnd();
//Right
glBegin(GL_POLYGON);
glVertex3f(70.0,0.0,0.0);
glTexCoord2d(1,1);
glVertex3f(70.0,400.0,0.0);
glTexCoord2d(0,1);
glVertex3f(70.0,400.0,-50.0);
glTexCoord2d(0,0);
glVertex3f(70.0,0.0,-50.0);
glTexCoord2d(1,0);
glVertex3f(70.0,0.0,0.0);
glEnd();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D ,11);
}
void menu(int item)
{
switch (item)
{
case 1:
{
a=-500, b=0, c=300,d=0,e=0,f=0,g=0,h=1,i=0;
}
break;
case 2:
{
a=0, b=300, c=500,d=0,e=0,f=0,g=0,h=1,i=0;
drawBuilding();
}
}
}
void display()
{
glRotatef( rotationAngle++, 0.0, 1.0, 0.0 );
glutFullScreen();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( a, b, c,
d, e, f,
g, h, i );
glRotatef( rotationAngle++, 0.0, 1.0, 0.0 );
//
drawBuilding();
glDisable(GL_TEXTURE_2D);
// this tells glut to call the 'timer' function in 33 milliseconds
// i.e. this way we will draw 1000/33 = 30 times a second
glutTimerFunc( 33, timer, 0 );
glutSwapBuffers();
printf(".");
}

Having shadows in a OpenGL rendered scene is not a matter of simply enabling some feature. OpenGL by itself just draws points, lines and triangles. One at a time and without any context between them. It's up to the user to provide the context.
Drawing shadows can be implemented in several ways, but the most used are
Stencil Volume Shadows
and
Shadow Mapping
Explaining them here would largely surpass the limits of a StackOverflow question. I hence refer you to the Wikipedia articles on them (and the resources linked by those)
http://en.wikipedia.org/wiki/Shadow_volume
http://en.wikipedia.org/wiki/Shadow_mapping

Related

Unable to display a vertex in the world

I am not able to plot the vertex glVertex2f( 10.0, 0.0 ) in the window, but when I use points like 0.8 it shows up.
Height = 640
Width = 480
So, I might be able to plot points in this range I guess. Can anyone point out the mistake and correct it?
Code:
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <cstdlib>
//defining constants
#define MAX_WIDTH 640
#define MAX_HEIGHT 480
//display callback function
void display(){
glClear( GL_COLOR_BUFFER_BIT );
glPointSize( 5 );
glLoadIdentity();
gluLookAt( 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0.0, 1.0, 0.0 );
glBegin( GL_POINTS );
//setting the pointer color
glColor3f( 1.0, 1.0, 1.0 );
glVertex2f( 0.0, 0.0 );
glVertex2f( 10.0, 0.0 );
glEnd();
glFlush();
}
//catching keyboard events
void keyboardEvent( unsigned char c, int x, int y ){
if( c == 27 ){
exit(0);
}
}
//catching mouse click events
void mouseEvent( int button, int state, int x, int y ){
//checking if the mouse button is clicked or not using state para.
if( state == GLUT_DOWN ){
if( button == GLUT_LEFT_BUTTON ){
}
else if( button == GLUT_RIGHT_BUTTON ){
}
}
}
//adjusting window when it is moved or resized
void reshape( int w, int h ){
glViewport( 0, 0, w, h );
}
//initialising the window at startup
void initialise(){
glClearColor( 0.0, 0.0, 0.0, 1.0 );
gluOrtho2D( 0, MAX_WIDTH, 0, MAX_HEIGHT );
}
int main( int argc, char **argv ){
//initialising the glut library
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize( MAX_WIDTH, MAX_HEIGHT );
glutInitWindowPosition( 100, 100 );
glutCreateWindow("DDA Assignment");
//calling normal functions
initialise();
//registering callback functions
glutDisplayFunc( display );
glutKeyboardFunc( keyboardEvent );
glutMouseFunc( mouseEvent );
glutReshapeFunc( reshape );
glutMainLoop();
return 0;
}
The glLoadIdentity() in display() is wiping out the matrix set by gluOrtho2D() in initialise().

Two spheres collision

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.

glEvalCoord when used with glFeedback is not giving output as expected

I am trying to read the value from glEvalCoord, but not getting the exact values which I should get. My code is
GLfloat ctrlpoints[4][3] = {
{ -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0},
{ 2.0, -4.0, 0.0}, { 4.0, 4.0, 0.0}};
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_LIGHTING);
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLint size;
GLfloat feedBuffer[1024];
glFeedbackBuffer (1024, GL_3D, feedBuffer);
glRenderMode (GL_FEEDBACK);
glBegin (GL_POINTS);
for (int i=0; i<=30; ++i)
{
GLfloat t = GLfloat(i)/30;
glEvalCoord1f(t);
}
glEnd();
size = glRenderMode (GL_RENDER);
cerr<<size<<endl;
}
Now, I am not sure but shouldn't it give me 30*3 values for each of the x, y and z coordinates of the curve?? But I am getting only 7*3 values. And the output of size is 28.
I think your size is 28 because your projection/modelview pair is clipping out some points.
"In feedback mode, each primitive that would be rasterized ... generates a block of values that's copied into the feedback array."
Try this:
#include <GL/glut.h>
#include <iostream>
using namespace std;
void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
double ar = w / h;
glOrtho( -5 * ar, 5 * ar, -5, 5, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
GLfloat ctrlpoints[4][3] =
{
{ -4.0, -4.0, 0.0 }, { -2.0, 4.0, 0.0 },
{ 2.0, -4.0, 0.0 }, { 4.0, 4.0, 0.0 }
};
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
GLfloat feedBuffer[1024];
glFeedbackBuffer (1024, GL_3D, feedBuffer);
glRenderMode (GL_FEEDBACK);
glPointSize( 5 );
glColor3ub( 255, 255, 255 );
glBegin (GL_POINTS);
for (int i=0; i<=30; ++i)
{
GLfloat t = GLfloat(i)/30;
glEvalCoord1f(t);
}
glEnd();
GLint size = glRenderMode (GL_RENDER);
cerr << size << endl;
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}
I added a slightly larger projection matrix.
With that I get a size of 124:
31 points * 3 floats per point = 93
31 points * 1 GL_POINT_TOKEN per point = 31
31 + 91 = 124

OpenGl display animation and draw text

I want to display the solar system and draw a simple text saying " Hello world " :
This code below display the solar system and everything works:
#include <iostream>
#include <OpenGL/gl.h>
#include <GLUT/glut.h>
void OpenGLInit(void);
static void Animate(void );
static void Key_r(void );
static void Key_s(void );
static void Key_up(void );
static void Key_down(void );
static void ResizeWindow(int w, int h);
static void KeyPressFunc( unsigned char Key, int x, int y );
static void SpecialKeyFunc( int Key, int x, int y );
static GLenum spinMode = GL_TRUE;
static GLenum singleStep = GL_FALSE;
// These three variables control the animation's state and speed.
static float HourOfDay = 0.0;
static float DayOfYear = 0.0;
static float AnimateIncrement = 24.0; // Time step for animation (hours)
// glutKeyboardFunc is called below to set this function to handle
// all normal key presses.
static void KeyPressFunc( unsigned char Key, int x, int y )
{
switch ( Key ) {
case 'R':
case 'r':
Key_r();
break;
case 's':
case 'S':
Key_s();
break;
case 27: // Escape key
exit(1);
}
}
// glutSpecialFunc is called below to set this function to handle
// all special key presses. See glut.h for the names of
// special keys.
static void SpecialKeyFunc( int Key, int x, int y )
{
switch ( Key ) {
case GLUT_KEY_UP:
Key_up();
break;
case GLUT_KEY_DOWN:
Key_down();
break;
}
}
static void Key_r(void)
{
if ( singleStep ) { // If ending single step mode
singleStep = GL_FALSE;
spinMode = GL_TRUE; // Restart animation
}
else {
spinMode = !spinMode; // Toggle animation on and off.
}
}
static void Key_s(void)
{
singleStep = GL_TRUE;
spinMode = GL_TRUE;
}
static void Key_up(void)
{
AnimateIncrement *= 2.0; // Double the animation time step
}
static void Key_down(void)
{
AnimateIncrement /= 2.0; // Halve the animation time step
}
/*
* Animate() handles the animation and the redrawing of the
* graphics window contents.
*/
static void Animate(void)
{
// Clear the redering window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (spinMode) {
// Update the animation state
HourOfDay += AnimateIncrement;
DayOfYear += AnimateIncrement/24.0;
HourOfDay = HourOfDay - ((int)(HourOfDay/24))*24;
DayOfYear = DayOfYear - ((int)(DayOfYear/365))*365;
}
// Clear the current matrix (Modelview)
glLoadIdentity();
// Back off eight units to be able to view from the origin.
glTranslatef ( 0.0, 0.0, -8.0 );
// Rotate the plane of the elliptic
// (rotate the model's plane about the x axis by fifteen degrees)
glRotatef( 15.0, 1.0, 0.0, 0.0 );
// Draw the sun -- as a yellow, wireframe sphere
glColor3f( 1.0, 1.0, 0.0 );
glutWireSphere( 1.0, 15, 15 );
// Draw the Earth
// First position it around the sun
// Use DayOfYear to determine its position
glRotatef( 360.0*DayOfYear/365.0, 0.0, 1.0, 0.0 );
glTranslatef( 4.0, 0.0, 0.0 );
glPushMatrix(); // Save matrix state
// Second, rotate the earth on its axis.
// Use HourOfDay to determine its rotation.
glRotatef( 360.0*HourOfDay/24.0, 0.0, 1.0, 0.0 );
// Third, draw the earth as a wireframe sphere.
glColor3f( 0.2, 0.2, 1.0 );
glutWireSphere( 0.4, 10, 10);
glPopMatrix(); // Restore matrix state
// Draw the moon.
// Use DayOfYear to control its rotation around the earth
glRotatef( 360.0*12.0*DayOfYear/365.0, 0.0, 1.0, 0.0 );
glTranslatef( 0.7, 0.0, 0.0 );
glColor3f( 0.3, 0.7, 0.3 );
glutWireSphere( 0.1, 5, 5 );
// Flush the pipeline, and swap the buffers
glFlush();
glutSwapBuffers();
if ( singleStep ) {
spinMode = GL_FALSE;
}
glutPostRedisplay(); // Request a re-draw for animation purposes
}
// Initialize OpenGL's rendering modes
void OpenGLInit(void)
{
glShadeModel( GL_FLAT );
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glClearDepth( 1.0 );
glEnable( GL_DEPTH_TEST );
}
// ResizeWindow is called when the window is resized
static void ResizeWindow(int w, int h)
{
float aspectRatio;
h = (h == 0) ? 1 : h;
w = (w == 0) ? 1 : w;
glViewport( 0, 0, w, h ); // View port uses whole window
aspectRatio = (float)w/(float)h;
// Set up the projection view matrix (not very well!)
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0, aspectRatio, 1.0, 30.0 );
// Select the Modelview matrix
glMatrixMode( GL_MODELVIEW );
}
// Main routine
// Set up OpenGL, hook up callbacks, and start the main loop
int main( int argc, char** argv )
{
// Need to double buffer for animation
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
// Create and position the graphics window
glutInitWindowPosition( 0, 0 );
glutInitWindowSize( 600, 360 );
glutCreateWindow( "Solar System Demo" );
// Initialize OpenGL.
OpenGLInit();
// Set up callback functions for key presses
glutKeyboardFunc( KeyPressFunc );
glutSpecialFunc( SpecialKeyFunc );
// Set up the callback function for resizing windows
glutReshapeFunc( ResizeWindow );
// Callback for graphics image redrawing
glutDisplayFunc( Animate );
// Start the main loop. glutMainLoop never returns.
glutMainLoop( );
return(0); // Compiler requires this to be here. (Never reached)
}
The code below draw text " Hello world " and works too:
#include <iostream>
#include <OpenGL/gl.h>
#include <GLUT/glut.h>
void drawBitmapText(char *string,float x,float y,float z)
{
char *c;
glRasterPos3f(x, y,z);
for (c=string; *c != '\0'; c++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, *c);
}
}
void drawStrokeText(char*string,int x,int y,int z)
{
char *c;
glPushMatrix();
glTranslatef(x, y+8,z);
// glScalef(0.09f,-0.08f,z);
for (c=string; *c != '\0'; c++)
{
glutStrokeCharacter(GLUT_STROKE_ROMAN , *c);
}
glPopMatrix();
}
void reshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,w,h,0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void render(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glColor3f(0,1,0);
drawBitmapText("Hello world",200,200,0);
glutSwapBuffers();
}
// Main routine
// Set up OpenGL, hook up callbacks, and start the main loop
int main( int argc, char** argv )
{
// Need to double buffer for animation
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
// Create and position the graphics window
glutInitWindowPosition( 0, 0 );
glutInitWindowSize( 600, 360 );
glutCreateWindow( "Solar System Demo" );
glutDisplayFunc(render);
glutIdleFunc(render);
glutReshapeFunc(reshape);
// Start the main loop. glutMainLoop never returns.
glutMainLoop( );
return(0); // Compiler requires this to be here. (Never reached)
}
i'm trying to use both of them together to display the solar system and draw the text, but
i'm getting a blank, black screen:
#include <iostream>
#include <OpenGL/gl.h>
#include <GLUT/glut.h>
void OpenGLInit(void);
static void Animate(void );
static void Key_r(void );
static void Key_s(void );
static void Key_up(void );
static void Key_down(void );
static void ResizeWindow(int w, int h);
static void KeyPressFunc( unsigned char Key, int x, int y );
static void SpecialKeyFunc( int Key, int x, int y );
static GLenum spinMode = GL_TRUE;
static GLenum singleStep = GL_FALSE;
// These three variables control the animation's state and speed.
static float HourOfDay = 0.0;
static float DayOfYear = 0.0;
static float AnimateIncrement = 24.0; // Time step for animation (hours)
// glutKeyboardFunc is called below to set this function to handle
// all normal key presses.
static void KeyPressFunc( unsigned char Key, int x, int y )
{
switch ( Key ) {
case 'R':
case 'r':
Key_r();
break;
case 's':
case 'S':
Key_s();
break;
case 27: // Escape key
exit(1);
}
}
// glutSpecialFunc is called below to set this function to handle
// all special key presses. See glut.h for the names of
// special keys.
static void SpecialKeyFunc( int Key, int x, int y )
{
switch ( Key ) {
case GLUT_KEY_UP:
Key_up();
break;
case GLUT_KEY_DOWN:
Key_down();
break;
}
}
static void Key_r(void)
{
if ( singleStep ) { // If ending single step mode
singleStep = GL_FALSE;
spinMode = GL_TRUE; // Restart animation
}
else {
spinMode = !spinMode; // Toggle animation on and off.
}
}
static void Key_s(void)
{
singleStep = GL_TRUE;
spinMode = GL_TRUE;
}
static void Key_up(void)
{
AnimateIncrement *= 2.0; // Double the animation time step
}
static void Key_down(void)
{
AnimateIncrement /= 2.0; // Halve the animation time step
}
/*
* Animate() handles the animation and the redrawing of the
* graphics window contents.
*/
static void Animate(void)
{
// Clear the redering window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (spinMode) {
// Update the animation state
HourOfDay += AnimateIncrement;
DayOfYear += AnimateIncrement/24.0;
HourOfDay = HourOfDay - ((int)(HourOfDay/24))*24;
DayOfYear = DayOfYear - ((int)(DayOfYear/365))*365;
}
// Clear the current matrix (Modelview)
glLoadIdentity();
// Back off eight units to be able to view from the origin.
glTranslatef ( 0.0, 0.0, -8.0 );
// Rotate the plane of the elliptic
// (rotate the model's plane about the x axis by fifteen degrees)
glRotatef( 15.0, 1.0, 0.0, 0.0 );
// Draw the sun -- as a yellow, wireframe sphere
glColor3f( 1.0, 1.0, 0.0 );
glutWireSphere( 1.0, 15, 15 );
// Draw the Earth
// First position it around the sun
// Use DayOfYear to determine its position
glRotatef( 360.0*DayOfYear/365.0, 0.0, 1.0, 0.0 );
glTranslatef( 4.0, 0.0, 0.0 );
glPushMatrix(); // Save matrix state
// Second, rotate the earth on its axis.
// Use HourOfDay to determine its rotation.
glRotatef( 360.0*HourOfDay/24.0, 0.0, 1.0, 0.0 );
// Third, draw the earth as a wireframe sphere.
glColor3f( 0.2, 0.2, 1.0 );
glutWireSphere( 0.4, 10, 10);
glPopMatrix(); // Restore matrix state
// Draw the moon.
// Use DayOfYear to control its rotation around the earth
glRotatef( 360.0*12.0*DayOfYear/365.0, 0.0, 1.0, 0.0 );
glTranslatef( 0.7, 0.0, 0.0 );
glColor3f( 0.3, 0.7, 0.3 );
glutWireSphere( 0.1, 5, 5 );
// Flush the pipeline, and swap the buffers
glFlush();
glutSwapBuffers();
if ( singleStep ) {
spinMode = GL_FALSE;
}
glutPostRedisplay(); // Request a re-draw for animation purposes
}
// Initialize OpenGL's rendering modes
void OpenGLInit(void)
{
glShadeModel( GL_FLAT );
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glClearDepth( 1.0 );
glEnable( GL_DEPTH_TEST );
}
// ResizeWindow is called when the window is resized
static void ResizeWindow(int w, int h)
{
float aspectRatio;
h = (h == 0) ? 1 : h;
w = (w == 0) ? 1 : w;
glViewport( 0, 0, w, h ); // View port uses whole window
aspectRatio = (float)w/(float)h;
// Set up the projection view matrix (not very well!)
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0, aspectRatio, 1.0, 30.0 );
// Select the Modelview matrix
glMatrixMode( GL_MODELVIEW );
}
void drawBitmapText(char *string,float x,float y,float z)
{
char *c;
glRasterPos3f(x, y,z);
for (c=string; *c != '\0'; c++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, *c);
}
}
void drawStrokeText(char*string,int x,int y,int z)
{
char *c;
glPushMatrix();
glTranslatef(x, y+8,z);
// glScalef(0.09f,-0.08f,z);
for (c=string; *c != '\0'; c++)
{
glutStrokeCharacter(GLUT_STROKE_ROMAN , *c);
}
glPopMatrix();
}
void reshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,w,h,0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void render(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glColor3f(0,1,0);
drawBitmapText("Hello world",200,200,0);
glutSwapBuffers();
}
// Main routine
// Set up OpenGL, hook up callbacks, and start the main loop
int main( int argc, char** argv )
{
// Need to double buffer for animation
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
// Create and position the graphics window
glutInitWindowPosition( 0, 0 );
glutInitWindowSize( 600, 360 );
glutCreateWindow( "Solar System Demo" );
// Initialize OpenGL.
OpenGLInit();
// Set up callback functions for key presses
glutKeyboardFunc( KeyPressFunc );
glutSpecialFunc( SpecialKeyFunc );
// Set up the callback function for resizing windows
glutReshapeFunc( ResizeWindow );
// Callback for graphics image redrawing
glutDisplayFunc( Animate );
glutDisplayFunc(render);
glutIdleFunc(render);
glutReshapeFunc(reshape);
// Start the main loop. glutMainLoop never returns.
glutMainLoop( );
return(0); // Compiler requires this to be here. (Never reached)
}
These lines in main() cause the problem:
glutKeyboardFunc( KeyPressFunc );
glutSpecialFunc( SpecialKeyFunc );
glutReshapeFunc( ResizeWindow );
glutDisplayFunc( Animate );
glutDisplayFunc(render);
glutIdleFunc(render);
The glutDisplayFunc() overwrites the internal function pointer inside the GLUT. So only the render() function gets called, not the Animate().
The second problem here: Idle function is also the render(), so it gets called twice. The same with Reshape function.
You need to combine the ResizeWindow() and reshape() functions, then render() and Animate() function and then remove the glutIdleFunc call since iteverything is done in the render() already.

OpenGL evaluator only partially lit

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.