GLUT zooming in and out by wheel - opengl

I have surfed a lot of sources and tried many varieties, but zooming still don't work. I can't change glprojection to gluPerspective, because in this case my prog don't draw anything. Here is approximate code.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "glut.h"
#define windowSize 900.0
double zoomFactor = 1;
void reshape (int w, int h)
{
glViewport (0.0, 0.0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (-(GLdouble) w * zoomFactor, (GLdouble) w* zoomFactor, -(GLdouble) h* zoomFactor, (GLdouble) h* zoomFactor);
}
void mouse(int button, int state, int x, int y)
{
if (button == 3 || button == 4 )
{
if (state == GLUT_UP) zoomFactor += 0.05;
else zoomFactor -= 0.05;
}
else return;
glutReshapeFunc(reshape);
}
Void display(){
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2f ((0),(0));
glVertex2f ((100),(0));
glEnd();
glBegin(GL_LINES);
glVertex2f ((100),(0));
glVertex2f ((100),(100));
glEnd();
glBegin(GL_LINES);
glVertex2f ((0),(0));
glVertex2f ((100),(1000));
glEnd();
glFlush();
}
int main(int argc,char** argv)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(windowSize, windowSize);
glutInitWindowPosition(500,0);
glutCreateWindow("test");
glClearColor(0, 0.1,0.8,0.90);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 200, 200,0);
glutDisplayFunc( display );
glutMouseFunc(mouse);
glutMainLoop(;
return(0);
}

glutReshapeFunc only tells GLUT which function to call, when the window size changes. It makes very little sense to call it in response to an input event as it will not call the reshape function.
Anyway, your problem is, that you placed setting the viewport and the projection in the reshape function. To all the tutorial writers out there: Stop doing that, it just ingrains bad habits into newbies.
Now please speak with me: "Everything drawing related goes into the display function. The viewport is a drawing state and in every OpenGL program just a little bit more complex than 'Hello Triangle' the viewport is going to be changed several times drawing a single frame – for example when using framebuffer objects. I will thereby vow to never place calls to glViewport or projection matrix setup in the window reshape handler. I also vow to slap everyone in the face who writes code like this in my presence."
Move the whole stuff in your reshape function into display (either set global variables, or use glutGet(GLUT_WINDOW_{WIDTH,HEIGHT}) to get the window dimensions in the display function) and call glutPostRedisplay in your mouse wheel function to trigger a redraw.

Related

Translate a triangle using animation(one by one after some interval) with opengl and c++

