How to avoid restarting the polygon when redraw? - c++

I'm writing the program that continuously draws a polygon until the user clicks right-click, but when I continue to draw something else on the screen the polygon disappears, how can I avoid this? This is my program:
float mouseX, mouseY;
vector<float> vecX(40);
vector<float> vecY(40);
int numPoints = 0;
int closed = 0;
void mouse(int button, int state, int x, int y)
{
mouseX = x;
mouseY = y;
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
if (closed || numPoints > 40)
numPoints = 0;
closed = 0;
vecX[numPoints] = mouseX;
vecY[numPoints] = mouseY;
numPoints++;
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
closed = 1;
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
if (numPoints)
{
glBegin(GL_LINE_STRIP);
for (int i = 0; i < numPoints; ++i)
glVertex2f(vecX[i], vecY[i]);
if (closed)
glVertex2f(vecX[0], vecY[0]);
else
glVertex2f(mouseX, mouseY);
glEnd();
}
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 400);
glutInitWindowPosition(0, 0);
glutCreateWindow("Testing");
gluOrtho2D(0, 600, 400, 0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
}
The vecX and vecY are used to store the coordinate of the mouse click.

Once a polyline is finished, you need to store it to a container. Use a std::vector of polylines. The type of a polyline is std::vector<float>. At the begin, just 1 empty polyline is in the container:
std::vector<std::vector<float>> polylines(1);
When you left-click, a new vertex coordinate is added to the last polyline in the container. When you right-click, a new polyline is added to the container:
void mouse(int button, int state, int x, int y)
{
mouseX = x;
mouseY = y;
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
polylines.back().push_back(mouseX);
polylines.back().push_back(mouseY);
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
polylines.push_back(std::vector<float>());
}
}
Draw the polylines in nested loops:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
for (auto i=0; i < polylines.size(); ++ i)
{
bool is_last = i == polylines.size() - 1;
const auto& polyline = polylines[i];
glBegin(is_last ? GL_LINE_STRIP : GL_LINE_LOOP);
for (auto j = 0; j < polyline.size(); j += 2)
glVertex2f(polyline[j], polyline[j+1]);
if (is_last)
glVertex2f(mouseX, mouseY);
glEnd();
}
glutSwapBuffers();
}

Related

Finish drawing a polygon by right-clicking, but displaying a menu instead

