Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

xg0blin

OpenGL SDL/Opengl projection problem

This topic is 5834 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am working on a project for school (get one credit hour for it). It has to work in linux, but I like to program in windows with visual studio, so I started the project using qt, but later decided that I would use SDL instead. To start the display I just drew a grid and am trying to make a camera move around in the little world (I''m adding more later, just a starting point). I''ve done this alot of times with glut, and the windows api, and it always works just fine. When I use SDL (which I am just learning), I can''t seem to get my projection set up properly, no matter what values I put into my functions. I even tried to just some code from a couple of sdl tutorials from gametutorials.com. It still isn''t working right, and I can''t figure out why. It''s probably something stupid I didn''t set up right in SDL, but I don''t know. Please have a look.
Camera.h
  
#ifndef Camera_h
#define Camera_h

#include <windows.h>
#include <SDL/SDL.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include "vector.h"

#define SPEED 15
#define PI 3.14159
#define SCREENWIDTH 1024
#define SCREENHEIGHT 768

class Camera
{
	private:
		Vector Position, View, Up;
		double FrameInterval;

	public:
		bool UpPressed, DownPressed, RightPressed, LeftPressed;

		Camera(double = 0.0, double = 0.0, double = 0.0, 
			   double = 0.0, double = 0.0, double = 0.0, 
			   double = 0.0, double = 0.0, double = 0.0);
		Vector GetPosition(void);
		Vector GetView(void);
		Vector GetUp(void);
		void SetCamera(double, double, double, double, double, double, double, double, double);
		void CheckForMovement(void);
		void UpdateCamera(void);
		void Look(void);
		void SlideCamera(double);
		void StrafeCamera(double);
		void RotateCamera(double, double, double, double);
		void SetViewByMouse(void);
		void CalculateFrameRate(void);
};

#endif
  

Camera.cpp
  
#include "Camera.h"

Camera::Camera(double PositX, double PositY, double PositZ,
			   double ViewX, double ViewY, double ViewZ,
			   double UpX, double UpY, double UpZ)
{
	Position.x = PositX;
	Position.y = PositY;
	Position.z = PositZ;

	View.x = ViewX;
	View.y = ViewY;
	View.z = ViewZ;

	Up.x = UpX;
	Up.y = UpY;
	Up.z = UpZ;

	FrameInterval = 0.0;
	
	UpPressed=DownPressed=LeftPressed=RightPressed=false;
}

Vector Camera::GetPosition(void)
{
	return Position;
}

Vector Camera::GetView(void)
{
	return View;
}

Vector Camera::GetUp(void)
{
	return Up;
}

void Camera::SetCamera(double PositX = 0.0, double PositY = 3.0, double PositZ = 5.0, 
					   double ViewX = 0.0, double ViewY = 0.0, double ViewZ = -5.0,
					   double UpX = 0.0, double UpY = 1.0, double UpZ = 0.0)
{
	Position.x = PositX;
	Position.y = PositY;
	Position.z = PositZ;

	View.x = ViewX;
	View.y = ViewY;
	View.z = ViewZ;

	Up.x = UpX;
	Up.y = UpY;
	Up.z = UpZ;
}

void Camera::CheckForMovement(void)
{
	double LocalSpeed = FrameInterval * SPEED;

	if(UpPressed)
		SlideCamera(-LocalSpeed);
	if(DownPressed)
		SlideCamera(LocalSpeed);
	if(LeftPressed)
		StrafeCamera(LocalSpeed);
	if(RightPressed)
		StrafeCamera(-LocalSpeed);
}

void Camera::UpdateCamera(void)
{
	SetViewByMouse();
	CheckForMovement();
	CalculateFrameRate();
}

void Camera::Look(void)
{	
	gluLookAt(Position.x, Position.y, Position.z,
		      View.x, View.y, View.z,
			  Up.x, Up.y, Up.z);
}

void Camera::SlideCamera(double speed)
{
	Vector NewView = View - Position;
	NewView = Normalize(NewView);

	Position.x += NewView.x * speed;
	Position.z += NewView.z * speed;

	View.x += NewView.x * speed;
	View.z += NewView.z * speed;
}

void Camera::StrafeCamera(double speed)
{
	Vector Strafe = Normalize(CrossProduct(View - Position, Up));

	Position.x += Strafe.x * speed;
	Position.z += Strafe.z * speed;

	View.x += Strafe.x * speed;
	View.z += Strafe.z * speed;
}

