Autor Wątek: Nanogui - błąd fbo  (Przeczytany 1321 razy)

Offline Trix

  • Użytkownik

# Wrzesień 30, 2017, 17:39:36
Dzień dobry,
Mam problem, otóż próbuję do mojej aplikacji OpenGL doczepić nanoGUI: https://github.com/wjakob/nanogui

Mam okienko zrobione w GLFW, a obraz renderuję do fbo (deffered shading).
Wszystko fajnie działa do momentu włączenia gui do potoku: m_screen->drawWidgets();

Porobiłem testy - sam canvas się rysuje (deffered shading'a), tylko tekstura nie (G-Buffer) - nadałem kolor zielony i faktycznie zmienił się w tle: (załącznik 1)

Ponadto próbowałem wywołać funkcje rysującą nangui raz - działa tylko główny G-Buffer - color texture, normalne itp. są złe.

Wzrosły również fps'y - tak jakby nie istniały tekstury (G-Buffer'y), przez co nie zapisuje danych do nich.
Sprawdzam logi framebuffera ale nic się nie zmienia - sprawdzałem logi także w pętli głównej - nic.

Kod tworzenia okienka i nanogui:

#include "window.hpp"
#include <glad/glad.h>
#include <nanogui/nanogui.h>


using namespace std;
using namespace nanogui;

WindowGLFW::WindowGLFW() : m_window(0), m_monitor(0)
{
}
WindowGLFW::~WindowGLFW()
{
DestroyWindow();
}
void WindowGLFW::DestroyWindow()
{
glfwDestroyWindow(m_window);
glfwTerminate();
}

void WindowGLFW::CreateGUI()
{
//nanogui::init();
m_screen = new Screen();
m_screen->initialize(m_window, true);

FormHelper *gui = new FormHelper(m_screen);
nanogui::ref<nanogui::Window> nanoguiWindow = gui->addWindow(Eigen::Vector2i(10, 10), "Form helper example");
//gui->addGroup("Basic types");
/*gui->addVariable("bool", bvar)->setTooltip("Test tooltip.");
gui->addVariable("string", strval);

gui->addGroup("Validating fields");
gui->addVariable("int", ivar)->setSpinnable(true);
gui->addVariable("float", fvar)->setTooltip("Test.");
gui->addVariable("double", dvar)->setSpinnable(true);

gui->addGroup("Complex types");
gui->addVariable("Enumeration", enumval, enabled)->setItems({ "Item 1", "Item 2", "Item 3" });
gui->addVariable("Color", colval);

gui->addGroup("Other widgets");
gui->addButton("A button", []() { std::cout << "Button pressed." << std::endl; })->setTooltip("Testing a much longer tooltip, that will wrap around to new lines multiple times.");;
*/
m_screen->setVisible(true);
m_screen->performLayout();
nanoguiWindow->center();
}

void WindowGLFW::InitWindow()
{
m_window = glfwCreateWindow(800, 600, "???", NULL, NULL);
if (!m_window)
CriticalLog::Write("could not open window", "could not open window");
glfwMakeContextCurrent(m_window);

// -> Callbacks
glfwSetCursorPosCallback(m_window, PassiveMouseCallback);
glfwSetMouseButtonCallback(m_window, MouseCallback);
glfwSetFramebufferSizeCallback(m_window, FramebufferSizeCallback);
glfwSetKeyCallback(m_window, KeyCallback);
glfwSetCharCallback(m_window, CharCallback);
glfwSetDropCallback(m_window, DropCallback);
glfwSetScrollCallback(m_window, ScrollCallback);
// <-

gladLoadGL();
CreateGUI();
}


void WindowGLFW::WindowLoop()
{
while (!glfwWindowShouldClose(m_window)) {
glfwPollEvents();

FixedUpdateIndex::Call();
Keyboard();
//m_screen->drawContents();

// własciwe renderowanie
WindowManager::Instance().RenderScene();

// bez tego działa
m_screen->drawWidgets();
glfwSwapBuffers(m_window);

}
}
const pair<int, int> WindowGLFW::GetWindowSize()
{
int width, height;
glfwGetWindowSize(m_window, &width, &height);
return pair<int, int>(width, height);
}

WindowGLFW& WindowGLFW::Instance()
{
static WindowGLFW window;
return window;
}

void WindowGLFW::FramebufferSizeCallback(GLFWwindow* window, int width, int height)
{
Instance().m_screen->resizeCallbackEvent(width, height);
}

void WindowGLFW::PassiveMouseCallback(GLFWwindow* window, double x, double y)
{


Instance().m_screen->cursorPosCallbackEvent(x, y);
}

void WindowGLFW::MouseCallback(GLFWwindow* window, int button, int action, int modifiers)
{


Instance().m_screen->mouseButtonCallbackEvent(button, action, modifiers);

}

void WindowGLFW::KeyCallback(GLFWwindow* window, int key, int scancode, int action, int modifiers)
{
Instance().m_screen->keyCallbackEvent(key, scancode, action, modifiers);
}