I want to make a space invader game in opengl. So I thought of creating the enemies using triangles. Before making the game, I want to try out my hand in animation. I have triangle. i want to translate it left upto some point with animation(i.e, triangle is translated after some interval of time. It should look as if it is moving).After reaching some point in the left, I want to translate it back to the same position or some distances right. The process should go on till the screen is open. I used sleep function. But it is not working. No animation is shown. Only the translated triangle is drawn at different translated position. Help me.
Here is my code-
#include "windows.h"
#include <gl/glut.h>
#include<stdio.h>
void init( void )
{
printf( "OpenGL version: %s\n", (char*)glGetString(GL_VERSION));
printf( "OpenGL renderer: %s\n", (char*)glGetString(GL_RENDERER));
//Configure basic OpenGL settings
glClearColor(1.0, 1.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,640.0,0.0,480.0);
glColor3f(1.0,0.0,0.0);
glPointSize(3);
}
void house(int x, int y,int z)
{
glPushMatrix();
glTranslatef(x, y,z);
glBegin (GL_LINES);
glVertex2i (0,30);
glVertex2i (15,60);
glVertex2i (15,60);
glVertex2i (30,30);
glVertex2i (30,30);
glVertex2i (0,30);
glEnd();
//Sleep(200);
glPopMatrix();
//glutSwapBuffers();
}
// Main drawing routine. Called repeatedly by GLUT's main loop
void display( void )
{
//Clear the screen and set our initial view matrix
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
int i;
for(i = 10; i < 350; i = i + 50)
{
house(i,20,0);
Sleep(200);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glFlush();
}
// Entry point - GLUT setup and initialization
int main( int argc, char** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode (GLUT_DEPTH | GLUT_SINGLE| GLUT_RGB);
glutInitWindowSize (800, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow( "OpenGL Test" );
glutDisplayFunc( display );
init();
glutMainLoop();
return 0;
}
In main() you have declared your display() as display callback function. GLUT will call this function either when it determines that the window need to be redrawn or when it is told to redraw it for example by the function glutPostRedisplay().
The display function is expected to call redraw the windows at a specific point in time. The glFlush() will force the execution of the GL commands.
The problem is that your animation loop is inside the redraw function and glFlush() is called at the end, showing the result at once. And you don't tell GLUT to redraw the windows. This is why you don't seee the animation.
For the purpose of the tutorial, I propose you to define a global variable for the initial position of the house drawing. Of course, you'll have to improve this as soon as you understood how all this works.
static int pos = 10; // temporary work around, just for the demo
Then define a timer function, that gets called after a time interval. This will be the core of your animation, organizing the moving, and the redrawing of the window by calling glutPostRedisplay() :
void timerfunc(int value) // handle animation
{
pos += 50; // update the postion
if (pos<350) // as in your originial loop
glutTimerFunc(200, timerfunc, 0); // plan next occurence
glutPostRedisplay(); // redraw the window
}
Activate your timer function, in main() just before launching glutMainLoop():
glutTimerFunc(200, timerfunc, 0); // call a timer function
glutMainLoop(); // this call is already in your code
Your display function can then be changed into:
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
house(pos, 20, 0); // draw the house at its last calculated position
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glFlush();
}
Then it works in animated modus !

Simple GLUT library issue

This will be my first post on stackoverflow.
So, I'm making a simple program(VISUAL STUDIO 2012), using GLUT library. I basically try to display a torus, but instead I get a black screen.
#include<gl/glut.h>
#include<math.h>
GLfloat r=8;
GLint spin=0;
GLfloat light_position[]={0.0,0.0,0.0,1.0};
GLfloat ex,ey=0, ez, upx=0, upy=0, upz=0;
void init(){
glClearColor(1.0,1.0,1.0,1.0);
glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_TEST);
glPushMatrix();
double sine = (float)sin((float)spin);
double cosine = (float)cos((float)spin);
ex=r*sine;
ez=r*cosine;
gluLookAt(ex,ey,-5.0,0,0,0,upx,upy,upz);
glColor3b(1.0,0,0);
glutSolidTorus(0.275,0.85,8,15);
glPopMatrix();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0,0,(GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0,20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv( GL_LIGHT0, GL_POSITION, light_position);
}
void mouse(int button, int state, int x, int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if( state == GLUT_DOWN){
spin = (spin+15)%360;
glutPostRedisplay();
}
break;
default:
break;
}
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(800,600);
glutInitWindowPosition(300,300);
glutCreateWindow("Light Rotating Torus");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
}
Can somebody modify it/give a hint, so it displays something?
Thanks
The most obvious problem is your UP vector. You set upx, upy and upz. That is not a valid up vector, try changing upy to 1.0f. Because of this, your torus was probably rendered out of screen.
Also, glClear doesn't take GL_DEPTH_TEST as a parameter.
Correct call should be:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Because of this, your screen was not cleared and stayed black (while you set glClearColor to be white).
And lastly, main function should always return int, never void (though it doesn't change anything in your case)

Using glutPassiveMotionFunc(); in GLUT

I have written a simple OpenGL program in C++ that displays a line joining the center of the window to the current position of the mouse pointer.
My code is :
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include<iostream>
using namespace std;
void passive(int,int);
void reshape(int,int);
void init(void);
void display(void);
void camera(void);
int x=3,y=3;
int main (int argc,char **argv) {
glutInit (&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize(1364,689);
glutInitWindowPosition(0,0);
glutCreateWindow("Sample");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutPassiveMotionFunc(passive);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
void display(void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
camera();
glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(x,y,0);
glEnd();
glutSwapBuffers();
}
void camera(void) {
glRotatef(0.0,1.0,0.0,0.0);
glRotatef(0.0,0.0,1.0,0.0);
glTranslated(0,0,-20);
}
void init(void) {
glEnable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_COLOR_MATERIAL);
}
void reshape(int w, int h) {
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,(GLfloat)w/(GLfloat)h,1.0,100.0);
glMatrixMode(GL_MODELVIEW);
}
void passive(int x1,int y1) {
x=x1; y=y1;
}
The problem I am facing is that the x and y values set in the passive() function is not correctly mapped into the screen which uses perspective projection. So the line drawn is joining the center to some other coordinate outside the screen. Any modifications to the code to get it working properly?
An easy way would be to create an orthographic projection matrix and then render all of your "2D" elements (including this line, using the screen coordinates provided by glutPassiveMotionFunc).
Something like this:
void display() {
// clear
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( ... ) // create 3D perspective projection matrix
glMatrixMode(GL_MODELVIEW);
// Render 3D content here
// Render 2D content
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, height, 0); // create 2D orthographic projection matrix with coordinate system roughly equivalent to window position
glMatrixMode(GL_MODELVIEW);
glBegin(GL_LINES);
glVertex2f( width / 2, height / 2 ); // now we can use "pixel coordinates"
glVertex2f( cursorX, cursorY );
glEnd();
...
}
Compare this to your modification of the perspective projection in your reshape method.
Obviously you'll also want to disable states that don't make sense for a "2D" rendering (like depth buffer checking, etc) but it should be pretty obvious. Take a look at this GDSE post for a discussion of how other people do this same task.

