How can I fix using gl buffers and shaders in different thread?












0















I would like to render my scene on different thread. I have classes for buffers and shader.



enum BUFFER
{
ARRAY,
ELEMENT_ARRAY
};

enum USAGE
{
STATIC_DRAW, DYNAMIC_DRAW
};

class Buffer
{
public:
Buffer() = default;
virtual ~Buffer() = default;

Buffer* Create(BUFFER buffer, USAGE usage)
{
return new GLBuffer(buffer, usage);
}

virtual void GenBuffer() {}
virtual void BindBuffer(){}
virtual void AddData(const void* data, intptr size, intptr offset) {}
//Data type is an enum
virtual void AddAttibute(unsigned int index, int size, DataType type, bool normalize, int stride, const void* offset) {}
};

class GLBuffer : public Buffer
{
public:
GLBuffer(BUFFER buffer, USAGE usage)
{
GenBuffer();
BindBuffer();

type = BUFFERToOpenGL(buffer);
usage = USAGEToOpenGL(usage);
}

void GenBuffer() override { glGenBuffers(1, &buffer); }
void BindBuffer() override { glBindBuffer(type, buffer); }

unsigned int buffer;
unsigned int type;
unsigned int usage;
};


I have not shown GLBuffer::AddData() and AddAttribute, but I think you got an idea of this.



The same for VertexArray



class VertexArray
{
public:
VertexArray* Create() { return GLVertexArray(); }
virtual void BindVertexArray() {}
}

class GLVertexArray : public VertexArray
{
public:
...
}


and so on



Shader is a bit different



enum SHADERTYPE
{
VERTEX,
FRAGMENT
};

class Shader
{
public:
Shader* Create() { return GLShader; }
virtual const int ShaderFromSource(const char* path, SHADERTYPE type) {}
virtual void End(const int* shaders, int count) {}

virtual void UseProgram() {}

virtual void //add uniforms etc
};

class GLShader : public Shader
{
public:
GLShader()
{
shaderProgram = glCreateProgram();
}

const int GLShader::ShaderFromSource(const char* path, SHADERTYPE type) override
{
unsigned int shaderID = glCreateShader(SHADERTYPEToOpenGL(type));

glShaderSource(shaderID, 1, &shader, NULL);
glCompileShader(shaderID);

glAttachShader(shaderProgram, shaderID);

return shaderID;
}

void GLShader::End(const int ids, int count) override
{
glLinkProgram(shaderProgram);

for (int i = 0; i < count; ++i) {
glDetachShader(shaderProgram, ids[i]);
glDeleteShader(ids[i]);
}
}

void UseProgram() override { glUseProgram(shaderProgram); }

unsigned int shaderProgram;
};


I want to create vao, vbo and shader in the Cube class ctor in the main thread and call Cube::Render in a render thread Cube::Render calls Use program adds uniforms and call DrawArray.



void mainloop()
{
Cube cube;

std::thread* thread = nullptr;
std::mutex mutex;
std::lock_guard<std::mutex> guard(mutex);
thread = new std::thread([&]() {
while (!quit) {
SDL_GL_MakeCurrent(window, glContext);

glClearColor(0, 0, static_cast<float>(15) / 255, 1);
glClear(GL_COLOR_BUFFER_BIT);

cube.Render();

SDL_GL_SwapWindow(window);
}
});
}


Cube cube - creates vao, vbo, shaders - adds vertices to vbo



class Cube
{
Cube()
{
vao = vao->Create();
vbo = vbo->Create(ARRAY, STATIC_DRAW);
vbo->AddData(...);
vbo->AddAttributes(...);

shader = shader->Create();
int shaders[2] = {
shader->ShaderFromSource(vs, VERTEX),
shader->ShaderFromSource(fs, FRAGMENT)
};
shader->End(shaders, 2);
}

VertexArray* vao = nullptr;
Buffer* vbo = nullptr;
Shader* shader = nullptr;
};


cube.Render() - uses shader, adds uniforms, call draw arrays



Cube::Render()
{
shader->UseProgram();
shader->Uniform(mvp);

vao->DrawArrays(TRIANGELS, 0, 36);
}


when Cube gets created in a main thread I got this message



enter image description here



when Cube gets created in a render thread I got this message
enter image description here



Why does it happen? How to support rendering in a different thread?










