我试图用两个函数展示两个不同的动画,一个渲染和两个线程。
每次运行代码时都会遇到不同类型的错误。 如:刷新功能中的分段默认(行SDL_RenderPresent(w1.renderer);)和其他奇怪的错误。每次都不同。
我知道它在两个不同的线程中使用渲染。但我不知道如何解决这个问题。
当我只使用其中一个线程运行时,一切正常。但不是他们两个。
我只是想在窗户周围播放不同的图形。 (总是使用sdl2)。
这是我的代码:
window.h中:
class Window
{
public:
SDL_Window *window1;
int background,windowWidth,windowHeight,windowXcoord,windowYcoord;
SDL_Renderer * renderer;
SDL_Renderer * renderer2;
Window();
};
void refresh();
extern Window w1;
window.cpp:
Window w1;
Window::Window()
{
window1=nullptr;
background = 0xffffff;
windowWidth=700; windowHeight=500;
windowXcoord = 650; windowYcoord = 0;
this->window1 =
SDL_CreateWindow("Window",windowXcoord,windowYcoord,
windowWidth,windowHeight, SDL_WINDOW_SHOWN);
this->renderer = SDL_CreateRenderer( this->window1, -1 ,
SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor( this->renderer, 255, 255, 255, 255 );
SDL_RenderClear( this->renderer );
SDL_RenderPresent(this->renderer);
}
// this function is called everytime an object or function want to "refresh" the window.
void refresh(){
// clearing the window
SDL_SetRenderDrawColor( w1.renderer, 255, 255, 255,0 );
SDL_RenderClear( w1.renderer );
// r1, the first Rects object to animate.
SDL_SetRenderDrawColor( w1.renderer,255,0,0,255);
SDL_RenderFillRect( w1.renderer, &r1.rect );
// r2, the second Rects.
SDL_SetRenderDrawColor( w1.renderer,255,0,255,255);
SDL_RenderFillRect( w1.renderer, &r2.rect );
SDL_RenderPresent(w1.renderer);
}
rects.h:
class Rects
{
public:
SDL_Rect rect;
Rects();
};
extern Rects r1, r2;
void moveR1();
void moveR2();
rects.cpp:
Rects::Rects()
{ }
Rects r1,r2;
// moveR1 and moveR2, (just some dumm animations-example)
void moveR1(){
r1.rect.x=400; r1.rect.y=100;
r1.rect.w =40; r1.rect.h =10;
SDL_SetRenderDrawColor( w1.renderer,255,0,0,255);
SDL_RenderFillRect( w1.renderer, &r1.rect );
{
for (int u = 1; u<=5;u++){
r1.rect.x=200; r1.rect.y=100;
r1.rect.w =50; r1.rect.h =50;
refresh();
for (int i = 1; i <=200; i++){
r1.rect.x-=1;
usleep (7000);
refresh();
}
}
}
}
void moveR2(){
r2.rect.x=200; r2.rect.y=100;
r2.rect.w =40; r2.rect.h =10;
SDL_SetRenderDrawColor( w1.renderer,255,255,0,255);
SDL_RenderFillRect( w1.renderer, &r2.rect );
{
for (int u = 1; u<=5;u++){
check
r2.rect.x=200; r2.rect.y=100;
r2.rect.w =50; r2.rect.h =50;
refresh();
for (int i = 1; i <=200; i++){
r2.rect.x+=1; r2.rect.y+=1;
usleep (7000);
refresh();
}
}
}
}
和主要:
int main()
{
thread t1(moveR1);
t1.detach();
thread t2(moveR2);
t2.detach();
// sleep instead of showing a loop.
sleep (10);
return 0;
}
欢迎任何礼貌的帮助,我在这里学习。
答案 0 :(得分:1)
当我只使用其中一个线程运行时,一切正常。但不是他们两个。
根据 2D加速渲染的documentation (也称为SDL_render.h
,换句话说,SDL_RenderPresent
所居住的地方:
此API不适用于多个线程,有关详细信息,请参阅SDL bug #1995。
你很快就无法做到这一点。通过查看错误的描述,它看起来像一个UB,并且bug的链接可能会为您提供所有细节。
我只是想在窗户周围播放不同的图形。
你不需要使用两个线程来做到这一点
您可以更新图形所需的位置,动画和任何内容,并从同一个线程中显示它们。在调用SDL_RenderCopy
之前,没有什么能阻止您多次调用相同的函数(例如SDL_RenderPresent
)。
如果你需要每个图形的一个主题,那么在视频中有数千个多边形的游戏呢?
答案 1 :(得分:0)
// thanks to skypjack, i am able to solve the problem
// HOW TO PRESENT TWO (OR MORE) GRAPHICS WITH SDL_RENDERER WITHOUT USING THREADS.
// The two rectangle animation are just and example.
// It could be whatever we want to show.
// In this case, just two rectangles moving around.
#include <unistd.h>
#include <SDL.h>
using namespace std;
SDL_Window *window1;
int background, windowWidth, windowHeight,windowXcoord,
windowYcoord;
SDL_Rect rectangle1;
SDL_Rect rectangle2;
SDL_Renderer *renderer;
int sequence1;
int sequence2;
void moveRectangle1(), moveRectangle2();
int main()
{
window1=nullptr;
background = 0xffffff;
windowWidth=700; windowHeight=500;
windowXcoord = 650; windowYcoord = 0;
window1 = SDL_CreateWindow("Main
Window",windowXcoord,windowYcoord, windowWidth,windowHeight,
SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer( window1, -1 ,
SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor( renderer, 255, 255, 255, 255 );
SDL_RenderClear( renderer );
SDL_RenderPresent(renderer);
rectangle1.x = 100; rectangle1.y = 100; rectangle1.h = 40;
rectangle1.w = 40;
rectangle2.x = 100; rectangle2.y = 100; rectangle2.h = 40;
rectangle2.w = 40;
for (int i = 1;i<500;i++){
SDL_SetRenderDrawColor( renderer, 255, 255, 255,0 );
SDL_RenderClear( renderer );
// chequear return (cerrar programa)
moveRectangle1();
moveRectangle2();
SDL_RenderPresent(renderer);
usleep (12000);
}
return 0;
}
void moveRectangle1(){
sequence1++;
if (sequence1 <= 50){ rectangle1.x++; }
else if (sequence1 <= 100){ rectangle1.x--; }
else { sequence1 = 0; }
SDL_SetRenderDrawColor(renderer,255,0,0,255);
SDL_RenderFillRect(renderer, &rectangle1 );
}
void moveRectangle2(){
sequence2++;
if (sequence2 <= 100){ rectangle2.y++; }
else if (sequence2 <= 200){ rectangle2.y--; }
else { sequence2 = 0; }
SDL_SetRenderDrawColor(renderer,0,200,0,255);
SDL_RenderFillRect( renderer, &rectangle2 );
}