GLUT zooming to cursor by clicking, dragging to pan - c++

I'm trying to make this functions like google maps or http://phrogz.net/tmp/canvas_zoom_to_cursor.html.
How to use mouse position like centre of zooming?
How to drag image by moving cursor? Want to do it with button==0 && state==GLUT_DOWN.
Any help much appreciated
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "glut.h"
#define windowSize 900.0
double zoomFactor = 1;
int mouseX=0, mouseY=0;
void reshape (int w, int h)
{
}
void mouse(int button, int state, int x, int y) {
if (button == 0)
{
if (state == GLUT_UP) return;
zoomFactor -= 0.05;
}
else if (button == 2) {
if (state == GLUT_UP) return;
zoomFactor += 0.05;
}
else return;
glutPostRedisplay();
}
void motion(int ax, int ay) {
mouseX = ax;
mouseY = ay;
}
Void display(){
glClear(GL_COLOR_BUFFER_BIT);
glViewport (0.0, 0.0, glutGet(GLUT_INIT_WINDOW_WIDTH), glutGet(GLUT_INIT_WINDOW_HEIGHT));
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (-glutGet(GLUT_INIT_WINDOW_WIDTH)*zoomFactor, glutGet(GLUT_INIT_WINDOW_WIDTH)*zoomFactor,\
-glutGet(GLUT_INIT_WINDOW_HEIGHT)*zoomFactor, glutGet(GLUT_INIT_WINDOW_HEIGHT)*zoomFactor);
glBegin(GL_LINES);
glVertex2f ((0),(0));
glVertex2f ((100),(0));
glEnd();
glBegin(GL_LINES);
glVertex2f ((100),(0));
glVertex2f ((100),(100));
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 );
glutPassiveMotionFunc(motion);
glutMouseFunc(mouse);
glutMainLoop(;
return(0);
}

Related

How to only draw the rectangle when choosing from the menu?

