SDL_Rect 大于指定值
SDL_Rect is larger than specified
我在 SDL_Rect 中遇到了一个奇怪的错误。每当我用这个矩形调用 SDL_RenderFillRect 时:
SDL_Rect rect = {100, 100, 100, 100};
我总是以矩形覆盖整个 800 x 600 window。
这是我的程序:
#include "SDL.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <thread>
#include <string>
class Window
{
public:
Window( std::string title, int width, int height );
void runEvents( SDL_Event event );
void drawRect( int x, int y, int h, int w );
bool closed = false;
SDL_Renderer *_renderer;
SDL_Window *_window;
private:
int colour = 0;
};
Window::Window( std::string title, int width, int height )
{
_window = SDL_CreateWindow( title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0 );
_renderer = SDL_CreateRenderer( _window, -1, 0 );
}
// this function deals with rects (it's supposed to draw a rect when the mouse button is down):
void Window::runEvents( SDL_Event event )
{
SDL_Rect rect = { 100, 100, 100, 100 };
switch( event.type )
{
case SDL_QUIT:
closed = true;
break;
case SDL_KEYDOWN:
switch( event.key.keysym.sym )
{
case SDLK_ESCAPE:
closed = true;
break;
case SDLK_KP_1:
// set colour to blue
SDL_SetRenderDrawColor( _renderer, 0, 51, 204, 255 );
std::cout << "Colour set to blue!" << std::endl;
colour = 1;
break;
case SDLK_KP_2:
// set colour to red
SDL_SetRenderDrawColor( _renderer, 255, 0, 0, 255 );
std::cout << "Colour set to red!" << std::endl;
colour = 2;
break;
case SDLK_KP_3:
// set colour to green
SDL_SetRenderDrawColor( _renderer, 51, 204, 51, 255 );
std::cout << "Colour set to green!" << std::endl;
colour = 3;
break;
case SDLK_KP_4:
SDL_SetRenderDrawColor( _renderer, 153, 0, 153, 255 );
std::cout << "Colour set to purple!" << std::endl;
colour = 4;
break;
case SDLK_KP_0:
SDL_SetRenderDrawColor( _renderer, 255, 255, 255, 255 );
std::cout << "Colour set to white!" << std::endl;
colour = 0;
break;
}
break;
//this draws the rectangle:
case SDL_MOUSEBUTTONDOWN:
SDL_SetRenderDrawColor( _renderer, 255, 0, 0, 255 );
drawRect( rect.h, rect.y, rect.h, rect.w );
break;
//this removes it
case SDL_MOUSEBUTTONUP:
switch( colour )
{
case 1:
SDL_SetRenderDrawColor( _renderer, 0, 51, 204, 255 );
break;
case 2:
SDL_SetRenderDrawColor( _renderer, 255, 0, 0, 255 );
break;
case 3:
SDL_SetRenderDrawColor( _renderer, 51, 204, 51, 255 );
break;
case 4:
SDL_SetRenderDrawColor( _renderer, 153, 0, 153, 255 );
break;
case 0:
SDL_SetRenderDrawColor( _renderer, 255, 255, 255, 255 );
break;
}
drawRect( rect.h, rect.y, rect.h, rect.w );
break;
}
}
//this function is supposed to draw the rect
void Window::drawRect( int x, int y, int h, int w )
{
SDL_Rect rect = { x, y, w, h };
SDL_RenderFillRect( _renderer, &rect );
}
bool running = true;
void mouseCheck()
{
while( running )
{
int x;
int y;
SDL_GetMouseState( &x, &y );
printf( "Mouse is at x: %i and y: %i\n", x, y );
SDL_Delay( 5000 );
}
}
int main( int argc, char *argv[] )
{
SDL_Init( SDL_INIT_EVERYTHING );
Window window( "Hello World", 800, 600 );
SDL_Event event;
SDL_SetRenderDrawColor( window._renderer, 255, 255, 255, 255 );
std::thread mousePosition( mouseCheck );
mousePosition.detach();
while( !window.closed )
{
SDL_RenderClear( window._renderer );
SDL_RenderPresent( window._renderer );
if( SDL_PollEvent( &event ) )
{
window.runEvents( event );
}
}
return 0;
}
多个问题:
现在你的主要绘制循环是:
1. Draw
2. Clear
3. Present
你想要:
1. (re)Set clear color
2. Clear
3. Draw
4. Present
不确定您要用那个 mouseCheck()
线程做什么,但要避免从其他线程调用与 GUI 相关的 SDL 函数。如果您需要在另一个线程中使用该信息,请使用线程安全 atomics/queues/messages 进行通信。
您在两个地方调用 drawRect()
,第一个参数是 rect.h
而不是 rect.x
。
我建议不要像您在 runEvents()
中那样交错输入处理和渲染。在清空事件队列 (while(SDL_PollEvent())
) 的同时更新系统状态 (shouldDrawRect
& colour
),然后使用新状态 (Window::drawScene()
) 绘制帧。
您每帧只处理一个事件。通过 while(SDL_PollEvent())
清空每一帧的事件队列,这样事件就不会被备份和丢弃。
总计:
#include "SDL.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <thread>
#include <string>
class Window
{
public:
Window( std::string title, int width, int height );
void runEvents( SDL_Event event );
void drawScene();
void drawRect( int x, int y, int h, int w );
bool closed = false;
SDL_Renderer *_renderer;
SDL_Window *_window;
private:
bool shouldDrawRect;
int colour = 0;
};
Window::Window( std::string title, int width, int height )
{
_window = SDL_CreateWindow( title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0 );
_renderer = SDL_CreateRenderer( _window, -1, 0 );
shouldDrawRect = false;
}
void Window::drawScene()
{
if( shouldDrawRect )
{
switch( colour )
{
case 0:
SDL_SetRenderDrawColor( _renderer, 255, 0, 0, 255 );
break;
case 1:
SDL_SetRenderDrawColor( _renderer, 0, 51, 204, 255 );
break;
case 2:
SDL_SetRenderDrawColor( _renderer, 255, 0, 0, 255 );
break;
case 3:
SDL_SetRenderDrawColor( _renderer, 51, 204, 51, 255 );
break;
case 4:
SDL_SetRenderDrawColor( _renderer, 153, 0, 153, 255 );
break;
}
SDL_Rect rect = { 100, 100, 100, 100 };
drawRect( rect.x, rect.y, rect.h, rect.w );
}
}
//this function deals with rects (it's supposed to draw a rect when the mouse button is down):
void Window::runEvents( SDL_Event event )
{
switch( event.type )
{
case SDL_QUIT:
closed = true;
break;
case SDL_KEYDOWN:
switch( event.key.keysym.sym )
{
case SDLK_ESCAPE:
closed = true;
break;
case SDLK_KP_1:
// set colour to blue
std::cout << "Colour set to blue!" << std::endl;
colour = 1;
break;
case SDLK_KP_2:
// set colour to red
std::cout << "Colour set to red!" << std::endl;
colour = 2;
break;
case SDLK_KP_3:
// set colour to green
std::cout << "Colour set to green!" << std::endl;
colour = 3;
break;
case SDLK_KP_4:
std::cout << "Colour set to purple!" << std::endl;
colour = 4;
break;
case SDLK_KP_0:
std::cout << "Colour set to white!" << std::endl;
colour = 0;
break;
}
break;
//this draws the rectangle:
case SDL_MOUSEBUTTONDOWN:
shouldDrawRect = true;
break;
//this removes it
case SDL_MOUSEBUTTONUP:
shouldDrawRect = false;
break;
}
}
//this function is supposed to draw the rect
void Window::drawRect( int x, int y, int h, int w )
{
SDL_Rect rect = { x, y, w, h };
SDL_RenderFillRect( _renderer, &rect );
}
bool running = true;
int main( int argc, char *argv[] )
{
SDL_Init( SDL_INIT_EVERYTHING );
Window window( "Hello World", 800, 600 );
SDL_Event event;
while( !window.closed )
{
SDL_SetRenderDrawColor( window._renderer, 255, 255, 255, 255 );
SDL_RenderClear( window._renderer );
while( SDL_PollEvent( &event ) )
{
window.runEvents( event );
}
window.drawScene();
SDL_RenderPresent( window._renderer );
}
return 0;
}
我在 SDL_Rect 中遇到了一个奇怪的错误。每当我用这个矩形调用 SDL_RenderFillRect 时:
SDL_Rect rect = {100, 100, 100, 100};
我总是以矩形覆盖整个 800 x 600 window。
这是我的程序:
#include "SDL.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <thread>
#include <string>
class Window
{
public:
Window( std::string title, int width, int height );
void runEvents( SDL_Event event );
void drawRect( int x, int y, int h, int w );
bool closed = false;
SDL_Renderer *_renderer;
SDL_Window *_window;
private:
int colour = 0;
};
Window::Window( std::string title, int width, int height )
{
_window = SDL_CreateWindow( title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0 );
_renderer = SDL_CreateRenderer( _window, -1, 0 );
}
// this function deals with rects (it's supposed to draw a rect when the mouse button is down):
void Window::runEvents( SDL_Event event )
{
SDL_Rect rect = { 100, 100, 100, 100 };
switch( event.type )
{
case SDL_QUIT:
closed = true;
break;
case SDL_KEYDOWN:
switch( event.key.keysym.sym )
{
case SDLK_ESCAPE:
closed = true;
break;
case SDLK_KP_1:
// set colour to blue
SDL_SetRenderDrawColor( _renderer, 0, 51, 204, 255 );
std::cout << "Colour set to blue!" << std::endl;
colour = 1;
break;
case SDLK_KP_2:
// set colour to red
SDL_SetRenderDrawColor( _renderer, 255, 0, 0, 255 );
std::cout << "Colour set to red!" << std::endl;
colour = 2;
break;
case SDLK_KP_3:
// set colour to green
SDL_SetRenderDrawColor( _renderer, 51, 204, 51, 255 );
std::cout << "Colour set to green!" << std::endl;
colour = 3;
break;
case SDLK_KP_4:
SDL_SetRenderDrawColor( _renderer, 153, 0, 153, 255 );
std::cout << "Colour set to purple!" << std::endl;
colour = 4;
break;
case SDLK_KP_0:
SDL_SetRenderDrawColor( _renderer, 255, 255, 255, 255 );
std::cout << "Colour set to white!" << std::endl;
colour = 0;
break;
}
break;
//this draws the rectangle:
case SDL_MOUSEBUTTONDOWN:
SDL_SetRenderDrawColor( _renderer, 255, 0, 0, 255 );
drawRect( rect.h, rect.y, rect.h, rect.w );
break;
//this removes it
case SDL_MOUSEBUTTONUP:
switch( colour )
{
case 1:
SDL_SetRenderDrawColor( _renderer, 0, 51, 204, 255 );
break;
case 2:
SDL_SetRenderDrawColor( _renderer, 255, 0, 0, 255 );
break;
case 3:
SDL_SetRenderDrawColor( _renderer, 51, 204, 51, 255 );
break;
case 4:
SDL_SetRenderDrawColor( _renderer, 153, 0, 153, 255 );
break;
case 0:
SDL_SetRenderDrawColor( _renderer, 255, 255, 255, 255 );
break;
}
drawRect( rect.h, rect.y, rect.h, rect.w );
break;
}
}
//this function is supposed to draw the rect
void Window::drawRect( int x, int y, int h, int w )
{
SDL_Rect rect = { x, y, w, h };
SDL_RenderFillRect( _renderer, &rect );
}
bool running = true;
void mouseCheck()
{
while( running )
{
int x;
int y;
SDL_GetMouseState( &x, &y );
printf( "Mouse is at x: %i and y: %i\n", x, y );
SDL_Delay( 5000 );
}
}
int main( int argc, char *argv[] )
{
SDL_Init( SDL_INIT_EVERYTHING );
Window window( "Hello World", 800, 600 );
SDL_Event event;
SDL_SetRenderDrawColor( window._renderer, 255, 255, 255, 255 );
std::thread mousePosition( mouseCheck );
mousePosition.detach();
while( !window.closed )
{
SDL_RenderClear( window._renderer );
SDL_RenderPresent( window._renderer );
if( SDL_PollEvent( &event ) )
{
window.runEvents( event );
}
}
return 0;
}
多个问题:
现在你的主要绘制循环是:
1. Draw 2. Clear 3. Present
你想要:
1. (re)Set clear color 2. Clear 3. Draw 4. Present
不确定您要用那个
mouseCheck()
线程做什么,但要避免从其他线程调用与 GUI 相关的 SDL 函数。如果您需要在另一个线程中使用该信息,请使用线程安全 atomics/queues/messages 进行通信。您在两个地方调用
drawRect()
,第一个参数是rect.h
而不是rect.x
。我建议不要像您在
runEvents()
中那样交错输入处理和渲染。在清空事件队列 (while(SDL_PollEvent())
) 的同时更新系统状态 (shouldDrawRect
&colour
),然后使用新状态 (Window::drawScene()
) 绘制帧。您每帧只处理一个事件。通过
while(SDL_PollEvent())
清空每一帧的事件队列,这样事件就不会被备份和丢弃。
总计:
#include "SDL.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <thread>
#include <string>
class Window
{
public:
Window( std::string title, int width, int height );
void runEvents( SDL_Event event );
void drawScene();
void drawRect( int x, int y, int h, int w );
bool closed = false;
SDL_Renderer *_renderer;
SDL_Window *_window;
private:
bool shouldDrawRect;
int colour = 0;
};
Window::Window( std::string title, int width, int height )
{
_window = SDL_CreateWindow( title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0 );
_renderer = SDL_CreateRenderer( _window, -1, 0 );
shouldDrawRect = false;
}
void Window::drawScene()
{
if( shouldDrawRect )
{
switch( colour )
{
case 0:
SDL_SetRenderDrawColor( _renderer, 255, 0, 0, 255 );
break;
case 1:
SDL_SetRenderDrawColor( _renderer, 0, 51, 204, 255 );
break;
case 2:
SDL_SetRenderDrawColor( _renderer, 255, 0, 0, 255 );
break;
case 3:
SDL_SetRenderDrawColor( _renderer, 51, 204, 51, 255 );
break;
case 4:
SDL_SetRenderDrawColor( _renderer, 153, 0, 153, 255 );
break;
}
SDL_Rect rect = { 100, 100, 100, 100 };
drawRect( rect.x, rect.y, rect.h, rect.w );
}
}
//this function deals with rects (it's supposed to draw a rect when the mouse button is down):
void Window::runEvents( SDL_Event event )
{
switch( event.type )
{
case SDL_QUIT:
closed = true;
break;
case SDL_KEYDOWN:
switch( event.key.keysym.sym )
{
case SDLK_ESCAPE:
closed = true;
break;
case SDLK_KP_1:
// set colour to blue
std::cout << "Colour set to blue!" << std::endl;
colour = 1;
break;
case SDLK_KP_2:
// set colour to red
std::cout << "Colour set to red!" << std::endl;
colour = 2;
break;
case SDLK_KP_3:
// set colour to green
std::cout << "Colour set to green!" << std::endl;
colour = 3;
break;
case SDLK_KP_4:
std::cout << "Colour set to purple!" << std::endl;
colour = 4;
break;
case SDLK_KP_0:
std::cout << "Colour set to white!" << std::endl;
colour = 0;
break;
}
break;
//this draws the rectangle:
case SDL_MOUSEBUTTONDOWN:
shouldDrawRect = true;
break;
//this removes it
case SDL_MOUSEBUTTONUP:
shouldDrawRect = false;
break;
}
}
//this function is supposed to draw the rect
void Window::drawRect( int x, int y, int h, int w )
{
SDL_Rect rect = { x, y, w, h };
SDL_RenderFillRect( _renderer, &rect );
}
bool running = true;
int main( int argc, char *argv[] )
{
SDL_Init( SDL_INIT_EVERYTHING );
Window window( "Hello World", 800, 600 );
SDL_Event event;
while( !window.closed )
{
SDL_SetRenderDrawColor( window._renderer, 255, 255, 255, 255 );
SDL_RenderClear( window._renderer );
while( SDL_PollEvent( &event ) )
{
window.runEvents( event );
}
window.drawScene();
SDL_RenderPresent( window._renderer );
}
return 0;
}