share|improve this question

























  • Calling class member functions of null pointer instances is not a good practice. The Shader::Create function should be declared as static and returns new GLSharder();

    – tunglt
    Jan 1 at 20:53











  • Ok, I will change it. Why it is not a good practice? It won't fix threads problem. I made a small test with new small VBO and GLVBO struct which does almost the same - calls genBuffers and bindBuffers(GL_ARRAY_BUFFER) and it does work. Any ideas?

    – JarekBisnesu
    Jan 1 at 21:12











  • It isn't a good practice because you force the code maintainer to reread your codes twice when the program crashed. He (or she) don't know if the called function has accessed to a member variable and catch an access violation. Using sharder = Shader::Create(); is much clearer.

    – tunglt
    Jan 1 at 22:14











  • Sharing OpenGL objects with multi-thread model needs more work. Each thread should have its own context and the contexts must be shared between threads via wglShareLists or SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);

    – tunglt
    Jan 1 at 22:17













  • As stated in VAO specification VAO objects cannot be shared between contexts, so the multiple contexts solution will not work for your program. More discussion about using OpenGL with multithread in SO is here

    – tunglt
    Jan 1 at 22:43


















0















I would like to render my scene on different thread. I have classes for buffers and shader.



enum BUFFER
{
ARRAY,
ELEMENT_ARRAY
};

enum USAGE
{
STATIC_DRAW, DYNAMIC_DRAW
};

class Buffer
{
public:
Buffer() = default;
virtual ~Buffer() = default;

Buffer* Create(BUFFER buffer, USAGE usage)
{
return new GLBuffer(buffer, usage);
}

virtual void GenBuffer() {}
virtual void BindBuffer(){}
virtual void AddData(const void* data, intptr size, intptr offset) {}
//Data type is an enum
virtual void AddAttibute(unsigned int index, int size, DataType type, bool normalize, int stride, const void* offset) {}
};

class GLBuffer : public Buffer
{
public:
GLBuffer(BUFFER buffer, USAGE usage)
{
GenBuffer();
BindBuffer();

type = BUFFERToOpenGL(buffer);
usage = USAGEToOpenGL(usage);
}

void GenBuffer() override { glGenBuffers(1, &buffer); }
void BindBuffer() override { glBindBuffer(type, buffer); }

unsigned int buffer;
unsigned int type;
unsigned int usage;
};


I have not shown GLBuffer::AddData() and AddAttribute, but I think you got an idea of this.



The same for VertexArray



class VertexArray
{
public:
VertexArray* Create() { return GLVertexArray(); }
virtual void BindVertexArray() {}
}

class GLVertexArray : public VertexArray
{
public:
...
}


and so on



Shader is a bit different



enum SHADERTYPE
{
VERTEX,
FRAGMENT
};

class Shader
{
public:
Shader* Create() { return GLShader; }
virtual const int ShaderFromSource(const char* path, SHADERTYPE type) {}
virtual void End(const int* shaders, int count) {}

virtual void UseProgram() {}

virtual void //add uniforms etc
};

class GLShader : public Shader
{
public:
GLShader()
{
shaderProgram = glCreateProgram();
}

const int GLShader::ShaderFromSource(const char* path, SHADERTYPE type) override
{
unsigned int shaderID = glCreateShader(SHADERTYPEToOpenGL(type));

glShaderSource(shaderID, 1, &shader, NULL);
glCompileShader(shaderID);

glAttachShader(shaderProgram, shaderID);

return shaderID;
}

void GLShader::End(const int ids, int count) override
{
glLinkProgram(shaderProgram);

for (int i = 0; i < count; ++i) {
glDetachShader(shaderProgram, ids[i]);
glDeleteShader(ids[i]);
}
}

void UseProgram() override { glUseProgram(shaderProgram); }

unsigned int shaderProgram;
};


I want to create vao, vbo and shader in the Cube class ctor in the main thread and call Cube::Render in a render thread Cube::Render calls Use program adds uniforms and call DrawArray.



void mainloop()
{
Cube cube;

std::thread* thread = nullptr;
std::mutex mutex;
std::lock_guard<std::mutex> guard(mutex);
thread = new std::thread([&]() {
while (!quit) {
SDL_GL_MakeCurrent(window, glContext);

glClearColor(0, 0, static_cast<float>(15) / 255, 1);
glClear(GL_COLOR_BUFFER_BIT);

cube.Render();

SDL_GL_SwapWindow(window);
}
});
}


