You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
7.7 KiB
C++
253 lines
7.7 KiB
C++
//------------------------------------------------------------------------------
|
|
// Copyright (c) 2018-2025 Michele Morrone
|
|
// All rights reserved.
|
|
//
|
|
// https://michelemorrone.eu - https://brutpitt.com
|
|
//
|
|
// X: https://x.com/BrutPitt - GitHub: https://github.com/BrutPitt
|
|
//
|
|
// direct mail: brutpitt(at)gmail.com - me(at)michelemorrone.eu
|
|
//
|
|
// This software is distributed under the terms of the BSD 2-Clause license
|
|
//------------------------------------------------------------------------------
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <glad/glad.h>
|
|
#include <imgui/imgui.h>
|
|
#include <imgui/imgui_internal.h>
|
|
#include <imgui/imgui_impl_glfw.h>
|
|
#include <imgui/imgui_impl_opengl3.h>
|
|
#include <GLFW/glfw3.h>
|
|
|
|
|
|
#include "oglDebug.h"
|
|
#include "../commons/shadersAndModel.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// imGuIZMO: include imGuIZMOquat.h or imguizmo_quat.h
|
|
#include <imguizmo_quat.h> // now also imguizmo_quat.h
|
|
|
|
|
|
|
|
int width = 1280, height = 800;
|
|
GLFWwindow *glfwWindow;
|
|
|
|
const int nElemVtx = 4;
|
|
const int nVertex = sizeof(coloredCubeData)/(sizeof(float)*2*nElemVtx);
|
|
|
|
// Shaders & Vertex attributes
|
|
GLuint program, vao, vaoBuffer;
|
|
enum loc { vtxIdx = 0, colIdx, mvpIdx}; // shader locations
|
|
|
|
mat4 mvpMatrix, viewMatrix, projMatrix;
|
|
|
|
void draw()
|
|
{
|
|
glUseProgram(program);
|
|
|
|
glProgramUniformMatrix4fv(program, loc::mvpIdx, 1, false, value_ptr(mvpMatrix)); // internal vgMath permits also "static_cast": use value_ptr for GLM compatibility
|
|
|
|
glBindVertexArray(vao);
|
|
glDrawArrays(GL_TRIANGLES, 0, nVertex);
|
|
|
|
glUseProgram(0);
|
|
}
|
|
|
|
void setPerspective()
|
|
{
|
|
float aspectRatio = float(height) / float(width); // Set "camera" position and perspective
|
|
float fov = radians( 45.0f ) * aspectRatio;
|
|
projMatrix = perspective( fov, 1/aspectRatio, 0.1f, 100.0f );
|
|
}
|
|
|
|
void setScene()
|
|
{
|
|
viewMatrix = lookAt( vec3( 0.0f, 0.0f, 10.0f ), // From / EyePos
|
|
vec3( 0.0f, 0.0f, 0.0f ), // To /
|
|
vec3( 0.0f, 1.0f, .0f)); // Up
|
|
|
|
setPerspective();
|
|
}
|
|
|
|
|
|
void glfwWindowSizeCallback(GLFWwindow* window, int w, int h)
|
|
{
|
|
width = w; height = h;
|
|
setPerspective();
|
|
glViewport(0, 0, width, height);
|
|
draw();
|
|
}
|
|
|
|
void initGL()
|
|
{
|
|
enableDebugCallback();
|
|
|
|
GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
|
|
glShaderSource(vertex, 1, &vertex_code, NULL);
|
|
glCompileShader(vertex);
|
|
glCompileShader(vertex);
|
|
|
|
GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
|
glShaderSource(fragment, 1, &fragment_code, NULL);
|
|
glCompileShader(fragment);
|
|
checkShader(fragment);
|
|
|
|
program = glCreateProgram();
|
|
glAttachShader(program, vertex);
|
|
glAttachShader(program, fragment);
|
|
glLinkProgram(program);
|
|
checkProgram(program);
|
|
|
|
glDeleteShader(vertex);
|
|
glDeleteShader(fragment);
|
|
|
|
glCreateVertexArrays(1, &vao);
|
|
glCreateBuffers(1, &vaoBuffer);
|
|
glNamedBufferStorage(vaoBuffer, sizeof(coloredCubeData), coloredCubeData, 0);
|
|
|
|
glVertexArrayAttribBinding(vao,loc::vtxIdx, 0);
|
|
glVertexArrayAttribFormat(vao, loc::vtxIdx, nElemVtx, GL_FLOAT, GL_FALSE, 0);
|
|
glEnableVertexArrayAttrib(vao, loc::vtxIdx);
|
|
|
|
glVertexArrayAttribBinding(vao,loc::colIdx, 0);
|
|
glVertexArrayAttribFormat(vao, loc::colIdx, nElemVtx, GL_FLOAT, GL_FALSE, nElemVtx*sizeof(float));
|
|
glEnableVertexArrayAttrib(vao, loc::colIdx);
|
|
|
|
glVertexArrayVertexBuffer(vao, 0, vaoBuffer, 0, 2*nElemVtx*sizeof(float));
|
|
|
|
glViewport(0, 0, width, height);
|
|
|
|
glDisable(GL_BLEND);
|
|
glDepthMask(GL_TRUE);
|
|
glEnable(GL_CULL_FACE);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LESS);
|
|
glFrontFace(GL_CW);
|
|
|
|
glDepthRange(-1.0, 1.0);
|
|
setScene();
|
|
}
|
|
|
|
void initFramework()
|
|
{
|
|
glfwInit();
|
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
|
|
|
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
glfwWindowHint(GLFW_DOUBLEBUFFER, GL_TRUE);
|
|
|
|
glfwWindow = glfwCreateWindow(width, height, "glCube", NULL, NULL);
|
|
if (!glfwWindow)
|
|
{
|
|
glfwTerminate();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
glfwMakeContextCurrent(glfwWindow);
|
|
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); //get OpenGL extensions
|
|
|
|
glfwSetWindowSizeCallback(glfwWindow, glfwWindowSizeCallback);
|
|
|
|
glfwSwapInterval(1); // 0 vSync off - 1 vSync on
|
|
}
|
|
|
|
void initImGui()
|
|
{
|
|
// Setup Dear ImGui context
|
|
IMGUI_CHECKVERSION();
|
|
ImGui::CreateContext();
|
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
|
|
|
// Setup Dear ImGui style
|
|
ImGui::StyleColorsDark();
|
|
|
|
// Setup Platform/Renderer backends
|
|
ImGui_ImplGlfw_InitForOpenGL(glfwWindow, true);
|
|
ImGui_ImplOpenGL3_Init("#version 450");
|
|
}
|
|
|
|
|
|
int main(int /* argc */, char ** /* argv */) // necessary for SDLmain in Windows
|
|
{
|
|
initFramework(); // initialize GLFW framework
|
|
initGL(); // init OpenGL building vaoBuffer and shader program (compile and link vtx/frag shaders)
|
|
|
|
// other OpenGL settings... used locally
|
|
vec4 bgColor = vec4(0.0f);
|
|
GLfloat f=1.0f;
|
|
|
|
// Setup/Initialize Dear ImGui context
|
|
initImGui();
|
|
|
|
// main render/draw loop
|
|
while (!glfwWindowShouldClose(glfwWindow)) {
|
|
glfwPollEvents();
|
|
glClearBufferfv(GL_DEPTH, 0, &f);
|
|
glClearBufferfv(GL_COLOR, 0, value_ptr(bgColor));
|
|
|
|
if (glfwGetWindowAttrib(glfwWindow, GLFW_ICONIFIED) != 0) {
|
|
ImGui_ImplGlfw_Sleep(10);
|
|
continue;
|
|
}
|
|
|
|
// ImGUI: prepare new frame
|
|
ImGui_ImplOpenGL3_NewFrame();
|
|
ImGui_ImplGlfw_NewFrame();
|
|
ImGui::NewFrame();
|
|
|
|
// ImGui: Your windows here
|
|
|
|
// Imgui window (container)
|
|
bool isVisible = true; // visibility flag: always on
|
|
ImGui::Begin("##giz", &isVisible);
|
|
|
|
// imGuIZMO: declare global/static/member/..
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
static vec4 rotation(1,0,0,0); // vec4(x, y, z, w)
|
|
|
|
// ImGuIZMO.quat widget
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
ImGui::gizmo3D("##aaa", rotation,/* size */ 240 ); // if(ImGui::gizmo3D(...) == true) ---> widget has been updated
|
|
// it returns "only" a rotation (net of transformations) in base to mouse(x,y) movement
|
|
// and add new rotation, obtained from new "delta.xy" mouse motion, to previous one (saved in your global/static/member var)
|
|
|
|
// End Imgui window (container) block
|
|
ImGui::End();
|
|
|
|
// now we can transfer the rotation in a matrix...
|
|
mat4 modelMatrix = rotate(mat4(1),rotation.w, vec3(rotation));
|
|
|
|
// build MVP matrix to pass to shader
|
|
mvpMatrix = projMatrix * viewMatrix * modelMatrix;
|
|
|
|
// draw the cube, passing MVP matrix to the vtx shader
|
|
draw();
|
|
|
|
// ImGui Rendering
|
|
ImGui::Render();
|
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
|
|
|
glfwSwapBuffers(glfwWindow);
|
|
}
|
|
|
|
// Cleanup ImGui
|
|
ImGui_ImplOpenGL3_Shutdown();
|
|
ImGui_ImplGlfw_Shutdown();
|
|
ImGui::DestroyContext();
|
|
|
|
// Cleanup OpenGL
|
|
glDeleteVertexArrays(1, &vao);
|
|
glDeleteBuffers(1, &vaoBuffer);
|
|
glDeleteProgram(program);
|
|
|
|
// Cleanup Framework
|
|
glfwDestroyWindow(glfwWindow);
|
|
glfwTerminate();
|
|
|
|
return EXIT_SUCCESS;
|
|
} |