Pablo Lopez
Pablo Lopez

Reputation: 67

Showing two or more different animation with SDL2-render in two different threads (no threads in the solution). C++

im trying to show two different animations made with two functions, one render and two threads.

Im getting different kind of error each time i run the code. Such as: segmentation default in the refresh function (line SDL_RenderPresent(w1.renderer);) and other strange errors too. Everytime is different.

I know its about using the render in both different threads. But i dont know how to solve this problem.

When i run with just one of the threads everything its ok. But not with the two of them.

I just want to show different graphics playing around the window. (always using sdl2).

Here is my code:

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();
              }
        }
  }
}

and the main:

int main()
{
  thread t1(moveR1);
  t1.detach();

  thread t2(moveR2);
  t2.detach();

  // sleep instead of showing a loop.

  sleep (10);

  return 0; 
}

any polite help is welcome, im here to learn.

Upvotes: 1

Views: 293

Answers (2)

Pablo Lopez
Pablo Lopez

Reputation: 67

// 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 );
}

Upvotes: 0

skypjack
skypjack

Reputation: 50550

When i run with just one of the threads everything its ok. But not with the two of them.

According to the documentation for 2D accelerated rendering (also known as SDL_render.h, in other terms the place where SDL_RenderPresent lives):

This API is not designed to be used from multiple threads, see SDL bug #1995 for details.

You won't be able to do that any time soon. By looking at the description of the error, it looks like an UB and the link to the bug gives you all the details probably.

I just want to show different graphics playing around the window.

You don't need to use two threads to do that.
You can just update positions, animations and whatever is needed for your graphics and show them from the same thread. Nothing prevents you from calling the same function (as an example SDL_RenderCopy) more than once before to invoke SDL_RenderPresent.
If you needed a thread per graphic, what about a game with thousands of polygons on video?

Upvotes: 1

Related Questions