Cube cube - creates vao, vbo, shaders - adds vertices to vbo



class Cube
{
Cube()
{
vao = vao->Create();
vbo = vbo->Create(ARRAY, STATIC_DRAW);
vbo->AddData(...);
vbo->AddAttributes(...);

shader = shader->Create();
int shaders[2] = {
shader->ShaderFromSource(vs, VERTEX),
shader->ShaderFromSource(fs, FRAGMENT)
};
shader->End(shaders, 2);
}

VertexArray* vao = nullptr;
Buffer* vbo = nullptr;
Shader* shader = nullptr;
};


cube.Render() - uses shader, adds uniforms, call draw arrays



Cube::Render()
{
shader->UseProgram();
shader->Uniform(mvp);

vao->DrawArrays(TRIANGELS, 0, 36);
}


when Cube gets created in a main thread I got this message



enter image description here



when Cube gets created in a render thread I got this message
enter image description here



Why does it happen? How to support rendering in a different thread?










share|improve this question

























  • Calling class member functions of null pointer instances is not a good practice. The Shader::Create function should be declared as static and returns new GLSharder();

    – tunglt
    Jan 1 at 20:53











  • Ok, I will change it. Why it is not a good practice? It won't fix threads problem. I made a small test with new small VBO and GLVBO struct which does almost the same - calls genBuffers and bindBuffers(GL_ARRAY_BUFFER) and it does work. Any ideas?

    – JarekBisnesu
    Jan 1 at 21:12











  • It isn't a good practice because you force the code maintainer to reread your codes twice when the program crashed. He (or she) don't know if the called function has accessed to a member variable and catch an access violation. Using sharder = Shader::Create(); is much clearer.

    – tunglt
    Jan 1 at 22:14











  • Sharing OpenGL objects with multi-thread model needs more work. Each thread should have its own context and the contexts must be shared between threads via wglShareLists or SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);

    – tunglt
    Jan 1 at 22:17













  • As stated in VAO specification VAO objects cannot be shared between contexts, so the multiple contexts solution will not work for your program. More discussion about using OpenGL with multithread in SO is here

    – tunglt
    Jan 1 at 22:43
















0












0








0








I would like to render my scene on different thread. I have classes for buffers and shader.



enum BUFFER
{
ARRAY,
ELEMENT_ARRAY
};

enum USAGE
{
STATIC_DRAW, DYNAMIC_DRAW
};

class Buffer
{
public:
Buffer() = default;
virtual ~Buffer() = default;

Buffer* Create(BUFFER buffer, USAGE usage)
{
return new GLBuffer(buffer, usage);
}

virtual void GenBuffer() {}
virtual void BindBuffer(){}
virtual void AddData(const void* data, intptr size, intptr offset) {}
//Data type is an enum
virtual void AddAttibute(unsigned int index, int size, DataType type, bool normalize, int stride, const void* offset) {}
};

class GLBuffer : public Buffer
{
public:
GLBuffer(BUFFER buffer, USAGE usage)
{
GenBuffer();
BindBuffer();

type = BUFFERToOpenGL(buffer);
usage = USAGEToOpenGL(usage);
}

void GenBuffer() override { glGenBuffers(1, &buffer); }
void BindBuffer() override { glBindBuffer(type, buffer); }

unsigned int buffer;
unsigned int type;
unsigned int usage;
};


I have not shown GLBuffer::AddData() and AddAttribute, but I think you got an idea of this.



The same for VertexArray



class VertexArray
{
public:
VertexArray* Create() { return GLVertexArray(); }
virtual void BindVertexArray() {}
}

class GLVertexArray : public VertexArray
{
public:
...
}


and so on



Shader is a bit different



enum SHADERTYPE
{
VERTEX,
FRAGMENT
};

class Shader
{
public:
Shader* Create() { return GLShader; }
virtual const int ShaderFromSource(const char* path, SHADERTYPE type) {}
virtual void End(const int* shaders, int count) {}

virtual void UseProgram() {}

virtual void //add uniforms etc
};

class GLShader : public Shader
{
public:
GLShader()
{
shaderProgram = glCreateProgram();
}

const int GLShader::ShaderFromSource(const char* path, SHADERTYPE type) override
{
unsigned int shaderID = glCreateShader(SHADERTYPEToOpenGL(type));

glShaderSource(shaderID, 1, &shader, NULL);
glCompileShader(shaderID);

glAttachShader(shaderProgram, shaderID);

return shaderID;
}

void GLShader::End(const int ids, int count) override
{
glLinkProgram(shaderProgram);

for (int i = 0; i < count; ++i) {
glDetachShader(shaderProgram, ids[i]);
glDeleteShader(ids[i]);
}
}

void UseProgram() override { glUseProgram(shaderProgram); }

unsigned int shaderProgram;
};


