c++ opengl camera movement - c++

I am having issues figuring out why the camera wont move! I think i setup the code correct. Any pointers?
When I launch it the triangle comes up but i cannot move the camera, most likely its my whole method behind the camera movement that is to blame due to inexperience. Could somebody point me in the right direction?
include "stdafx.h"
#include <GL/glut.h>
#include <GL/freeglut.h>
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
//THESE ARE MY VARIABLES
//===========
int x = 0; //|
int y = 0; //|
int z = 0; //|
//===========
//Camera Movement
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
if (WM_KEYDOWN == VK_UP) {
std::cout << "User pressed UP!";
++z;
}
if (WM_KEYDOWN == VK_DOWN) {
std::cout << "User pressed DOWN!";
--z;
}
if (WM_KEYDOWN == VK_LEFT) {
std::cout << "User pressed LEFT!";
--x;
}
if (WM_KEYDOWN == VK_RIGHT) {
std::cout << "User pressed RIGHT!";
++x;
}
}
void display()
{
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
glColor3f(1.0, 0, 0);
glVertex3f(0.5, 0.5, 1);
glColor3f(0, 1.0, 0);
glVertex3f(0.5, 0, 1);
glColor3f(0, 0, 1.0);
glVertex3f(0, 0.5, 1);
glVertex3f(0.5, 0.5, 1);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(640, 480);
glutInitWindowPosition(10, 10);
glutCreateWindow("McDank");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}

You need to register a keyboard callback with GLUT via glutKeyboardFunc() or glutSpecialFunc() to handle keystrokes.
Your glViewport() function is...bizarre. Not sure what you were trying to achieve here with comparing random Windows enums against other enums.
You need to actually use your x/y/z variables in your display function, perhaps in a glTranslate().
All together:
#include <GL/glut.h>
float x = 0;
float y = 0;
float z = 0;
void special( int key, int, int )
{
const float step = 0.1;
if( GLUT_KEY_LEFT == key )
x -= step;
if( GLUT_KEY_RIGHT == key )
x += step;
if( GLUT_KEY_UP == key )
y += step;
if( GLUT_KEY_DOWN == key )
y -= step;
glutPostRedisplay();
}
void display()
{
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -2, 2, -2, 2, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( x, y, z );
glBegin( GL_TRIANGLES );
glColor3ub( 255, 0, 0 );
glVertex2f( -1, -1 );
glColor3ub( 0, 255, 0 );
glVertex2f( 1, -1 );
glColor3ub( 0, 0, 255 );
glVertex2f( 0, 1 );
glEnd();
glutSwapBuffers();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(600, 600);
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutCreateWindow("McDank");
glutSpecialFunc( special );
glutDisplayFunc(display);
glutMainLoop();
return 0;
}

Related

Why does my glDrawArrays is not drawing the points I have stored?

I'm trying to just create a simple program that draws points where I click.
I declare a struct that holds the coordinates and the color of each point.
I declare a global vector< Point > that holds the list of points. The mouse input is well recorded and printed on the cout, but the points are not draw.
Any idea why I am missing in the initialization of GLUT?
#include <GL/freeglut_std.h>
#include <GL/gl.h>
#include <vector>
#include <iostream>
using namespace std;
struct Point
{
float x, y;
unsigned char r, g, b, a;
};
vector< Point > points;
void drawPoints()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50, 50, -50, 50, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// draw
glColor3ub( 255, 255, 255 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
glVertexPointer( 2, GL_FLOAT, sizeof(Point), &points[0].x );
glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(Point), &points[0].r );
glPointSize( 3.0 );
glDrawArrays( GL_POINTS, 0, points.size() );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
glFlush();
glutSwapBuffers();
}
void OnMouseClick(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
{
//store the x,y value where the click happened
Point p = Point();
p.x = (float)x;
p.y = (float)y;
p.r = 255;
p.g = 255;
p.b = 255;
p.a = 255;
points.push_back(p);
for (vector<Point>::iterator it = points.begin(); it != points.end(); ++it)
{
cout << it->x << " " << it->y << " " << flush;
}
cout << endl;
glutPostRedisplay();
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL - Drawing points");
glutDisplayFunc(drawPoints);
glutMouseFunc(OnMouseClick);
glutMainLoop();
return 0;
}
Coordinate system mismatch, either transform GLUT's mouse coordinates into your chosen glOrhto() coordinate system or change that call to match GLUT's mouse coordinate system.
Example of the second way:
#include <GL/glut.h>
#include <vector>
using namespace std;
struct Point
{
float x, y;
unsigned char r, g, b, a;
};
vector< Point > points;
void drawPoints()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
GLdouble w = glutGet( GLUT_WINDOW_WIDTH );
GLdouble h = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho( 0, w, h, 0, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// draw
if( !points.empty() )
{
glColor3ub( 255, 255, 255 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
glVertexPointer( 2, GL_FLOAT, sizeof( Point ), &points[ 0 ].x );
glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( Point ), &points[ 0 ].r );
glPointSize( 3.0 );
glDrawArrays( GL_POINTS, 0, points.size() );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
}
glutSwapBuffers();
}
void OnMouseClick( int button, int state, int x, int y )
{
if( button == GLUT_LEFT_BUTTON && state == GLUT_UP )
{
//store the x,y value where the click happened
Point p = Point();
p.x = (float)x;
p.y = (float)y;
p.r = 255;
p.g = 255;
p.b = 255;
p.a = 255;
points.push_back( p );
glutPostRedisplay();
}
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 500, 500 );
glutInitWindowPosition( 100, 100 );
glutCreateWindow( "OpenGL - Drawing points" );
glutDisplayFunc( drawPoints );
glutMouseFunc( OnMouseClick );
glutMainLoop();
return 0;
}

Draw a polygon QUADS when mouse is clicked?

how can drawing like square or TRIANGLES when clicked on any position on screen show the shape this is my Attempt i do't know what doing
...........................................................................
.......................................................................................
#include <windows.h>
#include <gl/Gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
GLsizei wh=500,ww=500;
GLfloat size=3.0;
void drawsquare( int x, int y)
{
y=wh-y;
glBegin(GL_POLYGON);
glVertex2f(x+size,y+size);
glVertex2f(x-size,y+size);
glVertex2f(x-size,y-size);
glVertex2f(x+size,y-size);
glEnd();
glFlush();
}
void mymose(int button,int state,int x,int y)
{
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
drawsquare(x,y);
//if(button==GLUT_RIGHT_BUTTON_BUTTON && state==GLUT_UP)
// exit();
}
void myInit(){
glViewport(0,0,ww,wh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0,0.0,0.0,1.0);
glColor3f(1.0,0.0,0.0);
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(ww,wh);
glutInitWindowPosition(100,100);
glutCreateWindow("GLUT");
glutMouseFunc(mymose);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
You need a vector to store the points in.
Add points in the mouse callback and request a redraw via glutPostRedisplay().
Then in display() you can spin over all the points in the vector and draw quads around them:
#include <GL/glut.h>
#include <vector>
struct Point
{
Point( float x, float y ) : x(x), y(y) {}
float x, y;
};
std::vector< Point > points;
void mouse( int button, int state, int x, int y )
{
if( button == GLUT_LEFT_BUTTON && state == GLUT_UP )
{
points.push_back( Point( x, y ) );
}
if( button == GLUT_RIGHT_BUTTON && state == GLUT_UP )
{
points.clear();
}
glutPostRedisplay();
}
void display()
{
glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
int w = glutGet( GLUT_WINDOW_WIDTH );
int h = glutGet( GLUT_WINDOW_HEIGHT );
glOrtho( 0, w, h, 0, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3ub( 255, 0, 0 );
glBegin( GL_QUADS );
for( size_t i = 0; i < points.size(); ++i )
{
const unsigned int SIZE = 20;
const Point& pt = points[ i ];
glVertex2i( pt.x - SIZE, pt.y - SIZE );
glVertex2i( pt.x + SIZE, pt.y - SIZE );
glVertex2i( pt.x + SIZE, pt.y + SIZE );
glVertex2i( pt.x - SIZE, pt.y + SIZE );
}
glEnd();
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glutMouseFunc( mouse );
glutDisplayFunc( display );
glutMainLoop();
return 0;
}

Open GL color picker not coloring objects

I have written a color picker in C++ using OpenGL but I cannot figure out how to color a polygon (or anything else for that matter) with the colors I have stored. Do I need to put the draw function in some kind of loop or is there a better way to do this?
#ifdef __APPLE__
# include <OpenGL/gl.h>
# include <OpenGL/glu.h>
# include <GLUT/glut.h>
#else
# include <GL/gl.h>
# include <GL/glu.h>
# include <GL/glut.h>
#endif
#include <iostream>
#include <cmath>
using namespace std;
#define WIDTH 750
#define HEIGHT 750
int i=0,mousex, mousey;
float pick[3];
bool mouseleftdown = false;
void hex(void){
glBegin(GL_POLYGON);
glColor3f(1,0,0); //red
glVertex2f(0, 2); //top
glColor3f(1,.38,.01); //orange
glVertex2f(2, 1); //top right
glColor3f(1,1,0); //yellow
glVertex2f(2, -1); //bottom right
glColor3f(0,1,0); //green
glVertex2f(0, -2); //bottom
glColor3f(0,0,1); //blue
glVertex2f(-2, -1); //bottom left
glColor3f(.8,0,.8); //purple
glVertex2f(-2, 1); //top left
glEnd();
glEnd();
}
void square(void){
glBegin(GL_POLYGON);
glVertex2i(1, -1);
glVertex2i(1, 1);
glVertex2i(-1, 1);
glVertex2i(-1, -1);
glEnd();
}
void mouse(int button, int state, int x, int y){
// Save the left button state
/*if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
glutPostRedisplay(); // Left button has changed; redisplay!
}*/
// Save the mouse position
mousex = x;
mousey = y;
glReadPixels(mousex , mousey , 1 , 1 , GL_RGB , GL_FLOAT , &pick);
cout << pick[0] <<"pick";
cout << " mouse x " << mousex << "\n";
cout << " mouse y " << mousey << "\n";
fflush(stdout);
cout << "pick R: " << pick[1] << "\n";
cout << "pick G: " << pick[0] << "\n";
cout << "pick B: " << pick[2] << "\n";
}
void draw(void){
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glScalef(20,20,1);
hex();
glPopMatrix();
glPushMatrix();
glTranslatef(100,100,0);
glColor3f(pick[1],pick[0],pick[2]);
glScalef(20,20,1);
square();
glPopMatrix();
glFlush();
}
void my_init(void){
//glClearColor(0, 0, 0, 1); //sets clear color
glLineWidth(4);
gluOrtho2D(-100, 100, -100, 100); //sets origin
}
int main(int argc, char* argv[ ]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("Color Picker");
glutDisplayFunc(draw);
glutMouseFunc(mouse);
my_init();
glClearColor(1, 1, 1, 0);
glutMainLoop(); //listens for events
return 0;
}
You have to simply add the line:
glutPostRedisplay();
at the end of your mouse callback function.
This is because you always have to explicitly tell glut when to refresh the window.

My C++ OpenGL SDL program is not working as I expected

I have just started learning OpenGL and I am attempting to make a game of pong.
I'm having trouble getting the paddle to appear on the screen and I can't fathom out why: I thought with this code it should appear in the top left corner and move when down and up keys are pressed.
main.cpp -
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include "classes.h"
#include "functions.h"
int main (int argc, char *argv[])
{
init_everything();
PlayerPaddle paddle;
bool quit = false;
while( quit == false )
{
while( SDL_PollEvent( &event ) )
{
paddle.handle_input();
if( event.type == SDL_QUIT )
{
quit = true;
}
}
glClear( GL_COLOR_BUFFER_BIT );
paddle.show();
SDL_GL_SwapBuffers();
}
SDL_Quit();
return 0;
}
classes.h -
#ifndef CLASSES_H
#define CLASSES_H
SDL_Event event;
// ******************* Beginning of PlayerPaddle class *******************
class PlayerPaddle
{
private:
int xloc;
int yloc;
int paddle_height;
int paddle_width;
public:
PlayerPaddle();
void show();
void handle_input();
};
PlayerPaddle::PlayerPaddle()
{
int xloc = 0;
int yloc = 0;
int paddle_height = 50;
int paddle_width = 15;
}
void PlayerPaddle::show()
{
glBegin( GL_QUADS );
glColor4f( 1.0, 1.0, 1.0, 1.0 );
glVertex3f( 0, yloc, 0 );
glVertex3f( paddle_width, yloc, 0 );
glVertex3f( paddle_width, paddle_height, 0 );
glVertex3f( 0, paddle_height, 0 );
glEnd();
glLoadIdentity();
}
void PlayerPaddle::handle_input()
{
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP:
yloc -= 10;
paddle_height -= 10;
break;
case SDLK_DOWN:
yloc += 10;
paddle_height += 10;
break;
}
}
if (yloc < 0)
{
yloc += 10;
paddle_height += 10;
}
if (yloc > 640)
{
yloc -= 10;
paddle_height -= 10;
}
}
// ******************* End of the PlayerPaddle class *******************
#endif
functions.h -
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
void init_GL()
{
glClearColor( 0, 0, 0, 0 );
glViewport(0, 0, 640, 480);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, 640, 480, 0, 1, -1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
void init_everything()
{
SDL_Init( SDL_INIT_EVERYTHING );
SDL_SetVideoMode( 640, 480, 32, SDL_OPENGL );
init_GL();
SDL_WM_SetCaption( "Pong by Michael Clover", NULL );
}
#endif
Give this a shot:
#include <SDL.h>
#include <SDL_opengl.h>
class PlayerPaddle
{
private:
int xloc;
int yloc;
int paddle_height;
int paddle_width;
public:
PlayerPaddle()
{
xloc = 0;
yloc = 0;
paddle_height = 50;
paddle_width = 15;
}
void show()
{
glPushMatrix();
glTranslatef( xloc, yloc, 0 );
glBegin( GL_QUADS );
glColor4f( 1.0, 1.0, 1.0, 1.0 );
glVertex2f( 0, 0 );
glVertex2f( paddle_width, 0 );
glVertex2f( paddle_width, paddle_height );
glVertex2f( 0, paddle_height );
glEnd();
glPopMatrix();
}
void handle_input( const SDL_Event& event )
{
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: yloc += 10; break;
case SDLK_DOWN: yloc -= 10; break;
}
}
if (yloc < 0)
{
yloc = 0;
}
if (yloc > 640)
{
yloc = 640;
}
}
};
void init_GL()
{
glClearColor( 0, 0, 0, 0 );
glViewport(0, 0, 640, 480);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, 640, 0, 480, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
void init_everything()
{
SDL_Init( SDL_INIT_EVERYTHING );
SDL_SetVideoMode( 640, 480, 32, SDL_OPENGL );
init_GL();
SDL_WM_SetCaption( "Pong by Michael Clover", NULL );
}
int main (int argc, char *argv[])
{
init_everything();
PlayerPaddle paddle;
bool quit = false;
while( quit == false )
{
SDL_Event event;
while( SDL_PollEvent( &event ) )
{
paddle.handle_input( event );
if( event.type == SDL_QUIT )
{
quit = true;
}
}
glClear( GL_COLOR_BUFFER_BIT );
paddle.show();
SDL_GL_SwapBuffers();
}
SDL_Quit();
return 0;
}
Most notably your constructor was borked. You were declaring and setting local variables instead of your member variables. Which resulted in uninitialized member variables, way off in la-la land (-80 thousand or so on my machine) and (obviously) nowhere near your viewport :)
I switched the glOrtho() call around to produce a standard Cartesian coordinate system, with (0,0) in the lower-left and (640,480) in the upper-right.

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.