I am writing a program that draws a rectangle with the mouse when and only when the user selects it in the menu, if the user does not select it will not draw. Up to now, I have successfully drawn the rectangle with the mouse, now how can I create a menu so that the user can choose to draw the rectangle? This is my program:
struct Position
{
Position() : x(0), y(0) {}
float x, y;
};
Position start, finish;
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
start.x = finish.x = x;
start.y = finish.y = y;
}
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
{
finish.x = x;
finish.y = y;
}
glutPostRedisplay();
}
void motion(int x, int y)
{
finish.x = x;
finish.y = y;
glutPostRedisplay();
}
void display()
{
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();
glPushMatrix();
glBegin(GL_LINE_LOOP);
glVertex2f(start.x, start.y);
glVertex2f(finish.x, start.y);
glVertex2f(finish.x, finish.y);
glVertex2f(start.x, finish.y);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void menu(int choice)
{
switch (choice)
{
case 1:
// What to write in here?
break;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("");
glutCreateMenu(menu);
glutAddMenuEntry("Rectangle", 1);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutDisplayFunc(display);
glutMainLoop();
}
Add a variable that indicates which shape has to be drawn:
int shape = 0;
Set the variable in menu:
void menu(int choice)
{
switch (choice)
{
case 1:
shape = 1
break;
}
glutPostRedisplay();
}
Draw the scene dependent on shape:
void display()
{
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();
if (shape == 1)
{
glPushMatrix();
glBegin(GL_LINE_LOOP);
glVertex2f(start.x, start.y);
glVertex2f(finish.x, start.y);
glVertex2f(finish.x, finish.y);
glVertex2f(start.x, finish.y);
glEnd();
glPopMatrix();
}
glutSwapBuffers();
}

OpenGL Glut Drawing Points Not Working

Can someone help me out in checking my code? I'm trying to draw a simple dot by clicking in the window, but I can't see any points drawn. The point recording system is copied as an example from one of the stack overflow posts.
#include <stdlib.h>
#include <stdio.h>
//#include <GL\glew.h>
#include <gl/glut.h>
//#include <GL\freeglut.h>
#include <math.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include "draw.h"
//DRAW draw2;
class Point
{
int Xvalue, Yvalue;
std::string Text;
public:
void xy(int x, int y)
{
Xvalue = x;
Yvalue = y;
}
void text(std::string text)
{
Text = text;
}
//return individual x y value
int x() { return Xvalue; }
int y() { return Yvalue; }
//return text value
std::string rtext() { return Text; }
};
Point point[30];
int count = 0;
void Init()
{
glClearColor(1.0, 1.0, 1.0, 0.0);
//glColor3f(0.0, 0.0, 0.0);
//glPointSize(5);
glMatrixMode(GL_PROJECTION); //coordinate system
//glLoadIdentity();
gluOrtho2D(0.0, 1200.0, 0.0, 800.0);
}
void Display()
{
glClear(GL_COLOR_BUFFER_BIT); // clear display window
glColor3f(1.0, 1.0, 1.0);
//glLoadIdentity();
/*Drawing here*/
//redraw
for (int i = 0; i < count; i++)
{
int x = point[i].x();
int y = point[i].y();
//draw2.Dot(x, y);
std::cout << "drawing dot " << x << " " << y << std::endl;
glBegin(GL_POINTS);
glColor3f(0.3, 0.3, 0.3);
glPointSize(5.0f);
glVertex2i(x, glutGet(GLUT_WINDOW_HEIGHT) - y);
glEnd();
}
glFlush();
}
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
point[count].xy(x, y);
//draw2.Dot(x, y);
count++;
}
glutPostRedisplay();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv); //initialize toolkit
//Request double buffered true color window with Z-buffer
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB ); //display mode
glutInitWindowSize(1200, 800); //set window size
glutCreateWindow("NURBS Curve"); //open screen window
Init(); //additional initializations
//CALLBACK FUNCTIONS
glutMouseFunc(mouse);
glutDisplayFunc(Display); //send graphics to display window
/*
GLenum err = glewInit();
if (GLEW_OK != err)
{
fprintf(stderr, "GLEW error");
return 1;
}
*/
//pass control to glut for events, loops
glutMainLoop();
return 0;
}
glBegin(GL_POINTS);
glColor3f(0.3, 0.3, 0.3);
glPointSize(5.0f); // wat
glVertex2i(x, glutGet(GLUT_WINDOW_HEIGHT) - y);
glEnd();
There's a short list of GL functions you can call inside a glBegin()/glEnd() pair and glPointSize() is not on it:
Only a subset of GL commands can be used between glBegin and glEnd.
The commands are
glVertex,
glColor,
glSecondaryColor,
glIndex,
glNormal,
glFogCoord,
glTexCoord,
glMultiTexCoord,
glVertexAttrib,
glEvalCoord,
glEvalPoint,
glArrayElement,
glMaterial, and
glEdgeFlag.
Also,
it is acceptable to use
glCallList or
glCallLists to execute
display lists that include only the preceding commands.
If any other GL command is executed between glBegin and glEnd,
the error flag is set and the command is ignored.
Move the glPointSize() outside the glBegin()/glEnd() pair:
glPointSize(5.0f);
glBegin(GL_POINTS);
for (int i = 0; i < count; i++)
{
int x = point[i].x();
int y = point[i].y();
glColor3f(0.3, 0.3, 0.3);
glVertex2i(x, h - y);
}
glEnd();
All together:
#include <gl/glut.h>
class Point
{
int Xvalue, Yvalue;
public:
void xy(int x, int y)
{
Xvalue = x;
Yvalue = y;
}
//return individual x y value
int x() { return Xvalue; }
int y() { return Yvalue; }
};
Point point[30];
int count = 0;
void Display()
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT); // clear display window
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const double w = glutGet( GLUT_WINDOW_WIDTH );
const double h = glutGet( GLUT_WINDOW_HEIGHT );
gluOrtho2D(0.0, w, 0.0, h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(1.0, 1.0, 1.0);
glPointSize(5.0f);
glBegin(GL_POINTS);
for (int i = 0; i < count; i++)
{
int x = point[i].x();
int y = point[i].y();
glColor3f(0.3, 0.3, 0.3);
glVertex2i(x, h - y);
}
glEnd();
glFlush();
}
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
point[count].xy(x, y);
count++;
}
glutPostRedisplay();
}
int main( int argc, char *argv[] )
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize(1200, 800);
glutCreateWindow("NURBS Curve");
glutMouseFunc(mouse);
glutDisplayFunc(Display);
glutMainLoop();
return 0;
}
Found out that glcolor3f and glpointsize had to be initialized first in my Init() function.
void Init()
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glColor3f(0.0, 0.0, 0.0); //this one
glPointSize(5); //and this one
glMatrixMode(GL_PROJECTION); //coordinate system
//glLoadIdentity();
gluOrtho2D(0.0, 1200.0, 0.0, 800.0);
}

My Shape does not want to move when press a key on OPENGL