void WindowGLFW::CharCallback(GLFWwindow* window, unsigned int codepoint)
{
Instance().m_screen->charCallbackEvent(codepoint);
}

void WindowGLFW::DropCallback(GLFWwindow* window, int count, const char **filenames)
{
Instance().m_screen->dropCallbackEvent(count, filenames);
}

void WindowGLFW::ScrollCallback(GLFWwindow* window, double x, double y)
{
Instance().m_screen->scrollCallbackEvent(x, y);
}

int main(int argc, char *argv[])
{
if (!glfwInit()) {
MessageBox(NULL, "FATAL ERROR: could not start GLFW3", NULL, MB_ICONHAND | MB_OK);
exit(EXIT_FAILURE);
}

WindowGLFW::Instance().InitWindow();
WindowGLFW::Instance().WindowLoop();

return 0;
}


Jakieś rady jak sobie z tym poradzić? Jestem w wielkiej kropce, bo muszę mieć program jak najszybciej.
Przypuszczam, że zmienia wewnątrz jakieś ustawienia - pytanie jakie? Szukałem po źródłach ale tam chyba za dużo nie zmienia?

Wstawiłem w pętli głównej system("pause");
okazało się, że co druga klatka pojawia się pierwsza wygenerowana klatka mojej aplikacji (nie aktualizuje się) wraz z kolejnymi klatkami gui, a następna tylko z gui i białym tłem.
Czym dalej od pierwszej klatki, tym obraz mojego canvasu blednieje - staje się coraz bardziej szary, aż finalnie staje się biały.

Kod fbo (deffered shading):
   PostProcessing::PostProcessing()
{
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);

glGenTextures(numTex, textures);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, WindowGLFW::Instance().GetWindowSize().first, WindowGLFW::Instance().GetWindowSize().second, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);

for (unsigned i = 1; i < numTex; ++i)
{
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, /*i == positionTex ? GL_RGB32F : */GL_RGB16F, WindowGLFW::Instance().GetWindowSize().first, WindowGLFW::Instance().GetWindowSize().second, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i], 0);
}

glGenTextures(1, &depthTex);
glBindTexture(GL_TEXTURE_2D, depthTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, WindowGLFW::Instance().GetWindowSize().first, WindowGLFW::Instance().GetWindowSize().second, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);

//glGenerateMipmap(GL_TEXTURE_2D);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0);

unsigned DrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glDrawBuffers(numTex, DrawBuffers);
glReadBuffer(GL_NONE);

CHECK_FRAMEBUFFER_ERROR();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

glUseProgram(*GetProgram());
glUniform1i(glGetUniformLocation(*GetProgram(), "colorTex"), colourTex);
glUniform1i(glGetUniformLocation(*GetProgram(), "normalTex"), normalTex);
glUniform1i(glGetUniformLocation(*GetProgram(), "positionTex"), positionTex);
glUniform1i(glGetUniformLocation(*GetProgram(), "depthTex"), numTex);
Program::BindUniformBlock(*GetProgram(), "Light", 1);
}


PostProcessing::~PostProcessing()
{
glDeleteFramebuffers(1, &framebuffer);
glDeleteTextures(numTex, textures);
glDeleteTextures(1, &depthTex);
}

PostProcessing& PostProcessing::Instance()
{
static PostProcessing pp;
return pp;
}

void PostProcessing::BindFrameBuffer()
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // potem zostaw tylko czyszczenie glebi, bo wszystko bedzie nadpisywane (teraz masz niebo puste)
}

void PostProcessing::Render()
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

for (unsigned i = 0; i < numTex; ++i)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, this->textures[i]);
}
glActiveTexture(GL_TEXTURE0 + numTex);
glBindTexture(GL_TEXTURE_2D, this->depthTex);

glUseProgram(*GetProgram());

glDisable(GL_DEPTH_TEST);
glDrawArrays(GL_POINTS, 0, 1);
glEnable(GL_DEPTH_TEST);
}

Program& PostProcessing::GetProgram()
{
static Program program = Program(
Shader("Data/Shaders/none.vs", TypeShader::VertexShader),
Shader("Data/Shaders/post_processing.gs", TypeShader::GeometryShader),
Shader("Data/Shaders/post_processing.fs", TypeShader::FragmentShader));
return program;
}

#edit
zaktualizowałem glad dla nanogui - przykładowy kod działa be zarzutu- u mnie czasem się uruchamia (dalej nie działa), a czasem nie(ten sam kod), niemalże skopiowałem ustawienia projektu, dalej to samo.
Przekopiowałem również dllke i lib glfw3, nanogui z projektu nanogui.
« Ostatnia zmiana: Wrzesień 30, 2017, 21:49:09 wysłana przez Trix »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Avaj

  • Użytkownik

# Październik 01, 2017, 18:50:58
Użyj narzędzi typu GLIntercept/RenderDoc, zrób snapshot stanu w jednej i drugiej klatce i porównaj/sprawdź co nanogui ci psuje w maszynie stanów.