void Camera::RotateCamera(double Angle, double x, double y, double z)
{
	Vector vNewView;

    // Get the view vector (The direction we are facing)

    Vector vView = View - Position;     

    // Calculate the sine and cosine of the angle once

    float cosTheta = (float)cos(Angle);
    float sinTheta = (float)sin(Angle);

    // Find the new x position for the new rotated point

    vNewView.x  = (cosTheta + (1 - cosTheta) * x * x)       * vView.x;
    vNewView.x += ((1 - cosTheta) * x * y - z * sinTheta)   * vView.y;
    vNewView.x += ((1 - cosTheta) * x * z + y * sinTheta)   * vView.z;

    // Find the new y position for the new rotated point

    vNewView.y  = ((1 - cosTheta) * x * y + z * sinTheta)   * vView.x;
    vNewView.y += (cosTheta + (1 - cosTheta) * y * y)       * vView.y;
    vNewView.y += ((1 - cosTheta) * y * z - x * sinTheta)   * vView.z;

    // Find the new z position for the new rotated point

    vNewView.z  = ((1 - cosTheta) * x * z - y * sinTheta)   * vView.x;
    vNewView.z += ((1 - cosTheta) * y * z + x * sinTheta)   * vView.y;
    vNewView.z += (cosTheta + (1 - cosTheta) * z * z)       * vView.z;

    // Now we just add the newly rotated vector to our position to set

    // our new rotated view of our camera.

    View = Position + vNewView;
}

void Camera::SetViewByMouse(void)
{
	int MouseX, MouseY;
	Vector ScreenMiddle(SCREENWIDTH/2, SCREENHEIGHT/2, 0), MouseDirection(0, 0, 0);
	static double CurrentRotationX = 0.0;

	SDL_GetMouseState(&MouseX, &MouseY);

	if((MouseX == ScreenMiddle.x) && (MouseY == ScreenMiddle.y))
		return;
	
	SDL_WarpMouse((int)ScreenMiddle.x, (int)ScreenMiddle.y);

	MouseDirection.x = (ScreenMiddle.x - MouseX)/1000; 
	MouseDirection.y = (ScreenMiddle.y - MouseY)/1000;

	CurrentRotationX -= MouseDirection.y;

	if(CurrentRotationX > 1.0)
		CurrentRotationX = 1.0;
	if(CurrentRotationX < -1.0)
		CurrentRotationX = -1.0;

	else
	{
		Vector Axis = CrossProduct(View - Position, Up);
		Axis = Normalize(Axis);

		RotateCamera(MouseDirection.y, Axis.x, Axis.y, Axis.z);
		RotateCamera(MouseDirection.x, 0, 1, 0);
	} 
}

void Camera::CalculateFrameRate(void)
{
	static double fps = 0.0;
	static double PreviousTime = 0.0;
	static double FrameTime = 0.0;
	char WindowFPSCounter[10] = {0};
	float CurrentTime = SDL_GetTicks() * 0.001f;

	FrameInterval = CurrentTime - FrameTime;
	FrameTime = CurrentTime;

	fps++;
	

	if(CurrentTime - PreviousTime > 1.0)
	{
		PreviousTime = CurrentTime;
		sprintf(WindowFPSCounter, "FPS: %d", (int)fps);
		SDL_WM_SetCaption(WindowFPSCounter, "Robert''s Camera Demo");
		fps = 0.0;
	}
}
  

engine.h
  
#include <windows.h>
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream.h>
#include "Camera.h"
#include "ImageLoad.h"

class Engine
{
	private:
		Camera EngineCam;
		ImageLoad Loader;
		SDL_Surface *MainWindow;
		int VideoFlags, WindowWidth, WindowHeight, WindowDepth;
				
	public:
		Engine() 
		{ 
			VideoFlags = 0; 
			WindowWidth = 1024, WindowHeight = 768, WindowDepth = 16;
		};

		void Start(void);
		void Quit(int);
		void InitEngine(void);
		void InitSDL(void);
		void InitGL(void);
		void MainLoop(void);
		void CreateSDLWindow(const char *);
		void Display(void);
		void KeyPressEvent(SDL_keysym *);
		void KeyReleaseEvent(SDL_keysym *);
		void UpdateEngine(void);
};



#endif
  

engine.cpp
  
#include "Engine.h"

void Engine::Start(void)
{
	EngineCam.SetCamera(0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0);
	InitSDL();
	InitGL();
	CreateSDLWindow("Robert''s Camera Demo");
	MainLoop();
}

void Engine::Quit(int ret_value)
{
	SDL_Quit();
	exit(ret_value);
}

