penrose

program for generating penrose tilings.
Log | Files | Refs | README | LICENSE

commit 59805d495e4c595f6abdf9ea7d716ad12e864a59
parent f465d3c30706dea3647cfdd546ae975436d86d8c
Author: mpizzzle <m@michaelpercival.xyz>
Date:   Sun, 11 Oct 2020 00:22:51 +0100

draws a fricken triangle

Diffstat:
MMakefile | 8++++----
Afragment.frag | 5+++++
Mpenrose.cpp | 162++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Ashader.cpp | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ashader.hpp | 8++++++++
Avertex.vert | 8++++++++
6 files changed, 216 insertions(+), 60 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,12 +1,12 @@ CXX = clang++ CXXFLAGS = -O2 -Wall -Wextra -pedantic -std=c++17 -I. -LIBS= -lSDL2 +LIBS = -lGL -lglfw -lGLEW +DEPS = shader.hpp ODIR = obj -_OBJ = penrose.o - +_OBJ = penrose.o shader.o OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) -$(ODIR)/%.o: %.cpp $(LIBS) +$(ODIR)/%.o: %.cpp $(DEPS) $(CXX) -c -o $@ $< $(CXXFLAGS) penrose: $(OBJ) $(LIBS) diff --git a/fragment.frag b/fragment.frag @@ -0,0 +1,5 @@ +#version 330 core +out vec3 color; +void main() { + color = vec3(1,0,0); +} diff --git a/penrose.cpp b/penrose.cpp @@ -1,68 +1,118 @@ -#include <SDL2/SDL.h> +#include <GL/glew.h> +#include <GLFW/glfw3.h> + #include <iostream> +#include <fstream> +#include <sstream> #include <vector> -class triangle { -public: - SDL_Point* points; - std::vector<triangle*> subtriangles; -}; - -class t123 : public triangle { -}; - -class t124 : public triangle { -}; - -void draw(SDL_Renderer* Renderer, std::vector<triangle> triangles) { - SDL_SetRenderDrawColor(Renderer, 0x33, 0x66, 0x99, SDL_ALPHA_OPAQUE); - SDL_RenderClear(Renderer); - - SDL_SetRenderDrawColor(Renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); - - for (triangle t : triangles) { - SDL_RenderDrawLines(Renderer, t.points, 4); - } - - SDL_RenderPresent(Renderer); -} +#include "shader.hpp" + +//class triangle { +//public: +// SDL_Point* points; +// std::vector<triangle*> subtriangles; +//}; +// +//class t123 : public triangle { +//}; +// +//class t124 : public triangle { +//}; +// +//void draw(SDL_Renderer* Renderer, std::vector<triangle> triangles) { +// SDL_SetRenderDrawColor(Renderer, 0x33, 0x66, 0x99, SDL_ALPHA_OPAQUE); +// SDL_RenderClear(Renderer); +// +// SDL_SetRenderDrawColor(Renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); +// +// for (triangle t : triangles) { +// SDL_RenderDrawLines(Renderer, t.points, 4); +// } +// +// SDL_RenderPresent(Renderer); +//} int main() { - bool quit = false; - - SDL_DisplayMode current; - SDL_Event event; - - SDL_Init(SDL_INIT_EVERYTHING); - SDL_GetCurrentDisplayMode(0, &current); - SDL_Log("Display #%d: current display mode is %dx%dpx @ %dhz.", 0, current.w, current.h, current.refresh_rate); - - std::vector<triangle> triangles; - - t123 t; - SDL_Point points[4] = { {0, 480}, {320, 0}, {640, 480}, {0, 480} }; - t.points = points; - triangles.push_back(t); - - SDL_Window* Window = SDL_CreateWindow("penrose", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, current.w, current.h, SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN); - SDL_Renderer* Renderer = SDL_CreateRenderer(Window, -1, 0); - - while (!quit) { - SDL_WaitEvent(&event); + // An array of 3 vectors which represents 3 vertices + static const GLfloat g_vertex_buffer_data[] = { + -.5f, -.5f, 0.0f, + .5f, -.5f, 0.0f, + 0.0f, .5f, 0.0f, + }; + + //std::vector<triangle> triangles; + //t123 t; + //SDL_Point points[4] = { {0, 480}, {320, 0}, {640, 480}, {0, 480} }; + //t.points = points; + //triangles.push_back(t); + + // Initialise GLFW + glewExperimental = true; + if(!glfwInit()) + { + return -1; + } + glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3 + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // We don't want the old OpenGL + + // Open a window and create its OpenGL context + GLFWwindow* window; // (In the accompanying source code, this variable is global for simplicity) + window = glfwCreateWindow(1920, 1080, "penrose", NULL, NULL); + + if(window == NULL) { + glfwTerminate(); + return -1; + } - switch (event.type) - { - case SDL_QUIT: - quit = true; - break; - } + glfwMakeContextCurrent(window); // Initialize GLEW + glewExperimental=true; - draw(Renderer, triangles); + if (glewInit() != GLEW_OK) { + return -1; } - SDL_DestroyRenderer(Renderer); - SDL_DestroyWindow(Window); - SDL_Quit(); + GLuint VertexArrayID; + glGenVertexArrays(1, &VertexArrayID); + glBindVertexArray(VertexArrayID); + + glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); + + // This will identify our vertex buffer + GLuint vertexbuffer; + // Generate 1 buffer, put the resulting identifier in vertexbuffer + glGenBuffers(1, &vertexbuffer); + // The following commands will talk about our 'vertexbuffer' buffer + glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); + // Give our vertices to OpenGL. + glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); + + GLuint programID = Shader::loadShaders("vertex.vert", "fragment.frag"); + glUseProgram(programID); + + do{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // 1st attribute buffer : vertices + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); + glVertexAttribPointer( + 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized? + 0, // stride + (void*)0 // array buffer offset + ); + // Draw the triangle ! + glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle + glDisableVertexAttribArray(0); + glfwSwapBuffers(window); + glfwPollEvents(); + } + while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0); return 0; } diff --git a/shader.cpp b/shader.cpp @@ -0,0 +1,85 @@ +#include <fstream> +#include <iostream> +#include <sstream> +#include <vector> + +#include "shader.hpp" + +GLuint Shader::loadShaders(std::string vert_shader, std::string frag_shader) { + // Create the shaders + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + // Read the Vertex Shader code from the file + std::string VertexShaderCode; + std::ifstream VertexShaderStream(vert_shader, std::ios::in); + if (VertexShaderStream.is_open()) { + std::stringstream sstr; + sstr << VertexShaderStream.rdbuf(); + VertexShaderCode = sstr.str(); + VertexShaderStream.close(); + } + + // Read the Fragment Shader code from the file + std::string FragmentShaderCode; + std::ifstream FragmentShaderStream(frag_shader, std::ios::in); + if (FragmentShaderStream.is_open()) { + std::stringstream sstr; + sstr << FragmentShaderStream.rdbuf(); + FragmentShaderCode = sstr.str(); + FragmentShaderStream.close(); + } + + GLint Result = GL_FALSE; + int InfoLogLength; + + // Compile Vertex Shader + char const * VertexSourcePointer = VertexShaderCode.c_str(); + glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (!InfoLogLength) { + std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); + printf("%sn", &VertexShaderErrorMessage[0]); + } + + // Compile Fragment Shader + char const * FragmentSourcePointer = FragmentShaderCode.c_str(); + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (!InfoLogLength) { + std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); + printf("%sn", &FragmentShaderErrorMessage[0]); + } + + // Link the program + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + // Check the program + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (!InfoLogLength) { + std::vector<char> ProgramErrorMessage(InfoLogLength + 1); + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); + printf("%sn", &ProgramErrorMessage[0]); + } + + glDetachShader(ProgramID, VertexShaderID); + glDetachShader(ProgramID, FragmentShaderID); + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} diff --git a/shader.hpp b/shader.hpp @@ -0,0 +1,8 @@ +#include <GL/glew.h> + +#include <string> + +class Shader { +public: + static GLuint loadShaders(std::string vert_shader, std::string frag_shader); +}; diff --git a/vertex.vert b/vertex.vert @@ -0,0 +1,8 @@ +#version 330 core + +layout(location = 0) in vec3 vertexPosition_modelspace; + +void main() { + gl_Position.xyz = vertexPosition_modelspace; + gl_Position.w = 1.0; +}