I seem to be having the same trouble over and over again and cannot get my thick head around it. This program will not display a paddle as I want (and expected it) to do on screen :( -
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
SDL_Event event;
const int paddle_width = 20;
const int paddle_height = 80;
class PlayerPaddle
{
private:
int xloc;
int yloc;
int yvel;
public:
PlayerPaddle()
{
int xloc = 20;
int yloc = 200;
int yvel = 0;
}
void ShowPaddle()
{
glTranslatef(xloc,yloc,0);
glBegin(GL_QUADS);
glColor4f(1.0,1.0,1.0,1.0);
glVertex3f(0,0,0);
glVertex3f(20,0,0);
glVertex3f(20,80,0);
glVertex3f(0,80,0);
glEnd();
glLoadIdentity();
}
void MovePaddle()
{
yloc += yvel;
}
void Handle_Input()
{
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: yvel -= paddle_height / 2; break;
case SDLK_DOWN: yvel += paddle_height / 2; break;
}
}
else if( event.type == SDL_KEYUP )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: yvel += paddle_height / 2; break;
case SDLK_DOWN: yvel -= paddle_height / 2; break;
}
}
}
};
void init ()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_SetVideoMode(640,480,32,SDL_OPENGL);
SDL_WM_SetCaption( "Pong", NULL );
glClearColor( 0, 0, 0, 0 );
glViewport(0, 0, 640, 480);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, 640 , 480 , 0, 0, 1 );
glMatrixMode( GL_MODELVIEW );
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
}
int main (int argc, char **argv)
{
init();
PlayerPaddle ppaddle;
bool quit = false;
while (quit == false)
{
while (SDL_PollEvent (&event))
{
ppaddle.Handle_Input();
if (event.type == SDL_QUIT)
quit = true;
}
ppaddle.MovePaddle();
glClear(GL_COLOR_BUFFER_BIT);
ppaddle.ShowPaddle();
SDL_GL_SwapBuffers();
}
SDL_Quit();
return 0;
}
I just get a clear black screen until I quit the program which returns 0 as expected. I know the code:
ppaddle.MovePaddle();
glClear(GL_COLOR_BUFFER_BIT);
ppaddle.ShowPaddle();
SDL_GL_SwapBuffers();
iterates at least once as if I inserted a return 1; statement in there the program would start up and return 1 immediately.
At a minimum you screwed up your constructor. Again.
It should probably be this:
PlayerPaddle()
{
xloc = 20;
yloc = 200;
yvel = 0;
}
You may also want to toss in a SDL_Delay(100) at the end of your main loop to slow things down until you get some more sophisticated physics handling going.
Related
What I'm trying to do is make an SDL program that can write special symbols to a window I created. The keyboard can change between 4 layers each registering 32 keys. I just can't figure out how to actually make something appear on the screen and have no idea what I'm doing wrong.
#include <iostream>
#include <SDL2/SDL.h>
int main(int argc, const char * argv[])
{
//Setup
bool quit = false;
SDL_Event event;
int z = 0; //Layer
int x = 0;
int y = 0;
//Init
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * window = SDL_CreateWindow("TPKB", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 960, 640, SDL_WINDOW_SHOWN);
SDL_Rect rect = {x, y, 32, 32};
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface * A_srf = SDL_LoadBMP("A.bmp"); SDL_Texture * A = SDL_CreateTextureFromSurface(renderer, A_srf); SDL_FreeSurface(A_srf);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
//Events
while (!quit)
{
SDL_WaitEvent(&event);
switch (event.type)
{
case SDL_QUIT:
quit = true;
break;
case SDL_KEYUP:
{
if(z == 0)
{
switch(event.key.keysym.sym)
{
//case SDLK_1: SDL_BlitSurface(A_srf, NULL, surface, srfrect); break;
case SDLK_2: SDL_RenderCopy(renderer, A, NULL, &rect); if(x == 928){x = 0; y += 32;} else{x += 32;} rect.x = x; rect.y = y; SDL_RenderClear(renderer); SDL_RenderPresent(renderer); break;
case SDLK_LEFT: z = 1; std::cout << "1"; break;
}
}
if(z == 1)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: z = 0; std::cout << "0"; break;
}
}
}
}
}
//Cleanup
SDL_DestroyRenderer(renderer);
SDL_DestroyTexture(A);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I've tried moving the render clear render present stuff around but it hasn't seemed to be activating at all.
My complete code -
#include <SDL.h>
#include <SDL_opengl.h>
#include <GL\GLU.h>
#include <fstream>
using namespace std;
int index = 0;
int speed = 0;
int frames = 0;
int lasttime = 0;
int mousex = 0;
int mousey = 0;
bool postRedraw = true;
int screenWidth = 640;
int screenHeight = 480;
float screenAspect = screenWidth/screenHeight;
bool init();
bool initGL();
void handleKeys( unsigned char key, int x, int y );
void update();
void render();
void close();
void Initialize();
void handleEvents();
ofstream logFile;
SDL_Window* gWindow = NULL;
bool isRunning = true;
SDL_GLContext gContext;
float xpos = 0.0;
float ypos = 0.0;
float zpos = 0.0;
void Initialize()
{
gluPerspective(60.0f, screenAspect, 1.0, 400.0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
glTranslatef(0.0f, 0.0f, -5.0f);
glFrontFace(GL_CCW);
glEnable(GL_LIGHT0);
}
void render()
{
glTranslatef(xpos, ypos, zpos);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f,0.0f,-1.0f);
glVertex3f(0.0f, 1.0f, -1.0f);
glVertex3f(0.0f, 2.0f, -2.0f);
glEnd();
postRedraw = true;
}
void handleEvents()
{
const Uint8* keystates = SDL_GetKeyboardState(NULL);
if(keystates[SDL_GetScancodeFromKey(SDLK_w)])
{
zpos += 0.01;
}
if(keystates[SDL_GetScancodeFromKey(SDLK_s)])
{
zpos -= 0.01;
} else {
}
}
bool init()
{
bool success = true;
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
logFile<<"SDL could not initialize! SDL Error: "<<SDL_GetError()<<endl;
success = false;
}
else
{
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screenWidth, screenHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE );
if( gWindow == NULL )
{
logFile<<"Window could not be created! SDL Error: "<<SDL_GetError()<<endl;
success = false;
}
else
{
gContext = SDL_GL_CreateContext( gWindow );
if( gContext == NULL )
{
logFile<<"OpenGL context could not be created! SDL Error: "<<SDL_GetError()<<endl;
success = false;
}
else
{
if( SDL_GL_SetSwapInterval( 1 ) < 0 )
{
logFile<<"Warning: Unable to set VSync! SDL Error: "<<SDL_GetError()<<endl;
}
if( !initGL() )
{
logFile<<"Unable to initialize OpenGL!"<<endl;
success = false;
}
}
}
}
logFile.open("log.txt");
if(logFile.is_open())
{
success = true;
} else {
success = false;
}
return success;
}
bool initGL()
{
bool success = true;
GLenum error = GL_NO_ERROR;
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
error = glGetError();
if( error != GL_NO_ERROR )
{
logFile<<"Error initializing OpenGL! "<<gluErrorString( error )<<endl;
success = false;
}
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
error = glGetError();
if( error != GL_NO_ERROR )
{
logFile<<"Error initializing OpenGL! "<<gluErrorString( error )<<endl;
success = false;
}
glClearColor( 0.f, 0.f, 0.f, 1.f );
error = glGetError();
if( error != GL_NO_ERROR )
{
logFile<<"Error initializing OpenGL! "<<gluErrorString( error );
success = false;
}
return success;
}
void close()
{
logFile.close();
SDL_DestroyWindow( gWindow );
gWindow = NULL;
SDL_Quit();
}
int main( int argc, char* args[] )
{
if( !init() )
{
logFile<<"Failed to initialize!"<<endl;
}
else
{
SDL_Event event;
Initialize();
lasttime = SDL_GetTicks();
while(isRunning)
{
while( SDL_PollEvent( &event ) != 0 )
{
if(event.type == SDL_QUIT)
{
isRunning = false;
} else if(event.type == SDL_MOUSEMOTION) {
SDL_GetMouseState(&mousex, &mousey);
} else if(event.type == SDL_MOUSEBUTTONDOWN) {
SDL_GetMouseState(&mousex, &mousey);
} else if(event.type == SDL_MOUSEBUTTONUP) {
SDL_GetMouseState(&mousex, &mousey);
}
}
handleEvents();
if(postRedraw)
{
postRedraw = false;
render();
SDL_GL_SwapWindow( gWindow );
}
if((SDL_GetTicks()-lasttime)>=1000)
{
lasttime = SDL_GetTicks();
speed = frames;
logFile<<speed<<endl;
frames = 0;
} else {
frames++;
}
}
}
close();
return 0;
}
The above code is just for testing, the minimalistic code where I have problem is -
void handleEvents()
{
const Uint8* keystates = SDL_GetKeyboardState(NULL);
if(keystates[SDL_GetSancodeFromKey(SDLK_w)]) {
zpos += 0.01;
}
if(keystates[SDL_GetScancodeFromKey(SDLK_s)])
{
zpos -= 0.01;
} else {
}
}
Expected:
the trangle drawn will move forword/ backward while w/s key is pressed.
Output:
the triangle keeps on moving in the desired direction even if the key was released.
You accumulate your matrix changes over time. glTranslatef modifies current matrix with translation. The next frame it modifies it again. And again, ....
You shoud reset matrix with glLoadIdentity() call. Be aware that it modifies currently selected matrix and will undo matrix changes you've made in Initialize (at least your glTranslatef here - perspective should go to GL_PROJECTION matrix, which you haven't done).
I'm self learning programming using various online tutorials and a couple of books. Currently it's C++. I've done a bit of OpenGL and SDL in the last few days.
I have a small program that creates a wall to stop a small square from passing through it.
Here's my code:
//
// main.cpp
// SDL_Template
//
// The headers
#include <stdlib.h>
#include <string>
// SDL headers
#include <SDL/SDL.h>
#include "SDL_image/SDL_image.h"
//#include "SDL/SDL_ttf.h"
//#include "SDL/SDL_mixer.h"
// Other headers
#include <OpenGL/gl3.h>
// Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
// The frame rate
const int FRAMES_PER_SECOND = 20;
// The attributes of the square
const int SQUARE_WIDTH = 20;
const int SQUARE_HEIGHT = 20;
// The surfaces
SDL_Surface *square = NULL;
SDL_Surface *screen = NULL;
// The event structure
SDL_Event event;
// The wall
SDL_Rect wall;
// The square
class Square
{
private:
// The collision box of the square
SDL_Rect box;
// The velocity of the square
int xVel, yVel;
public:
// Initializes the variables
Square();
// Takes key presses and adjusts the square's velocity
void handle_input();
// Moves the square
void move();
// Shows the square on the screen
void show();
};
//The timer
class Timer
{
private:
// The clock time when the timer started
int startTicks;
// The ticks stored when the timer was paused
int pausedTicks;
// The timer status
bool paused;
bool started;
public:
// Initializes variables
Timer();
// The various clock actions
void start();
void stop();
void pause();
void unpause();
// Gets the timer's time
int get_ticks();
// Checks the status of the timer
bool is_started();
bool is_paused();
};
SDL_Surface *load_image(std::string filename)
{
// The image that's loaded
SDL_Surface* loadedImage = NULL;
// The optimized surface that will be used
SDL_Surface* optimizedImage = NULL;
// Load the image
loadedImage = IMG_Load(filename.c_str());
// If the image loaded
if (loadedImage != NULL)
{
// Create an optimized surface
optimizedImage = SDL_DisplayFormat(loadedImage);
// Free the old surface
SDL_FreeSurface(loadedImage);
// If the surface was optimized
if (optimizedImage != NULL)
{
// Color key surface
SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB(optimizedImage->format, 0, 0xFF, 0xFF));
}
}
// Return the optimized surface
return optimizedImage;
}
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
// Holds offsets
SDL_Rect offset;
// Get offsets
offset.x = x;
offset.y = y;
// Blit
SDL_BlitSurface(source, clip, destination, &offset);
}
bool check_collision(SDL_Rect A, SDL_Rect B)
{
// The sides of the rectangles
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;
// Calculate the sides of rect A
leftA = A.x;
rightA = A.x + A.w;
topA = A.y;
bottomA = A.y + A.h;
// Calculate the sides of rect B
leftB = B.x;
rightB = B.x + B.w;
topB = B.y;
bottomB = B.y + B.h;
// If any of the sides from A are outside of B
if( bottomA <= topB )
{
return false;
}
if( topA >= bottomB )
{
return false;
}
if( rightA <= leftB )
{
return false;
}
if( leftA >= rightB )
{
return false;
}
// If none of the sides from A are outside B
return true;
}
bool init()
{
// Initialize all SDL subsystems
if (SDL_Init( SDL_INIT_EVERYTHING ) == -1)
{
return false;
}
// Set up the screen
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
// If there was an error in setting up the screen
if (screen == NULL)
{
return false;
}
// Set the window caption
SDL_WM_SetCaption("Move the Square", NULL);
// If everything initialized fine
return true;
}
bool load_files()
{
// Load the square image
square = load_image("square.bmp");
// If there was a problem in loading the square
if (square == NULL)
{
return false;
}
// If everything loaded fine
return true;
}
void clean_up()
{
// Free the surface
SDL_FreeSurface(square);
// Quit SDL
SDL_Quit();
}
Square::Square()
{
// Initialize the offsets
box.x = 0;
box.y = 0;
// Set the square's dimentions
box.w = SQUARE_WIDTH;
box.h = SQUARE_HEIGHT;
// Initialize the velocity
xVel = 0;
yVel = 0;
}
void Square::handle_input()
{
// If a key was pressed
if (event.type == SDL_KEYDOWN)
{
//Adjust the velocity
switch (event.key.keysym.sym)
{
case SDLK_UP: yVel -= SQUARE_HEIGHT / 2; break;
case SDLK_DOWN: yVel += SQUARE_HEIGHT / 2; break;
case SDLK_LEFT: xVel -= SQUARE_WIDTH / 2; break;
case SDLK_RIGHT: xVel += SQUARE_WIDTH / 2; break;
}
}
// If a key was released
else if (event.type == SDL_KEYUP)
{
//Adjust the velocity
switch (event.key.keysym.sym)
{
case SDLK_UP: yVel += SQUARE_HEIGHT / 2; break;
case SDLK_DOWN: yVel -= SQUARE_HEIGHT / 2; break;
case SDLK_LEFT: xVel += SQUARE_WIDTH / 2; break;
case SDLK_RIGHT: xVel -= SQUARE_WIDTH / 2; break;
}
}
}
void Square::move()
{
// Move the square left or right
box.x += xVel;
// If the square went too far to the left or right or has collided with the wall
if (( box.x < 0 ) || ( box.x + SQUARE_WIDTH > SCREEN_WIDTH ) || ( check_collision(box, wall)))
{
// Move back
box.x -= xVel;
}
// Move the square up or down
box.y += yVel;
// If the square went too far up or down or has collided with the wall
if (( box.y < 0 ) || ( box.y + SQUARE_HEIGHT > SCREEN_HEIGHT) || (check_collision(box, wall)))
{
// Move back
box.y -= yVel;
}
}
void Square::show()
{
// Show the square
apply_surface(box.x, box.y, square, screen);
}
Timer::Timer()
{
// Initialize the variables
startTicks = 0;
pausedTicks = 0;
paused = false;
started = false;
}
void Timer::start()
{
// Start the timer
started = true;
// Unpause the timer
paused = false;
// Get the current clock time
startTicks = SDL_GetTicks();
}
void Timer::stop()
{
// Stop the timer
started = false;
// Unpause the timer
paused = false;
}
void Timer::pause()
{
// If the timer is running and isn't already paused
if ((started == true) && (paused == false))
{
// Pause the timer
paused = true;
// Calculate the paused ticks
pausedTicks = SDL_GetTicks() - startTicks;
}
}
void Timer::unpause()
{
// If the timer is paused
if (paused == true)
{
// Unpause the timer
paused = false;
// Reset the starting ticks
startTicks = SDL_GetTicks() - pausedTicks;
// Reset the paused ticks
pausedTicks = 0;
}
}
int Timer::get_ticks()
{
// If the timer is running
if (started == true)
{
// If the timer is paused
if (paused == true)
{
// Return the number of ticks when the timer was paused
return pausedTicks;
}
else
{
// Return the current time minus the start time
return SDL_GetTicks() - startTicks;
}
}
// If the timer isn't running
return 0;
}
bool Timer::is_started()
{
return started;
}
bool Timer::is_paused()
{
return paused;
}
int main(int argc, char* args[])
{
// Quit flag
bool quit = false;
// The square
Square mySquare;
// The frame rate regulator
Timer fps;
// Initialize
if( init() == false )
{
return 1;
}
// Load the files
if (load_files() == false)
{
return 1;
}
// Set the wall
wall.x = 300;
wall.y = 40;
wall.w = 40;
wall.h = 400;
// While the user hasn't quit
while (quit == false)
{
// Start the frame timer
fps.start();
// While there are events to handle
while (SDL_PollEvent(&event))
{
// Handle events for the square
mySquare.handle_input();
// If the user has Xed out the window
if (event.type == SDL_QUIT)
{
// Quit the program
quit = true;
}
}
// Move the square
mySquare.move();
// Fill the screen white
SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));
// Show the wall
SDL_FillRect (screen, &wall, SDL_MapRGB(screen->format, 0x77, 0x77, 0x77));
// Show the square on the screen
mySquare.show();
// Update the screen
if (SDL_Flip(screen) == -1)
{
return 1;
}
// Cap the frame rate
if (fps.get_ticks() < 1000 / FRAMES_PER_SECOND)
{
SDL_Delay((1000 / FRAMES_PER_SECOND) - fps.get_ticks());
}
}
// Clean up
clean_up();
return 0;
}
I completely understand how this site works, so I'm not asking you to check my code. My code compiles in both Xcode 4.5 and Visual Studio 2010. In Xcode it compiles, but throws some warnings up (although it still builds), but nothing happens when it's run. However in Visual Studio 2012, it compiles, with no warnings and runs successfully.
I have searched here and the C++/SDL forums/help pages, but I haven't found any similar cases.
Why may this be? Seems it runs in Visual Studio 2010, I'm confident it isn't the code...
In case you were wondering the warnings flagged up in Xcode are:
229 enumeration values not handled in switch: 'SDLK_UNKNOWN','SDLK_BACKSPACE','SDLK_TAB'...
This is highlighted on the switch (event.key.keysym.sym) line of code.
So my questions are:
What kind of problems could case this warning error?
Are there any commonly know issues with programs working in Visual Studio and not Xcode?
I'm guessing (it seems I can't find anything about it) it's a setting somewhere that I haven't spotted...
I apologise for the length of this.
You are not handling all the possible choices in your switch statement. If this is what you intended then you can remove the warning by using the default case like the following:
switch (event.key.keysym.sym)
{
case SDLK_UP: yVel -= SQUARE_HEIGHT / 2; break;
case SDLK_DOWN: yVel += SQUARE_HEIGHT / 2; break;
case SDLK_LEFT: xVel -= SQUARE_WIDTH / 2; break;
case SDLK_RIGHT: xVel += SQUARE_WIDTH / 2; break;
default: break;
}
Xcode is simply warning you that you are not handling all possible values for the event.key.keysym.sym enumeration. Since I doubt you want to handle ever single different type of key press, this isn't a problem, as I would maybe see if I could turn down the warning level to suppress these warnings.
As for the program not running successfully when built by Xcode, I don't know. Perhaps SDL is set up in a different way?
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.
I'm getting some strange behaviour with the mouse position in SDL. If I re-size the window bigger, the x,y positions from either mouse events, seem to be restricted to the original window Width and Height.
If there some function call that I'm missing to tell SDL that the mousing area has increased in size.
The relevant parts of the app:
void Resize(int width, int height)
{
WindowWidth = width;
WindowHeight = height;
/* update OpenGL */
}
void Init()
{
glClearColor(0.f, 0.f, 0.f, 1.f);
Resize(WindowWidth, WindowHeight);
}
void MouseClick(int button, int state, int x, int y)
{
unsigned int MouseButton = unsigned(Mouse.z);
unsigned int b = (1 << (button-1));
if (state)
MouseButton = MouseButton | b;
else
MouseButton = MouseButton & (~b);
Mouse.z = MouseButton;
Mouse.x = x;
Mouse.y = y;
}
void MouseMove(int x, int y)
{
MouseRel.x = x - Mouse.x;
MouseRel.y = y - Mouse.y;
Mouse.x = x;
Mouse.y = y;
}
int main(int agrc, char *argv[])
{
bool quit = false;
SDL_Event event;
if ( SDL_Init(SDL_INIT_VIDEO) < 0)
return 1;
if (SDL_SetVideoMode(WindowWidth, WindowHeight, 0, SDL_OPENGL | SDL_RESIZABLE) == NULL)
return 2;
Init();
while (!quit)
{
DrawScene();
while ( SDL_PollEvent(&event) )
{
if ( event.type == SDL_VIDEORESIZE)
{
Resize(event.resize.w, event.resize.h);
}
else if ( event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP )
{
MouseClick(event.button.button, event.button.state, event.button.x, WindowHeight - event.button.y);
printf("event.button (%i, %i)\n", event.button.x, event.button.y);
MouseHandler();
}
else if ( event.type == SDL_MOUSEMOTION )
{
MouseMove(event.motion.x, WindowHeight - event.motion.y);
printf("event.motion (%i, %i)\n", event.motion.x, event.motion.y);
MouseHandler();
}
else if (event.type == SDL_QUIT)
quit |= true;
}
quit |= KeyboardHandler();
SDL_Delay(10);
}
SDL_Quit();
return 0;
}
Try re-calling SDL_SetVideoMode() in your SDL_VIDEORESIZE handler.