I want to create vao, vbo and shader in the Cube class ctor in the main thread and call Cube::Render in a render thread Cube::Render calls Use program adds uniforms and call DrawArray.



void mainloop()
{
Cube cube;

std::thread* thread = nullptr;
std::mutex mutex;
std::lock_guard<std::mutex> guard(mutex);
thread = new std::thread([&]() {
while (!quit) {
SDL_GL_MakeCurrent(window, glContext);

glClearColor(0, 0, static_cast<float>(15) / 255, 1);
glClear(GL_COLOR_BUFFER_BIT);

cube.Render();

SDL_GL_SwapWindow(window);
}
});
}


Cube cube - creates vao, vbo, shaders - adds vertices to vbo



class Cube
{
Cube()
{
vao = vao->Create();
vbo = vbo->Create(ARRAY, STATIC_DRAW);
vbo->AddData(...);
vbo->AddAttributes(...);

shader = shader->Create();
int shaders[2] = {
shader->ShaderFromSource(vs, VERTEX),
shader->ShaderFromSource(fs, FRAGMENT)
};
shader->End(shaders, 2);
}

VertexArray* vao = nullptr;
Buffer* vbo = nullptr;
Shader* shader = nullptr;
};


cube.Render() - uses shader, adds uniforms, call draw arrays



Cube::Render()
{
shader->UseProgram();
shader->Uniform(mvp);

vao->DrawArrays(TRIANGELS, 0, 36);
}


when Cube gets created in a main thread I got this message



enter image description here



when Cube gets created in a render thread I got this message
enter image description here



Why does it happen? How to support rendering in a different thread?










share|improve this question
















I would like to render my scene on different thread. I have classes for buffers and shader.



enum BUFFER
{
ARRAY,
ELEMENT_ARRAY
};

enum USAGE
{
STATIC_DRAW, DYNAMIC_DRAW
};

class Buffer
{
public:
Buffer() = default;
virtual ~Buffer() = default;

Buffer* Create(BUFFER buffer, USAGE usage)
{
return new GLBuffer(buffer, usage);
}

virtual void GenBuffer() {}
virtual void BindBuffer(){}
virtual void AddData(const void* data, intptr size, intptr offset) {}
//Data type is an enum
virtual void AddAttibute(unsigned int index, int size, DataType type, bool normalize, int stride, const void* offset) {}
};

class GLBuffer : public Buffer
{
public:
GLBuffer(BUFFER buffer, USAGE usage)
{
GenBuffer();
BindBuffer();

type = BUFFERToOpenGL(buffer);
usage = USAGEToOpenGL(usage);
}

void GenBuffer() override { glGenBuffers(1, &buffer); }
void BindBuffer() override { glBindBuffer(type, buffer); }

unsigned int buffer;
unsigned int type;
unsigned int usage;
};


I have not shown GLBuffer::AddData() and AddAttribute, but I think you got an idea of this.



The same for VertexArray



class VertexArray
{
public:
VertexArray* Create() { return GLVertexArray(); }
virtual void BindVertexArray() {}
}

class GLVertexArray : public VertexArray
{
public:
...
}


and so on



Shader is a bit different



enum SHADERTYPE
{
VERTEX,
FRAGMENT
};

class Shader
{
public:
Shader* Create() { return GLShader; }
virtual const int ShaderFromSource(const char* path, SHADERTYPE type) {}
virtual void End(const int* shaders, int count) {}

virtual void UseProgram() {}

virtual void //add uniforms etc
};

class GLShader : public Shader
{
public:
GLShader()
{
shaderProgram = glCreateProgram();
}

const int GLShader::ShaderFromSource(const char* path, SHADERTYPE type) override
{
unsigned int shaderID = glCreateShader(SHADERTYPEToOpenGL(type));

glShaderSource(shaderID, 1, &shader, NULL);
glCompileShader(shaderID);

glAttachShader(shaderProgram, shaderID);

return shaderID;
}

void GLShader::End(const int ids, int count) override
{
glLinkProgram(shaderProgram);

for (int i = 0; i < count; ++i) {
glDetachShader(shaderProgram, ids[i]);
glDeleteShader(ids[i]);
}
}

void UseProgram() override { glUseProgram(shaderProgram); }

unsigned int shaderProgram;
};


