Я создаю тему в моей программе. Затем я создаю второй контекст OpenGL для этого потока и делюсь им с контекстом основного потока.
Когда я пытаюсь прочитать данные в потоке из PBO, используя glMapBuffer, указатель возвращает nullptr. Также как я могу синхронизировать два потока.
Это первый раз, когда я работаю с двумя разными потоками, и у меня возникли большие проблемы даже при создании двух разных потоков.
Пожалуйста, посмотрите на мой код ипосоветуйте мне, как я могу заставить его работать.
Это код для потока.
Шейдеры являются базовыми шейдерами.
void wnd2func(void)
{
GLFWwindow *wnd2 = glfwCreateWindow(400, 300, "window 2", 0, wnd);
{
std::unique_lock<std::mutex> lck(mtx);
wnd2created = true;
cv.notify_one();
}
if (wnd2 == nullptr)
return;
glfwMakeContextCurrent(wnd2);
glewExperimental = GL_TRUE;
glewInit();
glGenBuffers(2, pbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[0]);
glBufferData(GL_PIXEL_PACK_BUFFER, SCR_WIDTH *SCR_HEIGHT * 3, 0, GL_STREAM_READ);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[1]);
glBufferData(GL_PIXEL_PACK_BUFFER, SCR_WIDTH *SCR_HEIGHT * 3, 0, GL_STREAM_READ);
while (true)
{
writeIndex = (writeIndex + 1) % 2;
readIndex = (writeIndex + 1) % 2;
// bind PBO to read pixels. This buffer is being copied from GPU to CPU memory
glReadBuffer(GL_FRONT);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[0]);
// copy from framebuffer to PBO asynchronously. it will be ready in the NEXT frame
glReadPixels(0, 0, SCR_WIDTH, SCR_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
// now read other PBO which should be already in CPU memory
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[0]);
// map buffer so we can access it
void* downsampleData = (unsigned char *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
// std::cout << "Yes Downsample";
if (downsampleData)
{
std::cout << "Able to read the data";
}
downsampleData = nullptr;
}
}
Это код для основногов котором я создаю простой объект куба
#include "pch.h"
#include <iostream>
#include <gl\glew.h>
#include <glfw3.h>
#include"Shader.h"
#include <stb_image.h>
#include "Camera.h"
#include <map>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <mutex>
#include <condition_variable>
int readIndex = 0;
int writeIndex = 1;
GLuint pbo[2];
GLFWwindow *wnd = nullptr;
bool wnd2created = false;
std::mutex mtx;
std::condition_variable cv;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
// settings
const unsigned int SCR_WIDTH = 400;
const unsigned int SCR_HEIGHT = 300;
// camera
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
int main()
{
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// glfw window creation
// --------------------
// GLFWwindow* sharedWindow = NULL;
wnd = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Test", 0, nullptr );
std::thread wnd2thread(wnd2func);
{
std::unique_lock<std::mutex> lck(mtx);
cv.wait(lck, []() -> bool { return wnd2created; });
}
glfwMakeContextCurrent(wnd);
if (wnd == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(wnd);
glfwSetFramebufferSizeCallback(wnd, framebuffer_size_callback);
glewExperimental = GL_TRUE;
glewInit();
glEnable(GL_DEPTH_TEST);
// set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
float cubeVertices[] = {
// positions // texture Coords
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
// cube VAO
unsigned int cubeVAO, cubeVBO;
glGenVertexArrays(1, &cubeVAO);
glGenBuffers(1, &cubeVBO);
glBindVertexArray(cubeVAO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
Shader shader("C:\\Shaders\\OpenGL_GUI\\Video\\Vertex.txt", "C:\\Shaders\\OpenGL_GUI\\Video\\Fragment.txt");
shader.use();
// render loop
// -----------
while (!glfwWindowShouldClose(wnd))
{
glEnable(GL_DEPTH_TEST); // enable depth testing (is disabled for rendering screen-space quad)
// make sure we clear the framebuffer's content
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader.use();
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
shader.setMat4("view", view);
shader.setMat4("projection", projection);
// cubes
glBindVertexArray(cubeVAO);
model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
glfwSwapBuffers(wnd);
glfwPollEvents();
}
// optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
glDeleteVertexArrays(1, &cubeVAO);
glfwTerminate();
return 0;
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}