OpenCV VideoCapture Video Capture cannot start, trying to use laptop camera - c++

Hey everyone so I was given this code by my professor to look over for using videocapture with OpenCV but it's not wokring for me. The proffessor was able to run it in class and he used his laptop camera, but the same code is not working for me. Is there anything wrong with this code? Or do I have to do some sort of initial setup with my laptop camera using openCV? Any help would be appreciated.
#include <opencv2/opencv.hpp> //for OpenCV 3.x
#include <opencv/highgui.h> //for OpenCV 3.x
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/gl.h>
#include <GL/glut.h>
#endif
#include <cstdio>
cv::VideoCapture *cap = NULL;
int width = 640;
int height = 480;
cv::Mat image;
/*------------ function displaying x,y,z coordinate system ----------*/
void drawAxes(float length)
{
glPushAttrib(GL_POLYGON_BIT | GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT) ;
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) ;
glDisable(GL_LIGHTING) ;
glBegin(GL_LINES) ;
glColor3f(1,0,0) ; //x: red
glVertex3f(0,0,0) ;
glVertex3f(length,0,0);
glColor3f(0,1,0) ; //y: blue
glVertex3f(0,0,0) ;
glVertex3f(0,length,0);
glColor3f(0,0,1) ; //z: green
glVertex3f(0,0,0) ;
glVertex3f(0,0,length);
glEnd() ;
glPopAttrib() ;
}
/*---------------- display --------------*/
void display()
{
glClear( GL_COLOR_BUFFER_BIT ); // clear window
// cv::Mat stores data, has to flip it before displaying it
cv::Mat tempimage;
/*
flip(image, image, 0); // vertically
flip(image, image, +1); // horizontally
// or 90 degree clock wise
transpose(image, image);
flip(image, image, +1);
// or 90 degree counter clock wise
transpose(image, image);
flip(image, image, 0);
*/
cv::flip(image, tempimage, 0);
glDrawPixels(tempimage.size().width,tempimage.size().height,GL_BGR,GL_UNSIGNED _BYTE,tempimage.ptr());
//set viewport
glViewport(0, 0, tempimage.size().width, tempimage.size().height);
//set projection matrix using intrinsic camera params
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/*
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
*/
gluPerspective(60, tempimage.size().width*1.0/tempimage.size().height, 1, 20);
//you will have to set modelview matrix using extrinsic camera params
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/*gluLookAt (cameraX, cameraY, cameraZ, lookAtX, lookAtY, lookAtZ, upX, upY, upZ);
https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/ gluLookAt.xml
*/
gluLookAt(3, 3, 3, 0, 0, 0, 0, 1, 0); //(upX, upY, upZ) = (0, 1, 0) always
//now that the camera params have been set, draw your 3D shapes
//first, save the current matrix
glPushMatrix();
//move to the position where you want the 3D object to go
glTranslatef(0, 0, 0); //this is an arbitrary position for demonstration
//you will need to adjust your transformations to match the positions where
//you want to draw your objects(i.e. chessboard center, chessboard corners)
glutSolidTeapot(0.2);
glutSolidSphere(.3, 100, 100);
drawAxes(1.0);
glPopMatrix();
// show the rendering on the screen
glutSwapBuffers();
// post the next redisplay
glutPostRedisplay();
}
void reshape( int w, int h )
{
// set OpenGL viewport (drawable area)
glViewport( 0, 0, w, h );
}
void mouse( int button, int state, int x, int y )
{
if ( button == GLUT_LEFT_BUTTON && state == GLUT_UP )
{
}
}
void keyboard( unsigned char key, int x, int y )
{
switch ( key )
{
case 'q':
// quit when q is pressed
exit(0);
break;
default:
break;
}
}
void idle()
{
// grab a frame from the camera
(*cap) >> image;
}
int main( int argc, char **argv )
{
int w,h;
if ( argc == 1 ) {
// start video capture from camera
cap = new cv::VideoCapture(0);
} else if ( argc == 2 ) {
// start video capture from file
cap = new cv::VideoCapture(argv[1]);
} else {
fprintf( stderr, "usage: %s [<filename>]\n", argv[0] );
return 1;
}
// check that video is opened
if ( cap == NULL || !cap->isOpened() ) {
fprintf( stderr, "could not start video capture\n" );
return 1;
}
// get width and height
w = (int) cap->get( CV_CAP_PROP_FRAME_WIDTH );
h = (int) cap->get( CV_CAP_PROP_FRAME_HEIGHT );
// On Linux, there is currently a bug in OpenCV that returns
// zero for both width and height here (at least for video from file)
// hence the following override to global variable defaults:
width = w ? w : width;
height = h ? h : height;
// initialize GLUT
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowPosition( 20, 20 );
glutInitWindowSize( width, height );
glutCreateWindow( "OpenGL / OpenCV Example" );
// set up GUI callback functions
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutMouseFunc( mouse );
glutKeyboardFunc( keyboard );
glutIdleFunc( idle );
// start GUI loop
glutMainLoop();
return 0;
}
EDIT:
I think i know the problem. It's because Im running a VM and the VM doesnt detect the camera. But how would I run this code with a video file? I also tried that but it didnt work.

