Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // dear imgui: standalone example application for GLFW + OpenGL 3, using programmable pipeline
- // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp.
- // (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
- #include "imgui.h"
- #include "imgui_impl_glfw.h"
- #include "imgui_impl_opengl3.h"
- #include <stdio.h>
- #include <vector>
- #include <glm/glm.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <glm/gtc/type_ptr.hpp>
- #define STB_IMAGE_IMPLEMENTATION
- #include <stb_image.h>
- // About OpenGL function loaders: modern OpenGL doesn't have a standard header file and requires individual function pointers to be loaded manually.
- // Helper libraries are often used for this purpose! Here we are supporting a few common ones: gl3w, glew, glad.
- // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
- #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
- #include <GL/gl3w.h> // Initialize with gl3wInit()
- #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
- #include <GL/glew.h> // Initialize with glewInit()
- #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
- #include <glad/glad.h> // Initialize with gladLoadGL()
- #else
- #include IMGUI_IMPL_OPENGL_LOADER_CUSTOM
- #endif
- #include <GLFW/glfw3.h> // Include glfw3.h after our OpenGL definitions
- static void glfw_error_callback(int error, const char* description)
- {
- fprintf(stderr, "Glfw Error %d: %s\n", error, description);
- }
- class Camera
- {
- float rotationAngle = glm::half_pi<float>();
- float elevationAngle = 0.0f;
- float speed = 0.05f;
- float elevationBoundary = 1.5f;
- public:
- void moveUp()
- {
- if (elevationAngle + speed < elevationBoundary)
- {
- elevationAngle += speed;
- }
- }
- void moveDown()
- {
- if (elevationAngle - speed > -elevationBoundary)
- {
- elevationAngle -= speed;
- }
- }
- void moveRight()
- {
- rotationAngle += speed;
- }
- void moveLeft()
- {
- rotationAngle -= speed;
- }
- glm::vec3 getPos()
- {
- return glm::vec3(cos(rotationAngle) * cos(elevationAngle), sin(elevationAngle), sin(rotationAngle) * cos(elevationAngle));
- }
- };
- void processInput(GLFWwindow *window);
- void framebuffer_size_callback(GLFWwindow* window, int width, int height);
- void prepareShader(unsigned int &shader, GLenum type, const GLchar ** source);
- void generateCube(float x, float y, float z, float size, std::vector<float> *vertices, std::vector<unsigned int> *indices);
- void generateSponge(float x, float y, float z, float size, int recursionLevel, std::vector<float> *vertices, std::vector<unsigned int> *indices);
- void fillTextureCoords(std::vector<float> &data, float* textureCoords, int totalTextureCoordsNumber);
- const char *vertexShaderSource = "#version 330 core\n"
- "layout (location = 0) in vec3 aPos;\n"
- "layout (location = 1) in vec2 aTexCoord;\n"
- "out vec2 TexCoord;\n"
- "uniform mat4 view;\n"
- "uniform mat4 projection;\n"
- "void main()\n"
- "{\n"
- " gl_Position = projection * view * vec4(aPos, 1.0);\n"
- " TexCoord = aTexCoord;\n"
- "}\0";
- const char *fragmentShaderSource = "#version 330 core\n"
- "in vec2 TexCoord;\n"
- "out vec4 FragColor;\n"
- "uniform vec4 color;\n"
- "uniform sampler2D myTexture;\n"
- "void main()\n"
- "{\n"
- " FragColor = texture(myTexture, TexCoord) * color;\n"
- "}\n\0";
- Camera cam;
- int main(int, char**)
- {
- // Setup window
- glfwSetErrorCallback(glfw_error_callback);
- if (!glfwInit())
- return 1;
- // Decide GL+GLSL versions
- #if __APPLE__
- // GL 3.2 + GLSL 150
- const char* glsl_version = "#version 150";
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
- #else
- // GL 4.3 + GLSL 430
- const char* glsl_version = "#version 430";
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only
- #endif
- float windowHeight = 800, windowWidth = 800;
- GLFWwindow* window = glfwCreateWindow(windowHeight, windowWidth, "Sierpinski", NULL, NULL);
- if (window == NULL)
- {
- return 1;
- }
- glfwMakeContextCurrent(window);
- glfwSwapInterval(1);
- // Initialize OpenGL loader
- #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
- bool err = gl3wInit() != 0;
- #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
- bool err = glewInit() != GLEW_OK;
- #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
- bool err = !gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
- #endif
- if (err)
- {
- fprintf(stderr, "Failed to initialize OpenGL loader!\n");
- return 1;
- }
- glViewport(0, 0, windowHeight, windowWidth);
- glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
- // Setup Dear ImGui binding
- IMGUI_CHECKVERSION();
- ImGui::CreateContext();
- ImGuiIO& io = ImGui::GetIO(); (void)io;
- //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
- //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
- ImGui_ImplGlfw_InitForOpenGL(window, true);
- ImGui_ImplOpenGL3_Init(glsl_version);
- // Setup style
- ImGui::StyleColorsDark();
- //ImGui::StyleColorsClassic();
- unsigned int vertexShader, fragmentShader, shaderProgram;
- prepareShader(vertexShader, GL_VERTEX_SHADER, &vertexShaderSource);
- prepareShader(fragmentShader, GL_FRAGMENT_SHADER, &fragmentShaderSource);
- shaderProgram = glCreateProgram();
- glAttachShader(shaderProgram, vertexShader);
- glAttachShader(shaderProgram, fragmentShader);
- glLinkProgram(shaderProgram);
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- float textureCoords[] = {
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- 0.0f, 1.0f,
- 1.0f, 1.0f
- };
- const int TOTAL_TEXTURE_COORDS_NUMBER = 8;
- //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- int width, height, nrChannels;
- unsigned char *textureData = stbi_load("textures.jpg", &width, &height, &nrChannels, 0);
- stbi_set_flip_vertically_on_load(true);
- std::vector<float>vertices;
- std::vector<unsigned int>indices;
- float x = 0.8, y = 0.8, z = 0.8, size = 1;
- int recursionLevel = 1;
- if (recursionLevel != 0) {
- generateSponge(x, y, z, size, recursionLevel - 1, &vertices, &indices);
- }
- else {
- generateCube(x, y, z, size, &vertices, &indices);
- }
- //fillTextureCoords(vertices, textureCoords, TOTAL_TEXTURE_COORDS_NUMBER);
- unsigned int VBO, VAO, EBO;
- glGenVertexArrays(1, &VAO);
- glBindVertexArray(VAO);
- unsigned int texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
- glGenerateMipmap(GL_TEXTURE_2D);
- stbi_image_free(textureData);
- glGenBuffers(1, &EBO);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(int), &indices.front(), GL_DYNAMIC_DRAW);
- glGenBuffers(1, &VBO);
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices.front(), GL_DYNAMIC_DRAW);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
- glEnableVertexAttribArray(1);
- glBindTexture(GL_TEXTURE_2D, texture);
- glBindVertexArray(VAO);
- int pyramidColorLocation = glGetUniformLocation(shaderProgram, "color");
- int viewLocation = glGetUniformLocation(shaderProgram, "view");
- ImVec4 backgroundColor = ImVec4(0.5f, 0.5f, 0.0f, 1.0f);
- ImVec4 pyramidColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
- glClearDepth(1.0f);
- glEnable(GL_DEPTH_TEST);
- glUseProgram(shaderProgram);
- glm::mat4 projection(1.0f);
- projection = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -10.0f, 10.0f);
- //projection = glm::scale(projection, glm::vec3(0.5f, 0.5f, 0.5f));
- int projectionLocation = glGetUniformLocation(shaderProgram, "projection");
- glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, glm::value_ptr(projection));
- while (!glfwWindowShouldClose(window))
- {
- glfwPollEvents();
- // Start the Dear ImGui frame
- ImGui_ImplOpenGL3_NewFrame();
- ImGui_ImplGlfw_NewFrame();
- ImGui::NewFrame();
- {
- ImGui::Begin("settings");
- ImGui::SetWindowSize(ImVec2(300, 100));
- ImGui::SetWindowPos(ImVec2(0, 0));
- ImGui::SliderInt("level", &recursionLevel, 0, 5);
- if (ImGui::Button("update"))
- {
- vertices.clear();
- indices.clear();
- if (recursionLevel != 0) {
- generateSponge(x, y, z, size, recursionLevel - 1, &vertices, &indices);
- }
- else {
- generateCube(x, y, z, size, &vertices, &indices);
- }
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices.front(), GL_DYNAMIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(int), &indices.front(), GL_DYNAMIC_DRAW);
- //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
- }
- ImGui::ColorEdit3("triangles", (float*)&pyramidColor);
- ImGui::End();
- }
- glUseProgram(shaderProgram);
- glm::mat4 view(1.0f);
- view = glm::lookAt(cam.getPos(), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
- glUniformMatrix4fv(viewLocation, 1, GL_FALSE, glm::value_ptr(view));
- glClearColor(backgroundColor.x, backgroundColor.y, backgroundColor.z, backgroundColor.w);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glUniform4f(pyramidColorLocation, pyramidColor.x, pyramidColor.y, pyramidColor.z, pyramidColor.w);
- glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
- ImGui::Render();
- ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
- glfwSwapBuffers(window);
- processInput(window);
- }
- // Cleanup
- ImGui_ImplOpenGL3_Shutdown();
- ImGui_ImplGlfw_Shutdown();
- ImGui::DestroyContext();
- glfwTerminate();
- return 0;
- }
- void processInput(GLFWwindow *window)
- {
- if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
- glfwSetWindowShouldClose(window, true);
- if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
- cam.moveUp();
- if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
- cam.moveDown();
- if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS)
- cam.moveLeft();
- if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS)
- cam.moveRight();
- }
- void framebuffer_size_callback(GLFWwindow* window, int width, int height)
- {
- glViewport(0, 0, width, height);
- }
- void prepareShader(unsigned int &shader, GLenum type, const GLchar ** source)
- {
- shader = glCreateShader(type);
- glShaderSource(shader, 1, source, NULL);
- glCompileShader(shader);
- }
- void generateCube(float x, float y, float z, float size, std::vector<GLfloat> *vertices, std::vector<unsigned int> *indices) {
- float smallSize = size / 3;
- float smalltextureSize = 1 / 3;
- int index = 0;
- if (indices->size() > 6) {
- index = indices->at(indices->size() - 5) + 1;
- }
- std::vector<GLfloat> newVertices = {
- x, y, z, 1,1,
- x - size, y, z, 0,1,
- x - size, y, z - size, 0,0,
- x, y, z - size, 1,0,
- x, y - size, z, 0,0,
- x - size, y - size, z,0,1,
- x - size, y - size, z - size,1,0,
- x, y - size, z - size,1,1,
- //top small +
- x - smallSize, y, z - smallSize,1 - smalltextureSize,1 - smalltextureSize,
- x - 2 * smallSize, y, z - smallSize,0 + smalltextureSize,1 - smalltextureSize,
- x - 2 * smallSize, y, z - 2 * smallSize, 0 + smalltextureSize,0 + smalltextureSize,
- x - smallSize, y, z - 2 * smallSize,1 - smalltextureSize,0 + smalltextureSize,
- //back small +
- x - smallSize, y - smallSize, z - size,0, 0,
- x - 2 * smallSize, y - smallSize, z - size,0, 1,
- x - 2 * smallSize, y - 2 * smallSize, z - size,1, 0,
- x - smallSize, y - 2 * smallSize, z - size,1, 1,
- //left small +
- x,y - smallSize, z - smallSize,0, 0,
- x,y - smallSize, z - 2 * smallSize,0, 1,
- x,y - 2 * smallSize, z - 2 * smallSize,1, 0,
- x,y - 2 * smallSize, z - smallSize,1, 1,
- //front small +
- x - smallSize, y - smallSize, z,0, 0,
- x - 2 * smallSize, y - smallSize, z,0, 1,
- x - 2 * smallSize, y - 2 * smallSize, z,1, 0,
- x - smallSize, y - 2 * smallSize, z,1, 1,
- //right small
- x - size,y - smallSize, z - smallSize,0, 0,
- x - size,y - smallSize, z - 2 * smallSize,0, 1,
- x - size,y - 2 * smallSize, z - 2 * smallSize,1, 0,
- x - size,y - 2 * smallSize, z - smallSize,1, 1,
- //bottom small +
- x - smallSize, y - size, z - smallSize,0, 0,
- x - 2 * smallSize, y - size, z - smallSize,0, 1,
- x - 2 * smallSize, y - size, z - 2 * smallSize,1, 0,
- x - smallSize, y - size, z - 2 * smallSize, 1, 1
- };
- std::vector<unsigned int> newIndices{
- //top
- 0,8,9,0,9,1,
- 1,9,10,1,10,2,
- 2,10,11,2,11,3,
- 3,11,8,3,8,0,
- //back
- 3,12,13,3,13,2,
- 2,13,14,2,14,6,
- 6,14,15,6,15,7,
- 7,15,12,7,12,3,
- //right
- 0,16,17,0,17,3,
- 3,17,18,3,18,7,
- 7,18,19,7,19,4,
- 4,19,16,4,16,0,
- //front
- 0,20,21,0,21,1,
- 1,21,22,1,22,5,
- 5,22,23,5,23,4,
- 4,23,20,4,20,0,
- //left
- 1,24,25,1,25,2,
- 2,25,26,2,26,6,
- 6,26,27,6,27,5,
- 5,27,24,5,24,1,
- //bottom
- 4,28,29,4,29,5,
- 5,29,30,5,30,6,
- 6,30,31,6,31,7,
- 7,31,28,7,28,4
- };
- for (int i = 0; i < indices->size(); i++) {
- indices->at(i) += index;
- }
- vertices->insert(vertices->end(), newVertices.begin(), newVertices.end());
- indices->insert(indices->end(), newIndices.begin(), newIndices.end());
- }
- void generateSponge(float x, float y, float z, float size, int recursionLevel, std::vector<GLfloat> *vertices, std::vector<unsigned int> *indices) {
- float smallSize = size / 3;
- if (recursionLevel > 0) {
- //top
- generateSponge(x, y, z, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - smallSize, y, z, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - 2 * smallSize, y, z, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x, y, z - smallSize, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - 2 * smallSize, y, z - smallSize, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x, y, z - 2 * smallSize, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - smallSize, y, z - 2 * smallSize, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - 2 * smallSize, y, z - 2 * smallSize, smallSize, recursionLevel - 1, vertices, indices);
- //middle
- generateSponge(x, y - smallSize, z, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - 2 * smallSize, y - smallSize, z, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x, y - smallSize, z - 2 * smallSize, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - 2 * smallSize, y - smallSize, z - 2 * smallSize, smallSize, recursionLevel - 1, vertices, indices);
- //bottom
- generateSponge(x, y - 2 * smallSize, z, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - smallSize, y - 2 * smallSize, z, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - 2 * smallSize, y - 2 * smallSize, z, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x, y - 2 * smallSize, z - smallSize, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - 2 * smallSize, y - 2 * smallSize, z - smallSize, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x, y - 2 * smallSize, z - 2 * smallSize, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - smallSize, y - 2 * smallSize, z - 2 * smallSize, smallSize, recursionLevel - 1, vertices, indices);
- generateSponge(x - 2 * smallSize, y - 2 * smallSize, z - 2 * smallSize, smallSize, recursionLevel - 1, vertices, indices);
- }
- else {
- //top
- generateCube(x, y, z, smallSize, vertices, indices);
- generateCube(x - smallSize, y, z, smallSize, vertices, indices);
- generateCube(x - 2 * smallSize, y, z, smallSize, vertices, indices);
- generateCube(x, y, z - smallSize, smallSize, vertices, indices);
- generateCube(x - 2 * smallSize, y, z - smallSize, smallSize, vertices, indices);
- generateCube(x, y, z - 2 * smallSize, smallSize, vertices, indices);
- generateCube(x - smallSize, y, z - 2 * smallSize, smallSize, vertices, indices);
- generateCube(x - 2 * smallSize, y, z - 2 * smallSize, smallSize, vertices, indices);
- //middle
- generateCube(x, y - smallSize, z, smallSize, vertices, indices);
- generateCube(x - 2 * smallSize, y - smallSize, z, smallSize, vertices, indices);
- generateCube(x, y - smallSize, z - 2 * smallSize, smallSize, vertices, indices);
- generateCube(x - 2 * smallSize, y - smallSize, z - 2 * smallSize, smallSize, vertices, indices);
- //bottom
- generateCube(x, y - 2 * smallSize, z, smallSize, vertices, indices);
- generateCube(x - smallSize, y - 2 * smallSize, z, smallSize, vertices, indices);
- generateCube(x - 2 * smallSize, y - 2 * smallSize, z, smallSize, vertices, indices);
- generateCube(x, y - 2 * smallSize, z - smallSize, smallSize, vertices, indices);
- generateCube(x - 2 * smallSize, y - 2 * smallSize, z - smallSize, smallSize, vertices, indices);
- generateCube(x, y - 2 * smallSize, z - 2 * smallSize, smallSize, vertices, indices);
- generateCube(x - smallSize, y - 2 * smallSize, z - 2 * smallSize, smallSize, vertices, indices);
- generateCube(x - 2 * smallSize, y - 2 * smallSize, z - 2 * smallSize, smallSize, vertices, indices);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement