Rotation in OpenGL

Started by
1 comment, last by Gorax 13 years, 8 months ago
I'm fairly new at OpenGL, and I'm attempting to go along with NeHE's tutorial, but make it object oriented as I go. I should also mention I'm fairly new to C++ as well, which is what I'm using along with OpenGL. One last note is that I'm using SDL as a window for my OpenGL.

Anyway, my classes may not reflect good OpenGL or C++, so if there's anything I should change, feel free to let me know. Let me get to what I'm wondering. I have a Plane class, which looks like this:

Plane.h
#ifndef _TRIANGLE_H_	#define _TRIANGLE_H_	#ifdef WIN32		#define WIN32_LEAN_AND_MEAN		#include <windows.h>	#endif	#if defined(__APPLE__) && defined(__MACH__)		#include <OpenGL/gl.h>	// Header File For The OpenGL32 Library		#include <OpenGL/glu.h>	// Header File For The GLu32 Library	#else		#include <GL/gl.h>	// Header File For The OpenGL32 Library		#include <GL/glu.h>	// Header File For The GLu32 Library	#endif#include <vector>#include "Point.h"#include "Color.h"class Plane {	private:		std::vector<Point> vertices;		std::vector<Color> colors;	public:		Plane(double, double, double);		double x, y, z;				// Current place in space		double rAngle, rX, rY, rZ;	// Rotational values		void draw();		Plane &operator<<(const Point &p);		Plane &operator<<(const Color &c);};#endif


Plane.cpp
#include "Plane.h"#include "SDL/SDL.h"Plane::Plane(double x, double y, double z) {	// Starting Position	this->x = x;	this->y = y;	this->z = z;	// Rotation Variables	rAngle = 0.0f;	rX = 0.0f;	rY = 0.0f;	rZ = 0.0f;}Plane &Plane::operator<<(const Point &p) {	this->vertices.push_back(p);	return *this;}Plane &Plane::operator<<(const Color &c) {	this->colors.push_back(c);	return *this;}void Plane::draw() {	glTranslatef(x, y, z);	glRotatef(rAngle, rX, rY, rZ);	glBegin(GL_POLYGON);		for(int i = 0; i <= vertices.size()-1; i++) {			glColor3f(colors.r, colors.g, colors.b);			glVertex3f(vertices.x,  vertices.y, vertices.z);		}	glEnd();	glRotatef(0.0f, 0.0f, 0.0f, 0.0f);	glTranslatef(-x, -y, -z);}


Now, I've created two Planes, a square and a triangle. And in my main portion of the app, I have some code that rotates it:

CApp.h (Mainly prototypes for the functions)
#ifndef _CAPP_H_	#define _CAPP_H_#include "SDL/SDL.h"#include "Plane.h"class CApp {	private:		bool FullScreen;		bool Running;		int winResW, winResH, fullResW, fullResH;		SDL_Surface* Surf_Display;	public:		CApp();		int OnExecute();		Plane triangle;		Plane square;	public:		bool OnInit();		void OnEvent(SDL_Event* Event);		void OnLoop();		void OnRender();		void OnCleanup();};#endif


CApp_OnEvent.cpp (Does things based on keys being pressed)
#include "CApp.h"#include "Keys.h"void CApp::OnEvent(SDL_Event* Event) {	if(Event->type == SDL_QUIT) {		Running = false;	}	else if(Event->type == SDL_KEYDOWN) {		if(Event->key.keysym.sym == SDLK_ESCAPE) {			Running = false;		}		else if(Event->key.keysym.sym == SDLK_F1) {			FullScreen = !FullScreen;			OnInit();		}		// Movement		if(Event->key.keysym.sym == SDLK_UP) {			Keys::keysPressed[Keys::UP] = true;		}		if(Event->key.keysym.sym == SDLK_DOWN) {			Keys::keysPressed[Keys::DOWN] = true;		}		if(Event->key.keysym.sym == SDLK_LEFT) {			Keys::keysPressed[Keys::LEFT] = true;		}		if(Event->key.keysym.sym == SDLK_RIGHT) {			Keys::keysPressed[Keys::RIGHT] = true;		}		// Rotation		if(Event->key.keysym.sym == SDLK_a) {			Keys::keysPressed[Keys::A] = true;		}		if(Event->key.keysym.sym == SDLK_d) {			Keys::keysPressed[Keys::D] = true;		}	}	else if(Event->type == SDL_KEYUP) {		// Movement		if(Event->key.keysym.sym == SDLK_UP) {			Keys::keysPressed[Keys::UP] = false;		}		if(Event->key.keysym.sym == SDLK_DOWN) {			Keys::keysPressed[Keys::DOWN] = false;		}		if(Event->key.keysym.sym == SDLK_LEFT) {			Keys::keysPressed[Keys::LEFT] = false;		}		if(Event->key.keysym.sym == SDLK_RIGHT) {			Keys::keysPressed[Keys::RIGHT] = false;		}		// Rotation		if(Event->key.keysym.sym == SDLK_a) {			Keys::keysPressed[Keys::A] = false;		}		if(Event->key.keysym.sym == SDLK_d) {			Keys::keysPressed[Keys::D] = false;		}	}}


CApp_OnLoop.cpp (Checks Keys for any being pressed)
#include "CApp.h"#include "Keys.h"void CApp::OnLoop() {	// Vertical Movement	if(Keys::keysPressed[Keys::UP]) {		triangle.y += 0.1f;	}	else if(Keys::keysPressed[Keys::DOWN]) {		triangle.y -= 0.1f;	}	// Horizontal Movement	if(Keys::keysPressed[Keys::RIGHT]) {		triangle.x += 0.1f;	}	else if(Keys::keysPressed[Keys::LEFT]) {		triangle.x -= 0.1f;	}	// Rotation	if(Keys::keysPressed[Keys::A]) {		triangle.rZ = 1.0f;		triangle.rAngle += 1.0f;	}	else if(Keys::keysPressed[Keys::D]) {		triangle.rZ = 1.0f;		triangle.rAngle -= 1.0f;	}	else {		triangle.rZ = 0.0f;	}}


Keys.h (Declares members to keep track of keys being pressed)
#ifndef _KEYS_H_	#define _KEYS_H_class Keys {	public:		static bool keysPressed[8];		static int A, D, DOWN, LEFT, RIGHT, S, UP, W;};#endif


Keys.cpp (Defines the bool and assigns values to the keys)
#include "Keys.h"bool Keys::keysPressed[8] = {false, false, false, false, false, false, false, false};//int Keys:: = ;int Keys::A = 0;int Keys::D = 1;int Keys::DOWN = 2;int Keys::LEFT = 3;int Keys::RIGHT = 4;int Keys::S = 5;int Keys::UP = 6;int Keys::W = 7;


My issue is that when I press A or D, instead of just the triangle rotating, the square rotates with it. And after the squares been rotated, it will move around in a very intriguing way when I move the triangle via arrow keys.

I'm sure the issue is just that I don't know how to use glRotatef() properly, so any help with that would be nice.

One last note: this is meant to be cross-platform code. I want the code to be able to compile in the Code::Blocks IDE on multiple platforms, as I'm using Code::Blocks as my IDE and compiling the code on different platforms (Windows, Mac, and Linux, mainly).
Advertisement
Nevermind.

By changing the draw function in Plane.cpp a little bit to look like:

void Plane::draw() {	glTranslatef(x, y, z);	glRotatef(rAngle, rX, rY, rZ);	glBegin(GL_POLYGON);		for(int i = 0; i <= vertices.size()-1; i++) {			glColor3f(colors.r, colors.g, colors.b);			glVertex3f(vertices.x,  vertices.y, vertices.z);		}	glEnd();	glLoadIdentity();}


The problem was fixed, seemingly. I have more testing to do, but the triangle looks like it's rotating solo. If there are any suggestions anyone has to general coding advice, I'd still be glad to hear it.
I doubt that loading the identity matrix is what you want. Since you're using the built-in matrices, you can just use glPushMatrix() and glPopMatrix() before applying translations and rotations to objects. If you plan on moving to newer versions of Open GL, you'll need to deal with the matrices yourself, but it's important to get the concepts worked out first, otherwise you'll find it's like jumping into the deep end.

This topic is closed to new replies.

Advertisement