I am writing a program that will continuously draw a polygon until the user right-clicks. The user can only draw if and only if the user makes a selection in the menu, if the user does not make a selection in the menu, the program will not draw. Up to now, my program has successfully drawn a polygon with the mouse, but the problem is that when I right-click to complete, the program pops up the menu instead of completing the polygon. Now how can I right-click to be able to complete the polygon, here's my program:
const int MAX = 100;
float mouseX, mouseY, ListX[MAX], ListY[MAX];
int numPoints = 0, closed = 0, shape = 0;
void mouse(int button, int state, int x, int y)
{
mouseX = x;
mouseY = y;
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
if (closed || numPoints >= MAX - 1)
numPoints = 0;
closed = 0;
ListX[numPoints] = mouseX;
ListY[numPoints] = mouseY;
numPoints++;
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
closed = 1;
}
void motion(int x, int y)
{
mouseX = x;
mouseY = y;
glutPostRedisplay();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
if (shape == 1)
{
if (numPoints)
{
glBegin(GL_LINE_STRIP);
for (int i = 0; i < numPoints; ++i)
glVertex2f(ListX[i], ListY[i]);
if (closed)
glVertex2f(ListX[0], ListY[0]);
else
glVertex2f(mouseX, mouseY);
glEnd();
}
}
glFlush();
}
void menu(int choice)
{
switch (choice)
{
case 1:
shape = 1;
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("");
gluOrtho2D(0, 640, 480, 0);
glutCreateMenu(menu);
glutAddMenuEntry("Polygon", 1);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutPassiveMotionFunc(motion);
glutMainLoop();
}
Edit: Thanks to genpfault, I finished the polygon by right-clicking but I don't know how to reattach it so I can re-open the menu.
...
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
if (shape == 1)
{
glutDetachMenu(GLUT_RIGHT_BUTTON); // Add this
...
}
glFlush();
}
void menu(int choice)
{
switch (choice)
{
case 1:
shape = 1;
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("");
gluOrtho2D(0, 640, 480, 0);
glutCreateMenu(menu);
glutAddMenuEntry("Polygon", 1);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutPassiveMotionFunc(mouse_move);
glutMainLoop();
}
Capture the return-value from glutCreateMenu(), that's the handle for the new menu.
Detach the menu in the menu callback via glutDetachMenu() and set a bool indicating you're in "add points" mode.
If you're in "add points" mode and detect a right-click, set the current menu to the menu handle from #1 via glutSetMenu(), then re-attach the menu with glutAttachMenu(). Reset the "add points" bool to false.
All together:
#include <GL/glut.h>
const int MAX = 100;
float mouseX, mouseY, ListX[MAX], ListY[MAX];
int numPoints = 0, closed = 0, shape = 0;
int hMenu = 0;
bool addingPoints = false;
void mouse(int button, int state, int x, int y)
{
mouseX = x;
mouseY = y;
if( addingPoints )
{
if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
{
if (closed || numPoints >= MAX - 1)
numPoints = 0;
closed = 0;
ListX[numPoints] = mouseX;
ListY[numPoints] = mouseY;
numPoints++;
}
if( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
{
closed = 1;
addingPoints = false;
glutSetMenu(hMenu);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
}
}
void motion(int x, int y)
{
mouseX = x;
mouseY = y;
glutPostRedisplay();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 640, 480, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (shape == 1)
{
if (numPoints)
{
glBegin(GL_LINE_STRIP);
for (int i = 0; i < numPoints; ++i)
glVertex2f(ListX[i], ListY[i]);
if (closed)
glVertex2f(ListX[0], ListY[0]);
else
glVertex2f(mouseX, mouseY);
glEnd();
}
}
glutSwapBuffers();
}
void menu(int choice)
{
switch (choice)
{
case 1:
numPoints = 0;
shape = 1;
addingPoints = true;
glutDetachMenu(GLUT_RIGHT_BUTTON);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutCreateWindow("");
hMenu = glutCreateMenu(menu);
glutSetMenu(hMenu);
glutAddMenuEntry("Polygon", 1);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutPassiveMotionFunc(motion);
glutMainLoop();
}

Creating a array of class objects (C++) [duplicate]

This question already has answers here:
How do I use arrays in C++?
(5 answers)
Closed 7 years ago.
I have been trying to make a simulator which involves ants randomly running around (for now...) I want to make a array of "Ant" to contain all my ant information and later functions. How would I do that?? (example with my code if possible)(I know java fairly well so if you could relate it to java that would be nice
//inclusions
#include <GLUT/glut.h>
#include <OpenGL/glu.h>
#include <OpenGL/gl.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//declarations
//class declarations
void keyboard (unsigned char key, int x, int y);
void keyboardUp (unsigned char key, int x, int y);
void mouseLocation(int,int);
int onMouse;
int rightClick;
int a = 0;
int mx;
int my;
float red=1.0, blue=0, green=0;
class Ant {
int x;
int y;
int type;
Ant() { } // private default constructor
public:
Ant(int nx, int ny, int ntype)
{
x = nx;
y = ny;
type = ntype;
}
void SetX(int swagger)
{
x = swagger;
}
void SetY(int ny)
{
y = ny;
}
void SetType(int ntype)
{
type = ntype;
}
int GetX() { return x; }
int GetY() { return y; }
};
//mouse listener methods
void mouseLocation(int x,int y) {
mx = x;
my = y;
}
void mouseClicks(int button, int state, int x, int y) {
mx = x;
my = y;
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
onMouse = 1;
}
if(button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
onMouse = 0;
}
if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP) {
rightClick = 0;
}
if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
rightClick = 1;
}
}
//keylistner methods
void keyboard (unsigned char key, int x, int y)
{
if (key == 'a')
{
a = 1;
}
}
void keyboardUp (unsigned char key, int x, int y)
{
if(key == 'a')
{
a = 0;
}
}
//ant methods
int randommove(int position,int speed)
{
speed++;
int random = rand() %speed - speed/2 ;
position = position + random;
return position;
}
//drawing methods
Ant ant1(100,100,1);
Ant ant2(50,500,1);
//Here is the where I want to try the ant array something like
//Ant ants[x] and then I would fill in the values with the SetX, SetY... methods
void ant()
{
int a2 = randommove(ant1.GetX(),2);
ant1.SetX(a2);
glLineWidth(1);
glBegin(GL_LINES);
glColor4f(1, 0, 0, 1);
glVertex2i(ant1.GetX(),ant1.GetY());
glVertex2i(ant1.GetX()+5,ant1.GetY()+5);
glEnd();
}
void line1()
{
if(a == 1)
{
glLineWidth(2.5);
glBegin(GL_LINES);
glVertex2i(80,20);
glVertex2i(100,400);
glEnd();
}
}
void line2()
{
if(onMouse == 1)
{
glLineWidth(2.5);
glBegin(GL_LINES);
glVertex2i(200,20);
glVertex2i(100,400);
glEnd();
}
}
void rect1()
{
if(mx >= 50 && my >= 50)
{
int x = 100;
int y = 100;
int w = 100;
int h = 100;
unsigned int rgba = 0xff0000ff; // red, no alpha
glBegin(GL_QUADS);
glColor4f(((rgba>>24)&0xff)/255.0f,
((rgba>>16)&0xff)/255.0f,
((rgba>>8)&0xff)/255.0f,
(rgba&0xff)/255.0f);
glVertex3f(x,y,0);
glVertex3f(x+w,y,0);
glVertex3f(x+w,y+h,0);
glVertex3f(x,y+h,0);
glEnd();
glColor4f(1, 1, 1, 1);
}
}
void rect2()
{
if(rightClick == 1)
{
int w = 100;
int h = 100;
unsigned int rgba = 0xff0000ff; // red, no alpha
glBegin(GL_QUADS);
glColor4f(((rgba>>24)&0xff)/255.0f,
((rgba>>16)&0xff)/255.0f,
((rgba>>8)&0xff)/255.0f,
(rgba&0xff)/255.0f);
glVertex3f(mx,my,0);
glVertex3f(mx+w,my,0);
glVertex3f(mx+w,my+h,0);
glVertex3f(mx,my+h,0);
glEnd();
glColor4f(1, 1, 1, 1);
}
}
//render drawing methods
void renderScence(void){
glClear (GL_COLOR_BUFFER_BIT);
glColor3f(red, green, blue);
ant();
line1();
line2();
rect1();
rect2();
glFlush();
}
//graphics init method
void init(void)
{
glutInitDisplayMode(GLUT_SINGLE |GLUT_RGB);
glutInitWindowSize (500,500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Testing");
glClearColor (0, 0, 0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
}
//main/graphics calls
int main(int argc,char** argv)
{
glutInit(&argc, argv);
init();
glutDisplayFunc(renderScence);
glutIdleFunc(renderScence);
glutMouseFunc(mouseClicks);
glutPassiveMotionFunc(mouseLocation);
glutKeyboardUpFunc (keyboardUp);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
You could create the array of Ant objects inside main, and it's the same way you'd create any other array except it's of type Ant:
Ant ants[25]; // 25 Ant objects
/* to set them all the same, as an example */
for(i=0; i<25; i++)
{
ants[i].SetX(1); // x = 1
ants[i].SetY(2); // y = 2
ants[i].SetType(3); // type = 3
}

C++ declaring classes/objects for a noobie

I have recently decided to try to learn c++. My major road block so far is object/class declaration I am reasonably experienced in java but the way c++ works confuses me. Can someone please show me a example of using a object (like the one below if possible) inside one file or multiple files? here is my current code (object is not implemented).
//inclusions
#include <GLUT/glut.h>
#include <OpenGL/glu.h>
#include <OpenGL/gl.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//declarations
void keyboard (unsigned char key, int x, int y);
void keyboardUp (unsigned char key, int x, int y);
void mouseLocation(int,int);
int onMouse;
int rightClick;
int a = 0;
int mx;
int my;
float red=1.0, blue=0, green=0;
class Ant
{
private:
int x;
int y;
int speed;
Ant() { } // private default constructor
public:
Ant(int nx, int ny, int nspeed)
{
SetX(nx);
SetY(ny);
SetSpeed(nspeed);
}
void SetX(int nx)
{
x = nx;
}
void SetY(int ny)
{
y = ny;
}
void SetSpeed(int nspeed)
{
speed = nspeed;
}
int GetX() { return x; }
int GetY() { return y; }
int GetSpeed() { return speed; }
};
//mouse listener methods
void mouseLocation(int x,int y) {
mx = x;
my = y;
}
void mouseClicks(int button, int state, int x, int y) {
mx = x;
my = y;
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
onMouse = 1;
}
if(button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
onMouse = 0;
}
if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP) {
rightClick = 0;
}
if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
rightClick = 1;
}
}
//keylistner methods
void keyboard (unsigned char key, int x, int y)
{
if (key == 'a')
{
a = 1;
}
}
void keyboardUp (unsigned char key, int x, int y)
{
if(key == 'a')
{
a = 0;
}
}
//drawing methods
void line1()
{
if(a == 1)
{
glLineWidth(2.5);
glBegin(GL_LINES);
glVertex2i(20,20);
glVertex2i(100,400);
glEnd();
}
}
void line2()
{
if(onMouse == 1)
{
glLineWidth(2.5);
glBegin(GL_LINES);
glVertex2i(200,20);
glVertex2i(100,400);
glEnd();
}
}
void rect1()
{
if(mx >= 50 && my >= 50)
{
int x = 100;
int y = 100;
int w = 100;
int h = 100;
unsigned int rgba = 0xff0000ff; // red, no alpha
glBegin(GL_QUADS);
glColor4f(((rgba>>24)&0xff)/255.0f,
((rgba>>16)&0xff)/255.0f,
((rgba>>8)&0xff)/255.0f,
(rgba&0xff)/255.0f);
glVertex3f(x,y,0);
glVertex3f(x+w,y,0);
glVertex3f(x+w,y+h,0);
glVertex3f(x,y+h,0);
glEnd();
glColor4f(1, 1, 1, 1);
}
}
void rect2()
{
if(rightClick == 1)
{
int x = 100;
int y = 100;
int w = 100;
int h = 100;
unsigned int rgba = 0xff0000ff; // red, no alpha
glBegin(GL_QUADS);
glColor4f(((rgba>>24)&0xff)/255.0f,
((rgba>>16)&0xff)/255.0f,
((rgba>>8)&0xff)/255.0f,
(rgba&0xff)/255.0f);
glVertex3f(mx,my,0);
glVertex3f(mx+w,my,0);
glVertex3f(mx+w,my+h,0);
glVertex3f(mx,my+h,0);
glEnd();
glColor4f(1, 1, 1, 1);
}
}
//render drawing methods
void renderScence(void){
glClear (GL_COLOR_BUFFER_BIT);
glColor3f(red, green, blue);
line1();
line2();
rect1();
rect2();
glFlush();
}
//graphics init method
void init(void)
{
glutInitDisplayMode(GLUT_SINGLE |GLUT_RGB);
glutInitWindowSize (500,500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Testing");
glClearColor (0, 0, 0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
}
//main/graphics calls
int main(int argc,char** argv)
{
glutInit(&argc, argv);
init();
glutDisplayFunc(renderScence);
glutIdleFunc(renderScence);
glutMouseFunc(mouseClicks);
glutPassiveMotionFunc(mouseLocation);
glutKeyboardUpFunc (keyboardUp);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
Your class definition is correct (although a bit Javaish). You can create and use an object of type Ant like this:
Ant a(3, 7, 82);
a.SetSpeed(42);
int speed = a.GetSpeed();

SFML sprite std::list

I have some SFML 2.0 code, where I draw a robot which moves in a grid. Grid is drawn using OpenGL, the robot image is loaded using sf::Texture. I have some code that makes walls on user left mouse click (no collision detection). I made a function which erases them on right click.
Walls are stored in sf::Sprite, then put into std::list and drawn in a loop. When I call list.erase() program segfaults. Debugger shows some problem in sf::transformable = operator.
How to fix that.
Here is the code:
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>
#include <list>
using namespace std;
static const size_t WIN_HEIGHT=800, WIN_WIDTH=800;
void drawGrid();
void fixCoords(int & x, int & y);
static list<sf::Sprite> walls;
int main()
{
// Create the main window
sf::RenderWindow window(sf::VideoMode(WIN_WIDTH, WIN_HEIGHT), "SFML window");
/*** Robot code ***/
sf::Image robotImg;
robotImg.loadFromFile("robot.png");
robotImg.createMaskFromColor(sf::Color(89, 167, 45));
sf::Texture robotTexture;
robotTexture.loadFromImage(robotImg);
sf::Sprite robotSpr(robotTexture);
sf::Sprite t;
robotSpr.setPosition(sf::Vector2f(400, 405));
/***** Wall code ****/
int x = 0, y = 0;
sf::Image wallimg;
wallimg.loadFromFile("wall.png");
wallimg.createMaskFromColor(sf::Color(255, 0, 255));
sf::Texture walltex;
walltex.loadFromImage(wallimg);
sf::Sprite wall;
wall.setTexture(walltex);
int movex = 0, movey = 0;
gluOrtho2D(0, WIN_WIDTH, 0, WIN_HEIGHT);
while (window.isOpen())
{
// Process events
sf::Event event;
while (window.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
{
window.close();
return 0;
}
if (event.type == sf::Event::MouseButtonPressed )
{
if(event.mouseButton.button == sf::Mouse::Left)
{
x = event.mouseButton.x;
y = event.mouseButton.y;
fixCoords(x, y);
wall.setPosition(sf::Vector2f(x, y));
walls.push_back(wall);
}
if(event.mouseButton.button == sf::Mouse::Right)
{
x = event.mouseButton.x;
y = event.mouseButton.y;
fixCoords(x, y);
for(list<sf::Sprite>::iterator it = walls.begin(); it != walls.end(); it++)
{
if((it->getPosition().x == x) && (it->getPosition().y == y)) // This line
walls.erase(it);
}
}
}
if(event.type == sf::Event::KeyPressed)
{
if((movex == 0) && (movey == 0))
{
if(event.key.code == sf::Keyboard::Up)
movey -= 37;
if(event.key.code == sf::Keyboard::Down)
movey += 37;
if(event.key.code == sf::Keyboard::Left)
movex -= 40;
if(event.key.code == sf::Keyboard::Right)
movex += 40;
}
}
}
window.pushGLStates();
window.clear(sf::Color(90, 167, 45));
// Insert SFML Draws here
if(movex > 0)
{
robotSpr.move(1, 0);
movex--;
}
if(movex < 0)
{
robotSpr.move(-1, 0);
movex++;
}
if(movey > 0)
{
robotSpr.move(0, 1);
movey--;
}
if(movey < 0)
{
robotSpr.move(0, -1);
movey++;
}
window.draw(robotSpr);
if((x != 0) && (y != 0))
{
for(list<sf::Sprite>::iterator it = walls.begin(); it != walls.end(); it++)
window.draw(*it);
}
window.popGLStates();
// OpenGL Here
drawGrid();
// Update the window
window.display();
}
}
void drawGrid()
{
glColor3ub(0, 0, 0);
glBegin(GL_LINES); // Horizontal lines
for(int i = 0; i < WIN_HEIGHT; i += WIN_HEIGHT / 20)
{
glVertex2i(0, i);
glVertex2i(WIN_WIDTH, i);
}
glEnd();
glColor3ub(0, 0, 0);
glBegin(GL_LINES); // Vertical lines
for(int i = 0; i < WIN_WIDTH; i += WIN_WIDTH / 20)
{
glVertex2i(i, 0);
glVertex2i(i, WIN_HEIGHT);
}
glEnd();
}
void fixCoords(int &x, int &y)
{
/**** Find the nearest x sqare ****/
for(int i = 1; i < WIN_WIDTH - 1; i += 40)
{
if((x >= i) && x <= (i + 40))
{
x = i - 1;
break;
}
}
for(int i = WIN_HEIGHT; i > 0; i -= 40)
{
if((y >= i) && y <= (i + 40))
{
y = i;
break;
}
}
}
This is an annoyance of the way the list<T> container works.
A list<T> container is implemented as a doubly linked list. So an iterator needs to access its current element to get to the next element. If you have just erased its current element, everything explodes.
You can make it work like this:
list<sf::Sprite>::iterator it=walls.begin(),next;
while(it!=walls.end()) {
next = it; next++;
if((it->getPosition().x == x) && (it->getPosition().y == y))
walls.erase(it);
it = next;
}
you could also use remove_if with an appropriate predicate class, but that would just be uglier and more convoluted.

SDL Mouse position Cropped after resize

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.