I have program that has 4 viewports.
1 of main GLFW window to deal with GUI and 4 of sub GLFW windows to render scenes.
Scene will be loaded up while sub GLFW window is being created then initialize Shaders/FBOs/SSBOs/Frame Buffers.
At this point I have a issue that I have to load up scene 4 times otherwise scenes cannot be rendered on each views.
I think scenes can be shared among views, so reducing it will improve the overall performance.
However when I try that, nothing is rendered on views.
So I would like to get some help from here to see what is the problem with my source codes.
GL_Window / GL_Viewport…
struct GL_Viewport {
HWND winHandle;
GLFWwindow* glfwHandle;
char name[256];
int x, y, width, height;
RECT area;
Camera* camera;
};
struct GL_Window {
HWND winHandle;
GLFWwindow* glfwHandle;
char name[256];
int x, y, width, height;
GL_Viewport* glViews;
int size;
bool AddViewport(int viewIndex = 0, int _x = 0, int _y = 0, int _width = 0, int _height = 0) {
if (viewIndex == 0)
glViews = (GL_Viewport*)malloc((viewIndex + 1) * sizeof(GL_Viewport));
else
glViews = (GL_Viewport*)realloc(glViews, (viewIndex + 1) * sizeof(GL_Viewport));
GL_Viewport dummyView;
glViews[viewIndex] = dummyView;
glViews[viewIndex].x = _x;
glViews[viewIndex].y = _y;
glViews[viewIndex].width = _width;
glViews[viewIndex].height = _height;
sprintf(glViews[viewIndex].name, "View-%d", viewIndex);
if (!glfwInit()) {
printf("Failed to initialize GLFW\n");
return false;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_DECORATED, GL_FALSE);
// Create viewport
glViews[viewIndex].glfwHandle = glfwCreateWindow(glViews[viewIndex].width, glViews[viewIndex].height, glViews[viewIndex].name, NULL, glfwHandle);
if (glViews[viewIndex].glfwHandle == NULL) {
printf("Failed to create viewport(s)\n");
return false;
}
// Switch to current viewport
glfwMakeContextCurrent(glViews[viewIndex].glfwHandle);
// Initialize GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
printf("Failed to initialize GLAD\n");
glfwTerminate();
return false;
}
// Get window handle
glViews[viewIndex].winHandle = glfwGetWin32Window(glViews[viewIndex].glfwHandle);
// Set parent
SetParent(glViews[viewIndex].winHandle, winHandle);
return true;
}
};
Main…
// Create main GLFW window
if (!gDisplayManager.startUp()) {
printf("Failed to initialize window display manager.\n");
return false;
}
// Create 4 viewports
for (int i = 0; i < gDisplayManager.glWindow.size; i++) {
// Create viewport
gDisplayManager.glWindow.AddViewport(i, 0, 0, gDisplayManager.ViewWidth, gDisplayManager.ViewHeight);
// Initialize viewports
gDisplayManager.InitViewports(i);
// Load scene(s)
if (!gSceneManager.startUp(gDisplayManager.glWindow.glViews[i])) {
printf("Failed to initialize scene manager.\n");
return false;
}
// Initializes rendering manager, which is in charge of high level
// rendering tasks (render queue, locating render scene etc)
// It gets passed references to the other major subsystems for use later
if (!gRenderManager.startUp(gSceneManager.getCurrentScene(), gDisplayManager.glWindow.glViews[i])) {
printf("Failed to initialize Render manager for view [%d].\n", i);
return false;
}
// Initializing input manager that manages all mouse, keyboard and
// mousewheel input.
if (!gInputManager.startUp(gDisplayManager.glWindow.glViews[i])) {
printf("Failed to initialize input manager for view [%d].\n", i);
return false;
}
}
while (!gDisplayManager.ShouldClose()) {
// Update all models in the current scene
gSceneManager.update(deltaT);
// Scan through all available viewports
for (int i = 0; i < gDisplayManager.glWindow.size; i++) {
glfwMakeContextCurrent(gDisplayManager.glWindow.glViews[i].glfwHandle);
// Update camera
gDisplayManager.glWindow.glViews[i].camera->update(NULL, 0, 0);
// User input
gInputManager.processInput(deltaTime, gDisplayManager.glWindow.glViews[i]);
// Render scene
gRenderManager.render(start, gDisplayManager.glWindow.glViews[i]);
// Swap screen buffer
gDisplayManager.Swap(i);
// Processes all pending events
glfwPollEvents();
}
}
SceneManager…
bool SceneManager::startUp(GL_Viewport& glView) {
currentSceneID = "sponza";
if (!loadScene(currentSceneID, glView)) {
printf("Could not load scene. No models successfully loaded!\n");
return false;
}
return true;
}
void SceneManager::update(unsigned int deltaT) {
currentScene->update(deltaT);
}
Scene* SceneManager::getCurrentScene() {
return currentScene;
}
// Loads the scene with the given ID
bool SceneManager::loadScene(std::string sceneID, GL_Viewport& glView) {
currentScene = new Scene(sceneID, glView);
return !currentScene->loadingError;
}
Scene…
Scene::Scene(const std::string& sceneName, GL_Viewport& glView) {
models.folderPath = "assets/scenes/";
models.fileExtension = ".json";
models.sceneID = sceneName;
loadingError = !loadContent(glView);
}
bool Scene::loadContent(GL_Viewport& glView) {
// Parsing into Json file readable format
models.sceneConfigFilePath = models.folderPath + models.sceneID + models.fileExtension;
std::ifstream file(models.sceneConfigFilePath.c_str());
json configJson;
file >> configJson;
loadSceneModels(configJson);
loadCamera(configJson, glView);
CubeMap::cubeMapCube.setup();
loadSkyBox(configJson);
loadLights(configJson);
generateEnvironmentMaps();
return !models.modelsInScene.empty();
}
RenderManager…
bool RenderManager::startUp(Scene* scene, GL_Viewport& glView) {
currentScene = scene;
if (!loadShaders()) {
printf("Shaders failed to be initialized correctly.\n");
return false;
}
if (!initFBOs(glView)) {
printf("FBO's failed to be initialized correctly.\n");
return false;
}
if (!initSSBOs(glView)) {
printf("SSBO's failed to be initialized correctly.\n");
return false;
}
if (!preProcess(glView)) {
printf("Pre-processing failed.\n");
return false;
}
return true;
}
void RenderManager::render(const unsigned int start, GL_Viewport& glView) {
// Making sure depth testing is enabled
glEnable(GL_DEPTH_TEST);
glDepthMask(true);
// Directional shadows
dirShadowFBO.bind();
dirShadowFBO.clear(GL_DEPTH_BUFFER_BIT, glm::vec3(1.0f));
currentScene->drawDirLightShadows(dirShadowShader, dirShadowFBO.depthBuffer, withDirectionalLightShadow);
// Multisampled Depth pre-pass
multiSampledFBO.bind();
multiSampledFBO.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, glm::vec3(0.0f));
currentScene->drawDepthPass(depthPrePassShader, glView);
// Light assignment
cullLightsCompShader.use();
cullLightsCompShader.setMat4("viewMatrix", glView.camera->viewMatrix);
cullLightsCompShader.dispatch(1, 1, 6);
// Forward render the scene in the multisampled FBO using the z buffer to discard early
glDepthFunc(GL_LEQUAL);
glDepthMask(false);
currentScene->drawScene(PBRClusteredShader, glView, withLight, withTexture);
currentScene->drawSkyBox(skyboxShader, glView, withSkyBox);
// Resolve the from multisampled to normal resolution for postProcessing
multiSampledFBO.blitTo(simpleFBO, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Post processing, includes bloom, exposure mapping
postProcess(start, glView);
}
Since the same scene has been loaded 4 times, it occupies system resources too much, I want to minimize it.