在两个不同的线程中使用 SDL2-render 显示两个或多个不同的动画(解决方案中没有线程)。 C++

Posted

技术标签:

【中文标题】在两个不同的线程中使用 SDL2-render 显示两个或多个不同的动画(解决方案中没有线程)。 C++【英文标题】:Showing two or more different animation with SDL2-render in two different threads (no threads in the solution). C++ 【发布时间】:2017-09-15 01:47:43 【问题描述】:

我试图展示由两个函数、一个渲染和两个线程制作的两个不同的动画。

每次运行代码时都会遇到不同类型的错误。 如:刷新函数中的分段默认(line 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; 

欢迎任何礼貌的帮助,我在这里学习。

【问题讨论】:

【参考方案1】:

当我只使用其中一个线程运行时,一切正常。但不是他们两个。

根据documentation 用于2D 加速渲染(也称为SDL_render.h,换句话说就是SDL_RenderPresent 所在的地方):

此 API 不适用于多线程,请参阅SDL bug #1995 了解详情。

您将无法很快做到这一点。通过查看错误的描述,它看起来像一个 UB,并且该错误的链接可能会为您提供所有详细信息。

我只想在窗口周围显示不同的图形。

您不需要使用两个线程来执行此操作。 您可以只更新位置、动画以及图形所需的任何内容,并从同一个线程中显示它们。没有什么能阻止您在调用 SDL_RenderPresent 之前多次调用相同的函数(例如 SDL_RenderCopy)。 如果每个图形都需要一个线程,那么视频中包含数千个多边形的游戏呢?

【讨论】:

好吧!我明白了,我会尝试不使用线程。谢谢skypjack。 skypjack,我发布了一个答案,其中的解决方案受到了您教给我的启发。再次感谢。【参考方案2】:
// 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 );

【讨论】:

以上是关于在两个不同的线程中使用 SDL2-render 显示两个或多个不同的动画(解决方案中没有线程)。 C++的主要内容,如果未能解决你的问题,请参考以下文章

在不使用显式锁的方式下使用多线程

c++ 互斥锁必须使用在同一个线程当中 不能lock和 unlock两个操作分别在不同线程中

c++ 互斥锁必须使用在同一个线程当中 不能lock和 unlock两个操作分别在不同线程中

Qt - 一个简单的回显服务器

ref的使用

分布式锁原理初探