Related
I want to use OpenGL to implement an animation that can be started and paused with mouse clicks. Since I am currently using the GLFW, the functions in GLUT are no longer applicable.
In GLUT, the implementation can be like this:
void windowMouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
// start
glutIdleFunc(idleFunction);
}
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
// pause
glutIdleFunc(NULL);
}
}
However, glutIdleFunc() does not work in GLFW. I just wrote a coding frame to perform my goal but got stuck in finding the proper function to replace glutIdleFunc().
void mouse_button_callback(GLFWwindow* window, int button, int action, int mode)
{
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
{
// start
}
else if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
{
// pause
}
}
Is there any function in GLFW that can replace the previous one? Or is there any way to perform continuous animation with GLFW?
Get creative with glfwPostEmptyEvent() and glfwWaitEventsTimeout():
// g++ main.cpp `pkg-config --cflags --libs glfw3 gl`
#include <GLFW/glfw3.h>
void (*idleFunc)(GLFWwindow*) = nullptr;
void idle( GLFWwindow* aWindow )
{
static float angle = 0.0f;
static double prvTime = glfwGetTime();
const double curTime = glfwGetTime();
const double dt = (curTime - prvTime);
prvTime = curTime;
angle += 60.0 * dt;
int w, h;
glfwGetFramebufferSize( aWindow, &w, &h );
glViewport( 0, 0, w, h );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glPushMatrix();
glRotatef( angle, 0, 0, 1 );
glBegin(GL_TRIANGLES);
glColor3ub( 0, 255, 0 );
glVertex2f( -0.5, -0.5 );
glVertex2f( 0.5, -0.5 );
glVertex2f( 0.0, 0.5 );
glEnd();
glPopMatrix();
glfwSwapBuffers( aWindow );
}
void display( GLFWwindow* aWindow )
{
int w, h;
glfwGetFramebufferSize( aWindow, &w, &h );
glViewport( 0, 0, w, h );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glBegin(GL_TRIANGLES);
glColor3ub( 255, 0, 0 );
glVertex2f( -0.5, -0.5 );
glVertex2f( 0.5, -0.5 );
glVertex2f( 0.0, 0.5 );
glEnd();
glfwSwapBuffers( aWindow );
}
void button( GLFWwindow* window, int button, int action, int mode )
{
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
{
idleFunc = idle;
glfwPostEmptyEvent();
}
else if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
{
idleFunc = nullptr;
glfwPostEmptyEvent();
}
}
int main( int, char** )
{
glfwInit();
GLFWwindow* window = glfwCreateWindow( 640, 480, "GLFW", NULL, NULL );
glfwMakeContextCurrent( window );
glfwSetMouseButtonCallback( window, button );
while( !glfwWindowShouldClose( window ) )
{
if(idleFunc)
{
idleFunc(window);
glfwWaitEventsTimeout(0.016);
}
else
{
display(window);
glfwWaitEvents();
}
}
glfwTerminate();
}
The glfwPostEmptyEvent() along with the structure of the glfwWindowShouldClose() loop in main() lets you simulate the behavior of glutPostRedisplay() and the glfwWaitEventsTimeout() lets the idleFunc() (if any) run every 16 milliseconds or so.
In this post the rectangle moved via mouse. I want to add a triangle and move like rectangle via mouse.
The triangle function like this:
void drawTriangle(float x,float y,float size){
glPushMatrix();
glTranslatef( x, y, 0.0f );
glScalef( size, size, 1.0f );
glBegin( GL_TRIANGLES );
glColor3ub( 255, 255, 255 );
glVertex2f( -1, 1 );
glVertex2f( 1, -1 );
glVertex2f( 1, 1 );
glEnd();
glPopMatrix();
Rectangle and triangle moved together. But I want to move it different. So what is my wrong?
You'll have to maintain an array of Shape objects and test each one for mouse collisions, as well as keep track of which Shape you're dragging:
#include <GL/glut.h>
#include <vector>
using namespace std;
struct Shape
{
float mX, mY;
float mSize;
bool mIsRectangle;
bool PointInside( const float x, const float y ) const
{
return
mX - mSize <= x && x <= mX + mSize
&&
mY - mSize <= y && y <= mY + mSize;
}
};
vector< Shape > objects;
Shape* dragging = NULL;
void mouse( int button, int state, int x, int y )
{
if( GLUT_DOWN == state )
{
dragging = NULL;
for( Shape& obj : objects )
{
if( obj.PointInside( x, y ) )
{
dragging = &obj;
glutPostRedisplay();
break;
}
}
}
else
{
dragging = NULL;
}
}
void motion( int x, int y )
{
if( dragging )
{
dragging->mX = x;
dragging->mY = y;
glutPostRedisplay();
}
}
void drawRect( float x, float y, float size )
{
glPushMatrix();
glTranslatef( x, y, 0.0f );
glScalef( size, size, 1.0f );
glBegin( GL_QUADS );
glColor3ub( 255, 255, 255 );
glVertex2f( -1, -1 );
glVertex2f( 1, -1 );
glVertex2f( 1, 1 );
glVertex2f( -1, 1 );
glEnd();
glPopMatrix();
}
void drawTriangle( float x, float y, float size )
{
glPushMatrix();
glTranslatef( x, y, 0.0f );
glScalef( size, size, 1.0f );
glBegin( GL_TRIANGLES );
glColor3ub( 255, 255, 255 );
glVertex2f( -1, 1 );
glVertex2f( 1, -1 );
glVertex2f( 1, 1 );
glEnd();
glPopMatrix();
}
void display()
{
glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
const double w = glutGet( GLUT_WINDOW_WIDTH );
const double h = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho( 0, w, h, 0, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
for( const Shape& obj : objects )
{
if( obj.mIsRectangle )
drawRect( obj.mX, obj.mY, obj.mSize );
else
drawTriangle( obj.mX, obj.mY, obj.mSize );
}
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutMouseFunc( mouse );
glutMotionFunc( motion );
Shape temp;
temp.mSize = 50;
temp.mX = temp.mY = 100;
temp.mIsRectangle = true;
objects.push_back( temp );
temp.mX = temp.mY = 200;
temp.mIsRectangle = false;
objects.push_back( temp );
glutMainLoop();
return 0;
}
I'm trying to draw a selection box over an image drawn using glDrawPixels, but I cannot get it to show. In order to represent the coordinates of the box, I have 4 global integers that I update on mouse actions (the first 2 on click, the others when the mouse is dragged), which I then use in the drawing function. I'm sure that the drawing function is called when the mouse gets dragged, and that the four values at least get updated, since I tried printing them every time the drawing function gets called.
The OpenGL calls I have in the main are:
glutInit(&argc, argv);
glutInitWindowSize(WINDOW_DIM, WINDOW_DIM);
glutInitWindowPosition(0, 0);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
glutCreateWindow("Window");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glClearColor(0.0, 0.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
glutMainLoop();
and my display function:
void display()
{
printf("calling display\n");
for(unsigned int i=0; i<WINDOW_DIM*WINDOW_DIM; ++i)
{
pixels[i]=colors[img[i]];
}
glClear(GL_COLOR_BUFFER_BIT);
glDrawPixels(WINDOW_DIM, WINDOW_DIM, GL_RGB, GL_FLOAT, (float*)pixels);
glutSwapBuffers();
if(upd_xmin!=0 || upd_ymin!=0 || upd_xmax!=0 || upd_ymax!=0)
{
glDrawBuffer(GL_FRONT);
glLogicOp(GL_XOR);
glEnable(GL_COLOR_LOGIC_OP);
printf("drawing selection\n");
printf("coords %d %d %d %d\n", upd_xmin, upd_ymin, upd_xmax, upd_ymax);
glColor3f(1.0, 1.0, 1.0);
glLineWidth(3.0);
glBegin(GL_LINE_LOOP);
glVertex2i(upd_xmin, upd_ymin);
glVertex2i(upd_xmin, upd_ymax);
glVertex2i(upd_xmax, upd_ymax);
glVertex2i(upd_xmax, upd_ymin);
glEnd();
glDisable(GL_COLOR_LOGIC_OP);
glDrawBuffer(GL_BACK);
}
}
As I said, I don't think the problem is with the mouse and motion function, seeing how the coordinates of the box (the upd_x and upd_y variables in the code above) get updated when there's a mouse event, but if needed I can post those as well.
Don't swap the buffers in the middle. Just draw the selection box on the back-buffer like everything else:
#include <GL/glut.h>
int StartX = -1;
int StartY = -1;
int EndX = -1;
int EndY = -1;
void mouse( int button, int state, int x, int y )
{
if( button == GLUT_LEFT && state == GLUT_DOWN )
{
StartX = x;
StartY = y;
}
if( button == GLUT_LEFT && state == GLUT_UP )
{
StartX = -1;
StartY = -1;
EndX = -1;
EndY = -1;
}
}
void motion( int x, int y )
{
EndX = x;
EndY = y;
glutPostRedisplay();
}
void display()
{
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double ar = w / h;
glOrtho( -2 * ar, 2 * ar, -2, 2, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glBegin( GL_TRIANGLES );
glColor3ub( 255, 0, 0 );
glVertex2i( -1, -1 );
glColor3ub( 0, 255, 0 );
glVertex2i( 1, -1 );
glColor3ub( 0, 0, 255 );
glVertex2i( 0, 1 );
glEnd();
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, w, h, 0, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
if( StartX > 0 && StartY > 0 && EndX > 0 && EndY > 0 )
{
glLogicOp(GL_XOR);
glEnable(GL_COLOR_LOGIC_OP);
glColor3f(1.0, 1.0, 1.0);
glLineWidth(3.0);
glBegin(GL_LINE_LOOP);
glVertex2i(StartX, StartY);
glVertex2i(EndX, StartY);
glVertex2i(EndX, EndY);
glVertex2i(StartX, EndY);
glEnd();
glDisable(GL_COLOR_LOGIC_OP);
}
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutMouseFunc( mouse );
glutMotionFunc( motion );
glutMainLoop();
return 0;
}
Since you weren't specifying them I added projection and modelview matrices.
I believe the problem lies here:
glClear(GL_COLOR_BUFFER_BIT);
glDrawPixels(WINDOW_DIM, WINDOW_DIM, GL_RGB, GL_FLOAT, (float*)pixels);
glutSwapBuffers();
rest of drawing
Your render call should look like:
clear
render
swap buffers
Where render is all of your draw calls (including glDrawPixels).
Also, glDrawPixels was removed in OpenGL 3.2. Unless you absolutely need to use that particular method, why not use an orthographic projection to draw GUI elements (which the selection box can be though of as)?
Edit: Also, be aware that if you make draw calls after glDrawPixels, those may overwrite what you drew with glDrawPixels.
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
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.