OpenGL particle system

I'm trying to simulate a particle system using OpenGl but I can't get it to work, this is what I have so far:
#include <GL/glut.h>
int main (int argc, char **argv){
// data allocation, various non opengl stuff
............
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );
glutInitWindowPosition(100,100);
glutInitWindowSize(size, size);
glPointSize (4);
glutCreateWindow("test gl");
............
// initial state, not opengl
............
glViewport(0,0,size,size);
glutDisplayFunc(display);
glutIdleFunc(compute);
glutMainLoop();
}
void compute (void) {
// change state not opengl
glutPostRedisplay();
}
void display (void) {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
for(i = 0; i<nparticles; i++) {
// two types of particles
if (TYPE(particle[i]) == 1) glColor3f(1,0,0);
else glColor3f(0,0,1);
glVertex2f(X(particle[i]),Y(particle[i]));
}
glEnd();
glFlush();
glutSwapBuffers();
}
I get a black window after a couple of seconds (the window has just the title bar before that). Where do I go wrong?
LE: the x and y coordinates of each particle are within the interval (0,size)
Try to make these changes in your code:
move the Main function at the end of the file
glPoinSize call belongs to the Display function
then you should provide a function to handle resizing of the window glutReshapeFunc(reshape), something like this
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}
glFlush is called from glutSwapBuffers function so you don't need it there
insert this code (after glutCreateWindow call) to set the initial position for the projection
glClearColor(0.2, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 10, 0.0, 10, -1.0, 1.0);

basic GL function glTranslatef don't seem to be working

I was following this tutorial, the triangle renders perfectly, but when I hit the Page Up key, nothing happens.
Here's my code:
// made in Visual Studio Express 2008
// OpenGL3-1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
// if you are not using Visual Studio to compile this then remove stdafx.h
#include <stdlib.h>
#include <windows.h>
#include "glut.h"
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glShadeModel (GL_SMOOTH);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Loading the Identity matrix means we reset the screen coordinate system to XYZ axis of lenght 1:
The screen starts at z=0, x=-1 to x=1 and y=-1 to y=1 */
glLoadIdentity ();
glTranslatef(0,0.0f,-6.0f);
// translate everything by 6 units in the z axis.
glBegin(GL_TRIANGLES);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glVertex3f(-1.0f,-1.0f, 0.0f);
glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd(); // Done Drawing A Triangle
Sleep(5);
glutSwapBuffers();
}
void reshape (int w, int h)
{
// just the window reshape function
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode (GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
// escapes from the program if the ESC key is hit
switch (key) {
case 27:
exit(0);
break;
}
}
void keyspecial( int key, int x, int y )
{
if( key == GLUT_KEY_PAGE_UP) // Page up
{
glTranslatef(90.0,0.0,0.0);
// ...... do what ever you want to do
glutPostRedisplay(); // redraw everything to reflect the changes
}
if (key == GLUT_KEY_PAGE_DOWN)
{
// ...... do what ever you want to do
glutPostRedisplay();// redraw everything to reflect the changes
}
if (key == GLUT_KEY_HOME)
{
// ...... do what ever you want to do
glutPostRedisplay();// redraw everything to reflect the changes
}
if (key == GLUT_KEY_END)
{
// ...... do what ever you want to do
glutPostRedisplay();// redraw everything to reflect the changes
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard); // tell glut to call this function when the user presses a key
glutSpecialFunc(keyspecial); // tell glut to call this function when the user presses a special a key
glutMainLoop();
return 0;
}
Note:
The tutorial suggested using glTranslate(x,y,z) instead of glTranslatef(x,y,z). I assumed that was a typo since glTranslate() doesn't exist
You're resetting your matrix in display, so your glTranslate* from the key event handler is lost. Rethink what you're trying to achieve.
What you're doing in this function is not the right thing to do
void reshape (int w, int h)
{ // just the window reshape function
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode (GL_MODELVIEW);
}
Speak with me: Don't set the viewport size and projection in the reshape handler!
You always set viewport and projection together with everything else in the display handler. It's the only right place to do it.
Next, you don't "place" objects using OpenGL matrix functions. You're just manipulating the transformation matrix, which should be set according to the placement of the objects, which may be perfectly well stored as matrix but independently of OpenGL state. So your keyboard handler should set some variable, which is then used for setting the modelview matrix at the right moment.