#ifndef __gl_h_ #include #endif #include "hpr/window_system/window_system.hpp" #include "hpr/window_system/glfw/window_system.hpp" #include "hpr/window_system/glfw/window.hpp" #include "hpr/gpu.hpp" #include "hpr/math.hpp" #include "hpr/mesh.hpp" #include #include #include #include void APIENTRY glDebugOutput( GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, const char* message, const void* userParam ) { // ignore non-significant error/warning codes if (id == 131169 || id == 131185 || id == 131218 || id == 131204) return; std::cout << "Debug::GL[" << id << "]: " << message << std::endl; switch (source) { case GL_DEBUG_SOURCE_API: std::cout << "Source: API"; break; case GL_DEBUG_SOURCE_WINDOW_SYSTEM: std::cout << "Source: Window System"; break; case GL_DEBUG_SOURCE_SHADER_COMPILER: std::cout << "Source: Shader Compiler"; break; case GL_DEBUG_SOURCE_THIRD_PARTY: std::cout << "Source: Third Party"; break; case GL_DEBUG_SOURCE_APPLICATION: std::cout << "Source: Application"; break; case GL_DEBUG_SOURCE_OTHER: std::cout << "Source: Other"; break; } std::cout << std::endl; switch (type) { case GL_DEBUG_TYPE_ERROR: std::cout << "Type: Error"; break; case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: std::cout << "Type: Deprecated Behaviour"; break; case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: std::cout << "Type: Undefined Behaviour"; break; case GL_DEBUG_TYPE_PORTABILITY: std::cout << "Type: Portability"; break; case GL_DEBUG_TYPE_PERFORMANCE: std::cout << "Type: Performance"; break; case GL_DEBUG_TYPE_MARKER: std::cout << "Type: Marker"; break; case GL_DEBUG_TYPE_PUSH_GROUP: std::cout << "Type: Push Group"; break; case GL_DEBUG_TYPE_POP_GROUP: std::cout << "Type: Pop Group"; break; case GL_DEBUG_TYPE_OTHER: std::cout << "Type: Other"; break; } std::cout << std::endl; switch (severity) { case GL_DEBUG_SEVERITY_HIGH: std::cout << "Severity: high"; break; case GL_DEBUG_SEVERITY_MEDIUM: std::cout << "Severity: medium"; break; case GL_DEBUG_SEVERITY_LOW: std::cout << "Severity: low"; break; case GL_DEBUG_SEVERITY_NOTIFICATION: std::cout << "Severity: notification"; break; } std::cout << std::endl; } void debug() { GLint flags; glGetIntegerv(GL_CONTEXT_FLAGS, &flags); if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) { glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glDebugMessageCallback(glDebugOutput, nullptr); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); } } struct ConstantBuffer { hpr::mat4 World; hpr::mat4 View; hpr::mat4 Projection; hpr::vec4 Eye; float Color[4]; float Offset[4]; float Scale; int AllWhiteLight; int Pad[2]; }; struct ObjectBuffer { hpr::mat4 ObjectTransform; hpr::vec4 DiffuseColor; hpr::vec4 FalloffColor; float FalloffPower; int UseDiffuseMap; int UseSpecularMap; int UseNormalMap; int UseFalloff; int UseAlpha; int UseReflectMap; float Specular; float SpecularPower; float ReflectPower; float Ambient; int Lit; int LightExclusion[3]; int Pad[1]; }; int main() { using namespace hpr; gpu::WindowSystem* ws = gpu::WindowSystem::create(gpu::WindowContext::Provider::GLFW); gpu::Window* w = ws->newWindow(); w->init("test", gpu::Window::Style::Windowed, 0, 0, 600, 400, nullptr, nullptr); if (gpu::opengl::Device::loadLoader()) std::cerr << "Load gl loader error" << std::endl; //debug(); gpu::Device* device; gpu::Device::create(&device, gpu::Device::DeviceAPI::OpenGL); device->initialize(); gpu::Shader* vertexShader; device->createVertexShader(&vertexShader, "shaders/test.vert.glsl", "VS"); gpu::Shader* fragmentShader; device->createFragmentShader(&fragmentShader, "shaders/test.frag.glsl", "FS"); gpu::ShaderProgram* shaderProgram; device->createShaderProgram(&shaderProgram); device->attachShader(shaderProgram, vertexShader); device->attachShader(shaderProgram, fragmentShader); device->linkProgram(shaderProgram); mesh::Mesh mesh; mesh.addVertex(-1, 1, 0.5); mesh.addVertex(1, 1, 0.5); mesh.addVertex(1, -1, 0.5); mesh.addVertex(-1, -1, 0.5); mesh.addEdge(mesh.vertex(0), mesh.vertex(1)); mesh.addEdge(mesh.vertex(1), mesh.vertex(2)); mesh.addEdge(mesh.vertex(2), mesh.vertex(3)); mesh.addEdge(mesh.vertex(3), mesh.vertex(0)); mesh.addEdge(mesh.vertex(0), mesh.vertex(2)); mesh.addFace(mesh.edge(0), mesh.edge(1), mesh.edge(4)); mesh.addFace(mesh.edge(2), mesh.edge(3), mesh.edge(4)); darray data (3 * 6, 0.f); auto arr = mesh.face(0)->vertices() + mesh.face(1)->vertices(); for (auto n = 0; n < arr.size(); ++n) for (auto k = 0; k < 3; ++k) data[k + 3 * n] = *(arr[n]->data() + k); darray indices (6, 0); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 2; indices[4] = 3; indices[5] = 0; //for (auto n = 0; n < arr.size(); ++n) // indices[n] = mesh.indexOf(arr[n]); std::cout << "Data: "; for (auto p : data) std::cout << p << " "; std::cout << std::endl; std::cout << "Indices: "; for (auto p : indices) std::cout << p << " "; std::cout << std::endl; darray vertices { 0.5f, 0.5f, 0.0f, // top right 0.5f, -0.5f, 0.0f, // bottom right -0.5f, -0.5f, 0.0f, // bottom left -0.5f, 0.5f, 0.0f // top left }; darray indices2 { // note that we start from 0! 0, 1, 3, // first Triangle 1, 2, 3 // second Triangle }; gpu::Buffer* vertexBuffer; device->createVertexBuffer(&vertexBuffer, sizeof(float) * vertices.size(), (char*)vertices.data()); gpu::Buffer* indexBuffer; device->createIndexBuffer(&indexBuffer, sizeof(unsigned int) * indices2.size(), (char*)indices2.data()); gpu::Buffer* constantBuffer; device->createUniformBuffer(&constantBuffer, sizeof(ConstantBuffer), nullptr); gpu::Buffer* objectBuffer; device->createUniformBuffer(&objectBuffer, sizeof(ObjectBuffer), nullptr); ConstantBuffer constantData; constantData.Color[0] = 1; constantData.Color[1] = 0; constantData.Color[2] = 0; constantData.Color[3] = 1; constantData.Offset[0] = 0; constantData.Offset[1] = 0; constantData.Offset[2] = 0; constantData.Offset[3] = 1; constantData.Scale = 1; ObjectBuffer objectData; objectData.Lit = 1; objectData.DiffuseColor = vec4(1, 1, 1, 1); objectData.Specular = 0.25; objectData.SpecularPower = 1; objectData.UseDiffuseMap = 0; objectData.UseSpecularMap = 0; objectData.UseNormalMap = 0; objectData.UseFalloff = 0; objectData.FalloffColor = vec4(1, 1, 1, 1); objectData.FalloffPower = 1; objectData.Ambient = 1; objectData.UseAlpha = 0; objectData.UseReflectMap = 0; device->useShaderProgram(shaderProgram); device->useUniformBuffer(constantBuffer, 0); device->useUniformBuffer(objectBuffer, 1); IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; ImGui::StyleColorsDark(); ImGui_ImplGlfw_InitForOpenGL(dynamic_cast(w)->instance(), true); ImGui_ImplOpenGL3_Init("#version 420"); while (w->isOpen()) { glViewport(0, 0, 600, 400); glEnable(GL_DEPTH_TEST); glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); device->useShaderProgram(shaderProgram); device->useVertexBuffer(vertexBuffer, 0, 0); device->useIndexBuffer(indexBuffer, 0); //dynamic_cast(device)->Draw(2, 0, 0); //glDrawArrays(GL_TRIANGLES, 0, 6); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); bool yes = true; ImGui::ShowDemoWindow(&yes); ImGui::Begin("Hello, world!"); { if (ImGui::Button("Exit")) w->state(gpu::Window::State::Closed); ImGui::End(); } ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); dynamic_cast(w)->swapBuffers(); dynamic_cast(w)->pollEvents(); } ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); device->destroyShaderProgram(shaderProgram, false); device->destroyShader(vertexShader); device->destroyShader(fragmentShader); device->destroyBuffer(vertexBuffer); device->destroyBuffer(indexBuffer); device->destroyBuffer(constantBuffer); device->destroyBuffer(objectBuffer); delete dynamic_cast(device); ws->destroyWindow(w); gpu::WindowSystem::destroy(ws); return 0; }