I want to make the shape perform a jump while moving horizontally using the sin function but it does not even respond to the 'j' button when it is pressed ?
Am still learning Opengl thouh. Any help about where is the mistake?
#include <GLUT/glut.h>
#include <math.h>
float pointone = 0;
float ydir =0;
GLboolean turn ;
void Display();
void DrawWall();
void Anim();
void Keyboard(unsigned char key, int x, int y);
int main(int argc, char** argr) {
glutInit(&argc, argr);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(1000, 600);
glutInitWindowPosition(50, 50);
glutKeyboardFunc(Keyboard);
glutIdleFunc(Anim);
glutCreateWindow("Kbeer El Haramiya");
glutDisplayFunc(Display);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glPointSize(20.0);
gluOrtho2D(0.0, 1000.0, 0.0, 600.0);
glutMainLoop();
}
void Display() {
glClear(GL_COLOR_BUFFER_BIT);
DrawWall();
glPushMatrix();
if(pointone<=850 && turn ==true){
pointone+=3;
turn=true;}
else if (pointone==0){
turn=true;}
else {
turn = false;
pointone-=3;
}
glTranslatef(pointone, ydir, 0);
glBegin(GL_POLYGON);
glColor3f(0.97f,0.96f,0.768f);
glVertex2i(0.0f, 0.0f);
glVertex2i(50.0f, 0.0f);
glVertex2i(50.0f, 50.0f);
glColor3f(0.70f,0.196f,0.12f);
glVertex2i(0.0f, 50.0f);
glEnd();
glPopMatrix();
glFlush();
}
void DrawWall(){
glBegin(GL_POLYGON);
glColor3f(0.97f,0.96f,0.768f);
glVertex2i(999, 0);
glVertex2i(999,600);
glVertex2i(900, 600);
glVertex2i(900, 0);
glEnd();
glBegin(GL_POLYGON);
glVertex2i(0, 200);
glVertex2i(700,200);
glVertex2i(700, 150);
glVertex2i(0,150);
glEnd();
}
void Keyboard(unsigned char key, int x, int y){
if(key == 'j') {
for(int i =0; i<361;i++){
ydir =sin(i);
glutPostRedisplay();
}
}
}
void Anim(){
glutPostRedisplay();
}
You have to update ydir somewhere in the Display() function. When you try to update it outside of this in a loop, there is only one single redraw scheduled after the Keyboard function has ended.
The code could look (for example) somehow like this:
int yint = -1; //-1 means no moving
void Display() {
if (yint > 360) // Reset when > 360°
yint = -1;
if (yint >= 0 && yint <= 360) //Update until 360° is reached
yint++;
float ydir = sin(yint);
//Draw code here
}
void Keyboard(unsigned char key, int x, int y){
if(key == 'j')
yint = 0;
}
The solution was simple, I was supposed to Create the window before calling Keyboardfunc ! :)

opengl not drawing anything

Just trying to draw a point using glut and glew for opengl version 4.3
my code
void Renderer(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
glPointSize(100);
glColor3f(255, 0, 0);
glVertex3d(10, 10, 0);
glEnd();
glFlush();
glutSwapBuffers();
}
is not rendering anything, can someone tell me what did i miss? here is full code:
#include <iostream>
using namespace std;
#include "vgl.h"
#include "LoadShaders.h"
enum VAO_IDs { Triangles, NumVAOS };
#define WIDTH 1024
#define HEIGHT 768
#define REFRESH_DELAY 10 //ms
//general
long frameCount = 0;
// mouse controls
int mouse_old_x, mouse_old_y;
int mouse_buttons = 0;
float rotate_x = 0.0, rotate_y = 0.0;
float translate_z = -3.0;
/////////////////////////////////////////////////////////////////////
//! Prototypes
/////////////////////////////////////////////////////////////////////
void keyboard(unsigned char key, int x, int y);
void mouse(int button, int state, int x, int y);
void motion(int x, int y);
void timerEvent(int value)
{
glutPostRedisplay();
glutTimerFunc(REFRESH_DELAY, timerEvent, frameCount++);
}
void init (void)
{
// default initialization
glClearColor(0.0, 0.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
// viewport
glViewport(0, 0, WIDTH, HEIGHT);
// projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)WIDTH / (GLfloat)HEIGHT, 1, 10000.0);
}
void Renderer(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
glPointSize(100);
glColor3f(255, 0, 0);
glVertex3d(10, 10, 0);
glEnd();
glFlush();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(WIDTH, HEIGHT);
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow("The Abyss");
glutKeyboardFunc(keyboard);
glutMotionFunc(motion);
glutMouseFunc(mouse);
glutTimerFunc(REFRESH_DELAY, timerEvent, frameCount);
if (glewInit()) //i guess this is true on failure
{
cerr << "Error initializing glew, Program aborted." << endl;
exit(EXIT_FAILURE);
}
//Init First
init();
//Init callback for Rendering
glutDisplayFunc(Renderer);
//Main Loop
glutMainLoop();
exit(EXIT_SUCCESS);
}
////////////////////////////////////////////////////////////////////////
//!Mouse and keyboard functionality
////////////////////////////////////////////////////////////////////////
void keyboard(unsigned char key, int /*x*/, int /*y*/)
{
switch (key)
{
case (27) :
exit(EXIT_SUCCESS);
break;
}
}
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
mouse_buttons |= 1<<button;
}
else if (state == GLUT_UP)
{
mouse_buttons = 0;
}
mouse_old_x = x;
mouse_old_y = y;
}
void motion(int x, int y)
{
float dx, dy;
dx = (float)(x - mouse_old_x);
dy = (float)(y - mouse_old_y);
if (mouse_buttons & 1)
{
rotate_x += dy * 0.2f;
rotate_y += dx * 0.2f;
}
else if (mouse_buttons & 4)
{
translate_z += dy * 0.01f;
}
mouse_old_x = x;
mouse_old_y = y;
}
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
You have requested a Core context. You need to:
Specify a vertex and fragment shader. There are no freebies in Core.
Stop using deprecated functionality like glBegin() and glMatrixMode().
Start using VBOs to submit your geometry.
Start using glDrawArrays() and friends to draw your geometry.

Creating a 4x2 2D coordinate system centered around (0,0)?

I am having trouble setting a orthographical projection matrix of dimensions 4x2 with (0,0) being in the center, (-2, -1) being at the bottom left corner, and (2, 1) being at the top right corner.
I use glutInitWindowSize(600, 300); to initialize the window size.
In my reshape function, I use glViewport(0, 0, w, h); to set the viewport.
Also in my reshape function, I use gluOrtho2D(-(float)w/h, (float)w/h, -2.0, 2.0); to set the ortho.
However, when I move my mouse around to see the world coordinates, the bottom left corner is (-1, -1) and the top right corner is (1, 1). Is there something I am doing wrong here? I am assuming since I am setting bottom and top to -2 and 2 respectively in the gluOrtho2D call, it should give me the right coordinates.
Please help me out if you see anything that might be wrong.
Here is my code so far, please ignore the arm variables and drawing functions.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <iostream>
#if 0 /*unix*/
#include <GL/glut.h>
#endif
#if 1 /*apple */
#include <GLUT/glut.h>
#include <OPENGL/gl.h>
#include <OPENGL/glext.h>
#endif
#if 0 /*windows*/
#include <io.h>
#include <fcntl.h>
#include <glut.h>
#endif
int GW, GH;
bool animfore, animupper;
float foreangle, upperangle;
using namespace std;
void drawShoulder();
void drawUpper();
void drawFore();
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
//draw shoulder
glPushMatrix();
drawShoulder();
//draw upper arm
glPushMatrix();
drawUpper();
//draw forearm
glPushMatrix();
drawFore();
glPopMatrix();
glPopMatrix();
glPopMatrix();
glutPostRedisplay();
glutSwapBuffers();
}
void drawShoulder() {
//cout << "Enters" << endl;
glBegin(GL_POLYGON);
glColor3f((float)30/255, (float)0/255, (float)30/255);
glVertex2f(-2.0, -0.4);
glVertex2f(-2.0, -1.0);
glVertex2f(-1.0, -1.0);
glVertex2f(-1.0, -0.4);
glEnd();
}
void drawUpper() {
}
void drawFore() {
}
void reshape(GLsizei w, GLsizei h) {
GW = w;
GW = h;
glViewport(0, 0, w, h);
glLoadIdentity();
gluOrtho2D(-(float)w/h, (float)w/h, -1.0, 1.0);
cout << "Enters" << endl;
}
void keyboard(unsigned char key, int x, int y) {
switch(key) {
case 'q' : case 'Q' :
exit(EXIT_SUCCESS);
break;
}
}
//control arm animations
void idle() {
if(animupper) {
}
if(animfore) {
}
}
float p2w_x(int gx) {
return (float)2.*GW/(GW*GH-GH)*gx-(float)GW/GH;
}
float p2w_y(int gy) {
int py = GH-1-gy;
return (float)2./(GH-1.)*py-1;
}
void mouseMove(int x, int y) {
cout << "(" << p2w_x(x) << "," << p2w_y(y) << ")" << endl;
}
int main(int argc, char **argv) {
// global variable intializations
GW = 600;
GH = 300;
animfore, animupper = true;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
// initialization
glutInitWindowSize(600, 300);
glutInitWindowPosition(100, 100);
glutCreateWindow("Robot Arm");
glClearColor(1.0, 1.0, 1.0, 1.0);
// callback functions
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutMotionFunc(mouseMove);
glutMainLoop();
}
Try setting glMatrixMode( GL_PROJECTION ) before you make your ortho call and then set it back to GL_MODELVIEW when you do your transformations.