Related

Rendering the mandelbrot set in OpenGl

I have to render the mandelbrot set and I was wondering if someone could point out some flaws with my code - at the moment, the output windows just shows a black screen. I think that my mandelbrot mathematics are correct, because I have used the same code to output a .tga of the mandelbrot - is it something to do with the OpenGl method I am using to output the pixels?
Full code:
#include <Windows.h>
#include <GL\glew.h>
#include <GL\freeglut.h>
#include <iostream>
#include <stdlib.h>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <complex>
#include <fstream>
#include <thread>
#include <mutex>
#include <vector>
#include <Windows.h>
// Import things we need from the standard library
using std::chrono::duration_cast;
using std::chrono::milliseconds;
using std::complex;
using std::cout;
using std::endl;
using std::ofstream;
// ...other useful includes
using std::cout;
using std::endl;
using std::thread;
using std::mutex;
using std::lock;
using std::unique_lock;
using std::vector;
const int width = 600, height = 600; // window size
int windowID;
// The number of times to iterate before we assume that a point isn't in the
// Mandelbrot set.
// (You may need to turn this up if you zoom further into the set.)
const int MAX_ITERATIONS = 500;
bool fullScreen = false;
bool need_to_draw = true;
//****************************************
// Render the Mandelbrot set into the image array.
// The parameters specify the region on the complex plane to plot.
void compute_mandelbrot(double left, double right, double top, double bottom)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the screen buffer
glBegin(GL_POINTS); // start drawing in single pixel mode
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
// Work out the point in the complex plane that
// corresponds to this pixel in the output image.
complex<double> c(left + (x * (right - left) / width),
top + (y * (bottom - top) / height));
// Start off z at (0, 0).
complex<double> z(0.0, 0.0);
// Iterate z = z^2 + c until z moves more than 2 units
// away from (0, 0), or we've iterated too many times.
int iterations = 0;
while (abs(z) < 2.0 && iterations < MAX_ITERATIONS)
{
z = (z * z) + c;
++iterations;
}
if (iterations == MAX_ITERATIONS)
{
glColor3f(1.0, 0.0, 0.0); // Set color to draw mandelbrot
// z didn't escape from the circle.
// This point is in the Mandelbrot set.
glVertex2i(x, y);
}
else
{
glColor3f(0.0, 0.0, 0.0); //Set pixel to black
// z escaped within less than MAX_ITERATIONS
// iterations. This point isn't in the set.
glVertex2i(x, y);
}
}
}
glEnd();
glutSwapBuffers();
need_to_draw = false;
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLsizei windowX = (glutGet(GLUT_SCREEN_WIDTH) - width) / 2;
GLsizei windowY = (glutGet(GLUT_SCREEN_HEIGHT) - height) / 2;
glutInitWindowPosition(windowX, windowY);
glutInitWindowSize(width, height);
windowID = glutCreateWindow("Mandelbrot");
if (need_to_draw)
{
compute_mandelbrot(-2.0, 1.0, 1.125, -1.125);
}
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glutMainLoop();
return 0;
}
The identity GL_PROJECTION matrix doesn't give you a 1-to-1 unit-to-pixel mapping like you're assuming, it's a +/-(1,1,1) cube.
Use glOrtho() to get the matrix you want:
glOrtho( 0, width, 0, height, -1, 1 );
All together:
#include <GL/glut.h>
#include <complex>
using std::complex;
// Render the Mandelbrot set into the image array.
// The parameters specify the region on the complex plane to plot.
void compute_mandelbrot( double left, double right, double top, double bottom )
{
// The number of times to iterate before we assume that a point isn't in the
// Mandelbrot set.
// (You may need to turn this up if you zoom further into the set.)
const int MAX_ITERATIONS = 500;
const int width = glutGet( GLUT_WINDOW_WIDTH );
const int height = glutGet( GLUT_WINDOW_HEIGHT );
glBegin( GL_POINTS ); // start drawing in single pixel mode
for( int y = 0; y < height; ++y )
{
for( int x = 0; x < width; ++x )
{
// Work out the point in the complex plane that
// corresponds to this pixel in the output image.
complex<double> c( left + ( x * ( right - left ) / width ),
top + ( y * ( bottom - top ) / height ) );
// Start off z at (0, 0).
complex<double> z( 0.0, 0.0 );
// Iterate z = z^2 + c until z moves more than 2 units
// away from (0, 0), or we've iterated too many times.
int iterations = 0;
while( abs( z ) < 2.0 && iterations < MAX_ITERATIONS )
{
z = ( z * z ) + c;
++iterations;
}
if( iterations == MAX_ITERATIONS )
{
glColor3f( 1.0, 0.0, 0.0 ); // Set color to draw mandelbrot
// z didn't escape from the circle.
// This point is in the Mandelbrot set.
glVertex2i( x, y );
}
else
{
glColor3f( 0.0, 0.0, 0.0 ); //Set pixel to black
// z escaped within less than MAX_ITERATIONS
// iterations. This point isn't in the set.
glVertex2i( x, y );
}
}
}
glEnd();
}
void display()
{
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
const int width = glutGet( GLUT_WINDOW_WIDTH );
const int height = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho( 0, width, 0, height, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
compute_mandelbrot( -2.0, 1.0, 1.125, -1.125 );
glutSwapBuffers();
}
int main( int argc, char** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA );
glutInitWindowSize( 300, 300 );
glutCreateWindow( "Mandelbrot" );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}

OpenGL- inaccurate depth values from z buffer

I am drawing a quad in OpenGL and then using glReadPixels to access the depth buffer. But, the problem is I'm always getting 1 from all the position of the OpenGL window. For example, for zbuffer[0][0] (please see the code below), the value should be 0, because that part of the window has no object. Again, for zbuffer[639][470], the value should also be 0, but I am receiving 1 for both the case.
Could you please point me what I am doing wrong here?
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream>
#include <fstream>
using namespace std;
void display ( ) // Create The Display Function
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluLookAt(0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,-1.0 ,0.0 ,1.0 ,0.0);
glBegin(GL_QUADS);
glColor3f(0.813205,0.813205,0.813205);
glVertex3f(-0.389662380802125,0.249152038469432, -1.12528215173346); // top left corner
glColor3f(0.309385,0.309385,0.309385);
glVertex3f(0.433401472883409,0.272288002674917, -0.923754348668237); // top right corner
glColor3f(0.288292,0.288292,0.288292);
glVertex3f(0.441173907261717,-0.296124431126115, -0.915317251508196);// bottom right corner
glColor3f(0.74028,0.74028,0.74028);
glVertex3f(-0.388657135983495,-0.317680965994535, -1.09611219327051); // bottom left corner
glEnd();
GLfloat zbuffer[640][480];
glReadPixels(0,0,640,480,GL_DEPTH_COMPONENT,GL_FLOAT, zbuffer);
cout<<"Depth1:"<<zbuffer[0][0]<<endl;
cout<<"Depth2:"<<zbuffer[639][470]<<endl;
glFlush();
glutSwapBuffers ( );
}
void reshape ( int w, int h ) // Create The Reshape Function (the viewport)
{
glViewport(0 ,0 ,(GLsizei)w,( GLsizei)h);
glMatrixMode (GL_PROJECTION );
glLoadIdentity ( );
gluPerspective(48.6f, (GLfloat) 640 / 480, 0.01f, 1000.0f);
glMatrixMode (GL_MODELVIEW) ;
}
void keyboard ( unsigned char key, int x, int y ) // Create Keyboard Function
{
switch ( key ) {
case 27: // When Escape Is Pressed...
exit ( 0 ); // Exit The Program
break; // Ready For Next Case
default: // Now Wrap It Up
break;
}
}
void mouse(int button, int state, int x, int y) {
float mx = x ;
float my = y ;
// ox = (mx/320-1.0);
// oy = -(my/240 -1.0);
switch(button){
case GLUT_LEFT_BUTTON:
if(state==GLUT_DOWN){
printf("%f,",mx);
printf("%f\n",my);
}
break;
}
}
int main ( int argc, char** argv )
{
glutInit ( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (640, 480);
glutInitWindowPosition(0, 0);
glutCreateWindow ( "My Window" ); directory as title)
glutReshapeFunc ( reshape ) ;
glutDisplayFunc ( display ); // Matching Earlier Functions To Their Counterparts
glutKeyboardFunc ( keyboard );
glutMouseFunc(mouse);
glutMainLoop ( ); // Initialize The Main Loop
return 0;
}
And here is the object drawn in OpenGL:
For example, for zbuffer[0][0] (please see the code below), the value should be 0, because that part of the window has no object.
No, it shouldn't. THe default glClearDepth value is 1.0, so glClear( GL_DEPTH_BUFFER_BIT) sets every pixel in the depth buffer to 1.0. This also makes sense because using the dfeault conventions, the near plane is mapped to z=0 in window space, and the far plane to z=1, and the depth test is set to GL_LESS, so that fragments will pass which are nearer that what is currently drawn at that position.