I want to create vao, vbo and shader in the Cube class ctor in the main thread and call Cube::Render in a render thread Cube::Render calls Use program adds uniforms and call DrawArray.



void mainloop()
{
Cube cube;

std::thread* thread = nullptr;
std::mutex mutex;
std::lock_guard<std::mutex> guard(mutex);
thread = new std::thread([&]() {
while (!quit) {
SDL_GL_MakeCurrent(window, glContext);

glClearColor(0, 0, static_cast<float>(15) / 255, 1);
glClear(GL_COLOR_BUFFER_BIT);

cube.Render();

SDL_GL_SwapWindow(window);
}
});
}


Cube cube - creates vao, vbo, shaders - adds vertices to vbo



class Cube
{
Cube()
{
vao = vao->Create();
vbo = vbo->Create(ARRAY, STATIC_DRAW);
vbo->AddData(...);
vbo->AddAttributes(...);

shader = shader->Create();
int shaders[2] = {
shader->ShaderFromSource(vs, VERTEX),
shader->ShaderFromSource(fs, FRAGMENT)
};
shader->End(shaders, 2);
}

VertexArray* vao = nullptr;
Buffer* vbo = nullptr;
Shader* shader = nullptr;
};


cube.Render() - uses shader, adds uniforms, call draw arrays



Cube::Render()
{
shader->UseProgram();
shader->Uniform(mvp);

vao->DrawArrays(TRIANGELS, 0, 36);
}


when Cube gets created in a main thread I got this message



enter image description here



when Cube gets created in a render thread I got this message
enter image description here



Why does it happen? How to support rendering in a different thread?







c++ multithreading opengl rendering






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 1 at 19:21







JarekBisnesu

















asked Jan 1 at 19:06









JarekBisnesuJarekBisnesu

495




495













  • Calling class member functions of null pointer instances is not a good practice. The Shader::Create function should be declared as static and returns new GLSharder();

    – tunglt
    Jan 1 at 20:53











  • Ok, I will change it. Why it is not a good practice? It won't fix threads problem. I made a small test with new small VBO and GLVBO struct which does almost the same - calls genBuffers and bindBuffers(GL_ARRAY_BUFFER) and it does work. Any ideas?

    – JarekBisnesu
    Jan 1 at 21:12











  • It isn't a good practice because you force the code maintainer to reread your codes twice when the program crashed. He (or she) don't know if the called function has accessed to a member variable and catch an access violation. Using sharder = Shader::Create(); is much clearer.

    – tunglt
    Jan 1 at 22:14











  • Sharing OpenGL objects with multi-thread model needs more work. Each thread should have its own context and the contexts must be shared between threads via wglShareLists or SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);

    – tunglt
    Jan 1 at 22:17













  • As stated in VAO specification VAO objects cannot be shared between contexts, so the multiple contexts solution will not work for your program. More discussion about using OpenGL with multithread in SO is here

    – tunglt
    Jan 1 at 22:43





















  • Calling class member functions of null pointer instances is not a good practice. The Shader::Create function should be declared as static and returns new GLSharder();

    – tunglt
    Jan 1 at 20:53











  • Ok, I will change it. Why it is not a good practice? It won't fix threads problem. I made a small test with new small VBO and GLVBO struct which does almost the same - calls genBuffers and bindBuffers(GL_ARRAY_BUFFER) and it does work. Any ideas?

    – JarekBisnesu
    Jan 1 at 21:12











  • It isn't a good practice because you force the code maintainer to reread your codes twice when the program crashed. He (or she) don't know if the called function has accessed to a member variable and catch an access violation. Using sharder = Shader::Create(); is much clearer.

    – tunglt
    Jan 1 at 22:14











  • Sharing OpenGL objects with multi-thread model needs more work. Each thread should have its own context and the contexts must be shared between threads via wglShareLists or SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);

    – tunglt
    Jan 1 at 22:17













  • As stated in VAO specification VAO objects cannot be shared between contexts, so the multiple contexts solution will not work for your program. More discussion about using OpenGL with multithread in SO is here

    – tunglt
    Jan 1 at 22:43



