void Engine::InitSDL(void)
{
	VideoFlags = SDL_OPENGL|SDL_HWPALETTE|SDL_RESIZABLE;
	
	if(SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		cerr << "Could not initialize SDL_VIDEO" << endl;
		Quit(0);
	}
	
	const SDL_VideoInfo *VideoInfo = SDL_GetVideoInfo();

	if(VideoInfo == NULL)
	{
		cerr << "Could not get VideoInfo" << endl;
		Quit(0);
	}
	
	if(VideoInfo->hw_available)
		VideoFlags |= SDL_HWSURFACE;
	else
		VideoFlags |= SDL_SWSURFACE;

	if(VideoInfo->blit_hw)
		VideoFlags |= SDL_HWACCEL;

	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, WindowDepth);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 0);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 0);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 0);
	SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 0);
}

void Engine::InitGL(void)
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glColor3f(0.0f, 1.0f, 0.0f);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(90.0f, 4/3, 0.1, 150);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void Engine::CreateSDLWindow(const char *WindowTitle)
{
	MainWindow = SDL_SetVideoMode(WindowWidth, WindowHeight, WindowDepth, VideoFlags);

	if(MainWindow == NULL)
	{
		cerr << "Failed to Create SDL Window" << endl;
		Quit(0);
	}
	SDL_WM_SetCaption(WindowTitle, WindowTitle);
}

void Engine::MainLoop(void)
{
	bool Working = true;
	SDL_Event Event;
	
	while(Working)
	{
		while(SDL_PollEvent(&Event))
		{
			switch(Event.type)
			{
				case SDL_QUIT:
					Working = true;
					break;
				case SDL_KEYDOWN:
					KeyPressEvent(&Event.key.keysym);
					break;
				case SDL_KEYUP:
					KeyReleaseEvent(&Event.key.keysym);
					break;
				default:
					break;
			}
		}
		EngineCam.UpdateCamera();
		Display();
	}
}

void Engine::Display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	EngineCam.Look();
	glColor3f(0.0f, 1.0f, 0.0f);
	for(GLint i = -1000; i <= 1000; i++)
	{
		glBegin(GL_LINES);
			glVertex3i(i, 0, -1000);
			glVertex3i(i, 0,  1000);

			glVertex3i(-1000, 0, i);
			glVertex3i( 1000, 0, i);
		glEnd();
	}

	SDL_GL_SwapBuffers();
}

void Engine::KeyPressEvent(SDL_keysym *key)
{
	switch(key->sym)
	{	
		case SDLK_ESCAPE:	
			Quit(0);
			break;
		case SDLK_UP:
		case SDLK_w:
			EngineCam.UpPressed = true;
			break;
		case SDLK_DOWN:
		case SDLK_s:
			EngineCam.DownPressed = true;
			break;
		case SDLK_LEFT:
		case SDLK_a:
			EngineCam.LeftPressed = true;
			break;
		case SDLK_RIGHT:
		case SDLK_d:
			EngineCam.RightPressed = true;
			break;
		default:
			break;
	}	
}

void Engine::KeyReleaseEvent(SDL_keysym *key)
{
	switch(key->sym)
	{
		case SDLK_UP:
		case SDLK_w:
			EngineCam.UpPressed = false;
			break;
		case SDLK_DOWN:
		case SDLK_s:
			EngineCam.DownPressed = false;
			break;
		case SDLK_LEFT:
		case SDLK_a:
			EngineCam.LeftPressed = false;
			break;
		case SDLK_RIGHT:
		case SDLK_d:
			EngineCam.RightPressed = false;
			break;
		default:
			break;
	}
}
  

Main.cpp
  
#include "Engine.h"

int main(int argc, char **argv)
{
	Engine NGen;
	NGen.Start();
	return 0;
}
  

and in case you need it, vector.cpp. Maybe I did something wrong here

  
#include "Engine.h"

int main(int argc, char **argv)
{
	Engine NGen;
	NGen.Start();
	return 0;
}
  

There are more files, but they should have nothing to do with the projection. Anybody got any ideas.

Share this post


Link to post
Share on other sites
Advertisement
What exactly is wrong? Do you get any display at all?

You don''t need to include windows or the gl/glu headers, just use SDL/SDL_opengl.h (I doubt that is the problem but could be). Try it without the paletted surface as well.

Share this post


Link to post
Share on other sites
The problem is, I do get a display, but I'm trying to set it up like you're in a big world or something, and it's like it's just clipping the whole thing off at the near clipping plane and not displaying anything after it or something. My grid appears right in front of me for like 2 units and disappears for the rest of the display. I have the near clipping plane at 1 and the far at 150, but it's clipping it at 1, and not displaying anything after that point. I can't figure out why though. If you copy/paste that stuff, it should be enough to compile and run. I just didn't include my image loading library, quaternion library, and mesh library. I am not using those yet anyways, I was just trying to get my display set.


[edited by - xg0blin on December 23, 2002 4:53:24 PM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!