Sam Lantinga wrote:
In theory, if you create two threads and a window and renderer or OpenGL context on each thread, then you should be able to simultaneously wait for vblank in the present on each thread. Note that you’ll have to have to call SDL_PumpEvents() in each thread as well, to get each window’s messages.
Thank for help,
now it have some light in tunnel 
program work but in random moment two windows lag in same time for 1-2 seconds and after that everything is become again normal.
Here is my code.
thread code.
I made Window and renderer into main loop and give them to thread.
I create one texture → pic, one transparent rectangle and vertical moving line.
void draw_thread(Window *win, Renderer *rend, int index) {
std::string str(“1.png”);
Texture *pic = new Texture (rend, str);
RectT rect(rand()%500,rand()%500,350, 250);
int count = 0;
while (!quit)
{
f (Platform::PumpEvents())
quit = true;
count+=10;
if (count >= win->Rect().w)
count = 0;
rend->Clear();
pic->DrawToWindow(rect);
rend->SetColor(255,255,255,255);
rend->DrawLine(0 + count,0, 0 + count,win->Rect().w,5);
rend->SetColor(255,0,0,125);
rend->DrawRect(155,155,200,200,true);
rend->Present();
}
}
Here is how i create window:
Window::Window(std::string &name, int screen_num, bool fullscren)
: window(nullptr),
windowRect()
{
if (!SDL_WasInit(SDL_INIT_VIDEO))
{
PDEBUG(“ERROR: SDL Was not inited please init platform first!\n”);
return;
}
SDL_Rect display_rect;
if (SDL_GetDisplayBounds(screen_num, &display_rect) != 0)
{
PDEBUG("ERROR: SDL_GetDisplayBounds() %s\n", SDL_GetError());
return;
}
memcpy(&windowRect, &display_rect, sizeof (windowRect));
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
uint32_t flags = SDL_WINDOW_OPENGL;
if (fullscren)
flags |= SDL_WINDOW_BORDERLESS;
window = SDL_CreateWindow(name.c_str(), display_rect.x, display_rect.y, display_rect.w, display_rect.h, flags);
if (window == nullptr)
{
PDEBUG("ERROR: SDL_CreateWindow() %s\n", SDL_GetError());
return;
}
}
Here is how i create renderer:
Renderer::Renderer(Window *win, bool vsync)
: window(win),
render(nullptr),
context()
{
if (win == nullptr)
{
PDEBUG(“ERROR: Window is NULL\n”);
return;
}
//Create Renderer
uint32_t flags = SDL_RENDERER_ACCELERATED;
if (vsync)
flags |= SDL_RENDERER_PRESENTVSYNC;
render = SDL_CreateRenderer(win->window, -1, flags);
if (render == nullptr)
{
PDEBUG("ERROR: SDL_CreateRenderer(): %s\n", SDL_GetError());
return;
}
//Create Window OpenGL Context
context = SDL_GL_CreateContext(win->window);
if (SDL_GL_MakeCurrent(window->window, context) != 0)
PDEBUG("ERROR: SDL_GL_MakeCurrent() %s\n", SDL_GetError());
SDL_SetRenderDrawBlendMode(render, SDL_BLENDMODE_BLEND);
Clear();
}
bool
Renderer::SetColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
//if (SDL_GL_MakeCurrent(window->window, context) != 0)
// PDEBUG(“ERROR: SDL_GL_MakeCurrent() %s\n”, SDL_GetError());
if (SDL_SetRenderDrawColor(render, r, g, b, a) == 0)
return true;
PDEBUG(“ERROR: SDL_SetRenderDrawColor() %s\n”, SDL_GetError());
return false;
}
bool
Renderer::DrawRect(int x, int y, int width, int height, bool bFilled)
{
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = width;
rect.h = height;
if (bFilled)
{
if (SDL_RenderFillRect(render, &rect) < 0)
{
PDEBUG("ERROR: SDL_RenderDrawRect() %s\n", SDL_GetError());
return false;
}
}
else
{
if (SDL_RenderDrawRect(render, &rect) < 0)
{
PDEBUG("ERROR: SDL_RenderFillRect() %s\n", SDL_GetError());
return false;
}
}
return true;
}
bool
Renderer::DrawLine(int xStart, int yStart, int xEnd, int yEnd, int width)
{
//if (SDL_GL_MakeCurrent(window->window, context) != 0)
// PDEBUG("ERROR: SDL_GL_MakeCurrent() %s\n", SDL_GetError());
glLineWidth(width);
if (SDL_RenderDrawLine(render, xStart, yStart, xEnd, yEnd) < 0)
{
PDEBUG("ERROR: SDL_RenderDrawLine() %s\n", SDL_GetError());
return false;
}
return true;
}
void
Renderer::Present()
{
SDL_RenderPresent(render);
}
and here is PollEnvent Function:
bool
Platform::PollEvents()
{
SDL_Event event;
if (SDL_PollEvent(&event) == 0)
return false;
switch (event.type)
{
case SDL_QUIT:
return true;
case SDL_KEYDOWN:
break;
case SDL_KEYUP:
if(event.key.keysym.sym == SDLK_ESCAPE)
return true;
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_CLOSE)
return true;
break;
}
return false;
}
What can be the problem here i cant see it…