Calling class member functions of null pointer instances is not a good practice. The Shader::Create function should be declared as static and returns new GLSharder();

– tunglt
Jan 1 at 20:53





Calling class member functions of null pointer instances is not a good practice. The Shader::Create function should be declared as static and returns new GLSharder();

– tunglt
Jan 1 at 20:53













Ok, I will change it. Why it is not a good practice? It won't fix threads problem. I made a small test with new small VBO and GLVBO struct which does almost the same - calls genBuffers and bindBuffers(GL_ARRAY_BUFFER) and it does work. Any ideas?

– JarekBisnesu
Jan 1 at 21:12





Ok, I will change it. Why it is not a good practice? It won't fix threads problem. I made a small test with new small VBO and GLVBO struct which does almost the same - calls genBuffers and bindBuffers(GL_ARRAY_BUFFER) and it does work. Any ideas?

– JarekBisnesu
Jan 1 at 21:12













It isn't a good practice because you force the code maintainer to reread your codes twice when the program crashed. He (or she) don't know if the called function has accessed to a member variable and catch an access violation. Using sharder = Shader::Create(); is much clearer.

– tunglt
Jan 1 at 22:14





It isn't a good practice because you force the code maintainer to reread your codes twice when the program crashed. He (or she) don't know if the called function has accessed to a member variable and catch an access violation. Using sharder = Shader::Create(); is much clearer.

– tunglt
Jan 1 at 22:14













Sharing OpenGL objects with multi-thread model needs more work. Each thread should have its own context and the contexts must be shared between threads via wglShareLists or SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);

– tunglt
Jan 1 at 22:17







Sharing OpenGL objects with multi-thread model needs more work. Each thread should have its own context and the contexts must be shared between threads via wglShareLists or SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);

– tunglt
Jan 1 at 22:17















As stated in VAO specification VAO objects cannot be shared between contexts, so the multiple contexts solution will not work for your program. More discussion about using OpenGL with multithread in SO is here

– tunglt
Jan 1 at 22:43







As stated in VAO specification VAO objects cannot be shared between contexts, so the multiple contexts solution will not work for your program. More discussion about using OpenGL with multithread in SO is here

– tunglt
Jan 1 at 22:43














1 Answer
1






active

oldest

votes


















1














I see you're using SDL2, so, you have to create 2 SDL_GLContexts, let's say



SDL_GLContext mainContext;
SDL_GLContext renderThreadContext;


if you already enabled SDL_GL_SHARE_WITH_CURRENT_CONTEXT all you need to do is



after creating a window you have to create mainContext context



mainContext = SDL_GL_CreateContext(window);


then create a thread and Create renderThreadContext in this thread!!!



void RenderThread() {
std::thread* renderThread = nullptr;

thread = new std::thread([&](){
renderThreadContext = SDL_GL_CreateContext(window);
//*** NOW CREATE CUBE OBJECT ***
Cube cube;
while(!quit) {
SDL_GL_Make_Current(window, renderThreadContext);
//Opengl Calls
SDL_GL_SwapWindow(window);
}
});
}


as tunglt said - Each thread should have its own context, so you have to create a new context in a thread as I showed above.






share|improve this answer
























  • Yep, that works! Thank you man! I did not understand tunglt at the first time. Thank you @tunglt too

    – JarekBisnesu
    Jan 2 at 17:34











  • Your welcome. Glad I helped you.

    – Shout
    Jan 2 at 17:36











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53998186%2fhow-can-i-fix-using-gl-buffers-and-shaders-in-different-thread%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














I see you're using SDL2, so, you have to create 2 SDL_GLContexts, let's say



SDL_GLContext mainContext;
SDL_GLContext renderThreadContext;


if you already enabled SDL_GL_SHARE_WITH_CURRENT_CONTEXT all you need to do is



after creating a window you have to create mainContext context



mainContext = SDL_GL_CreateContext(window);


then create a thread and Create renderThreadContext in this thread!!!



void RenderThread() {
std::thread* renderThread = nullptr;

thread = new std::thread([&](){
renderThreadContext = SDL_GL_CreateContext(window);
//*** NOW CREATE CUBE OBJECT ***
Cube cube;
while(!quit) {
SDL_GL_Make_Current(window, renderThreadContext);
//Opengl Calls
SDL_GL_SwapWindow(window);
}
});
}


as tunglt said - Each thread should have its own context, so you have to create a new context in a thread as I showed above.