opengl rubberbanded box not showing

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.

GLUT: Wrong Mouse Coordinates?

Using SCREEN_WIDTH = 1200, and SCREEN_HEIGHT = 800.
First, I draw a box to the screen at (x = 0, y = 0, w = 40, h = 40);
Then I use the handleMouse Function to return the x and y coordinates of where the mouse is clicked.
The problem is, when the program starts in non-Maximized windowed mode, when I click on (What appears to be) the very bottom right corner of the box the coordinates returned are x = 40, y = 32. When I think it should be returning x = 40, y = 40.
I don't know whether the problem is if its not being drawn right, or the functions is returning the wrong x/y.
I believe I understand how openGL rendering, transformation and glOrth work, but I could be completely wrong. I have seen a few suggestions online saying that the Windows Decor(Using windows 7) can cause this problem, but have done very little explaining and provided no solution.
This is my entire source code. I have stripped off everything from my game down to the basics, and the problem still persists :( . I added two pictures so people could see my problem. In NON-MAXIMIZED WINDOW(the top picture), when clicking the bottom-right corner, the coordinates returned are 41,32; The y coordinate is smaller than it should be. And in the MAXIMIZED WINDOW(the bottom picture), when clicking the same corner, It returns the correct coordinates 40, 40. These results occur for both my original source code and genpfault's suggested code.
//Turns out I can't post Pictures :(, links instead.
non-Maximized Windowed!
Maximized Windowed!
main.cpp
int main( int argc, char* args[] )
{
//Initialize FreeGLUT
glutInit( &argc, args );
//Create OpenGL 2.1 context
glutInitContextVersion( 2, 1 );
//Create Double Buffered Window
glutInitDisplayMode( GLUT_DOUBLE );
glutInitWindowSize( SCREEN_WIDTH, SCREEN_HEIGHT );
glutCreateWindow( "OpenGL" );
//Do post window/context creation initialization
if( !initGL() )
{
printf( "Unable to initialize graphics library!\n" );
return 1;
}
//initGame();
glutMouseFunc(handleMouse);
glutDisplayFunc( render );
glutMainLoop();
return 0;
}
Functions.h
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
bool initGL();
void render();
void handleMouse(int button, int state, int x, int y);
#endif
Functions.cpp
bool initGL()
{
//Initialize clear color
glClearColor( 0.f, 0.f, 0.f, 1.f );
//Check for error
GLenum error = glGetError();
if( error != GL_NO_ERROR )
{
//cout <<"Error initializing OpenGL! " << gluErrorString( error ) << endl;
return false;
}
return true;
}
void render()
{
//Clear color buffer
glClear( GL_COLOR_BUFFER_BIT );
glColor3f(1.f,1.f,1.f);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glVertex2f(0,0);
glVertex2f(0, 41);
glVertex2f(41, 41);
glVertex2f(41, 0);
glEnd();
glutSwapBuffers();
}
void handleMouse(int button, int state, int x, int y)
{
std::cout << x << '\t' << y << std::endl;
}
constants.h
const int SCREEN_WIDTH = 1200;
const int SCREEN_HEIGHT = 800;
This works fine for me on Windows 7 on Aero and Classic:
#include <GL/glut.h>
#include <iostream>
void render()
{
glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho(0, w, h, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3ub( 255, 255, 255 );
glBegin(GL_QUADS);
glVertex2f(0,0);
glVertex2f(41, 0);
glVertex2f(41, 41);
glVertex2f(0, 41);
glEnd();
glutSwapBuffers();
}
void handleMouse(int button, int state, int x, int y)
{
std::cout << x << '\t' << y << std::endl;
}
int main( int argc, char* args[] )
{
glutInit( &argc, args );
glutInitDisplayMode( GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "OpenGL" );
glutMouseFunc(handleMouse);
glutDisplayFunc( render );
glutMainLoop();
return 0;
}
Most notably I added the runtime glutGet() window size queries to render().
Try moving the quad away from the edge of the display because when I tryed to do something like that the edge of the screen was very odd
glBegin(GL_QUADS);
glVertex2f(20,20);
glVertex2f(20, 61);
glVertex2f(61, 61);
glVertex2f(61, 20);
glEnd();

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.