share|improve this answer
























  • Yep, that works! Thank you man! I did not understand tunglt at the first time. Thank you @tunglt too

    – JarekBisnesu
    Jan 2 at 17:34











  • Your welcome. Glad I helped you.

    – Shout
    Jan 2 at 17:36
















1














I see you're using SDL2, so, you have to create 2 SDL_GLContexts, let's say



SDL_GLContext mainContext;
SDL_GLContext renderThreadContext;


if you already enabled SDL_GL_SHARE_WITH_CURRENT_CONTEXT all you need to do is



after creating a window you have to create mainContext context



mainContext = SDL_GL_CreateContext(window);


then create a thread and Create renderThreadContext in this thread!!!



void RenderThread() {
std::thread* renderThread = nullptr;

thread = new std::thread([&](){
renderThreadContext = SDL_GL_CreateContext(window);
//*** NOW CREATE CUBE OBJECT ***
Cube cube;
while(!quit) {
SDL_GL_Make_Current(window, renderThreadContext);
//Opengl Calls
SDL_GL_SwapWindow(window);
}
});
}


as tunglt said - Each thread should have its own context, so you have to create a new context in a thread as I showed above.






share|improve this answer
























  • Yep, that works! Thank you man! I did not understand tunglt at the first time. Thank you @tunglt too

    – JarekBisnesu
    Jan 2 at 17:34











  • Your welcome. Glad I helped you.

    – Shout
    Jan 2 at 17:36














1












1








1







I see you're using SDL2, so, you have to create 2 SDL_GLContexts, let's say



SDL_GLContext mainContext;
SDL_GLContext renderThreadContext;


if you already enabled SDL_GL_SHARE_WITH_CURRENT_CONTEXT all you need to do is



after creating a window you have to create mainContext context



mainContext = SDL_GL_CreateContext(window);


then create a thread and Create renderThreadContext in this thread!!!



void RenderThread() {
std::thread* renderThread = nullptr;

thread = new std::thread([&](){
renderThreadContext = SDL_GL_CreateContext(window);
//*** NOW CREATE CUBE OBJECT ***
Cube cube;
while(!quit) {
SDL_GL_Make_Current(window, renderThreadContext);
//Opengl Calls
SDL_GL_SwapWindow(window);
}
});
}


as tunglt said - Each thread should have its own context, so you have to create a new context in a thread as I showed above.






share|improve this answer













I see you're using SDL2, so, you have to create 2 SDL_GLContexts, let's say



SDL_GLContext mainContext;
SDL_GLContext renderThreadContext;


if you already enabled SDL_GL_SHARE_WITH_CURRENT_CONTEXT all you need to do is



after creating a window you have to create mainContext context



mainContext = SDL_GL_CreateContext(window);


then create a thread and Create renderThreadContext in this thread!!!



void RenderThread() {
std::thread* renderThread = nullptr;

thread = new std::thread([&](){
renderThreadContext = SDL_GL_CreateContext(window);
//*** NOW CREATE CUBE OBJECT ***
Cube cube;
while(!quit) {
SDL_GL_Make_Current(window, renderThreadContext);
//Opengl Calls
SDL_GL_SwapWindow(window);
}
});
}


as tunglt said - Each thread should have its own context, so you have to create a new context in a thread as I showed above.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 2 at 16:42









ShoutShout

1286




1286













  • Yep, that works! Thank you man! I did not understand tunglt at the first time. Thank you @tunglt too

    – JarekBisnesu
    Jan 2 at 17:34











  • Your welcome. Glad I helped you.

    – Shout
    Jan 2 at 17:36



















  • Yep, that works! Thank you man! I did not understand tunglt at the first time. Thank you @tunglt too

    – JarekBisnesu
    Jan 2 at 17:34











  • Your welcome. Glad I helped you.

    – Shout
    Jan 2 at 17:36

















Yep, that works! Thank you man! I did not understand tunglt at the first time. Thank you @tunglt too

– JarekBisnesu
Jan 2 at 17:34





Yep, that works! Thank you man! I did not understand tunglt at the first time. Thank you @tunglt too

– JarekBisnesu
Jan 2 at 17:34













Your welcome. Glad I helped you.

– Shout
Jan 2 at 17:36





Your welcome. Glad I helped you.

– Shout
Jan 2 at 17:36




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53998186%2fhow-can-i-fix-using-gl-buffers-and-shaders-in-different-thread%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas