├── include ├── shaders │ ├── line.frag │ ├── main.frag │ ├── main.vert │ ├── point.vert │ ├── line.vert │ └── point.frag ├── pline.h ├── pquad.h ├── pcircle.h ├── pshader.h └── psketch.h ├── test ├── src │ ├── main.cpp │ └── sketch.cpp ├── include │ └── sketch.h └── CMakeLists.txt ├── src ├── pcircle.cpp ├── pquad.cpp ├── pline.cpp ├── pshader.cpp └── psketch.cpp ├── cmake-modules └── FindSOIL.cmake ├── README.md ├── CMakeLists.txt └── .tdlist /include/shaders/line.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec3 color; 4 | 5 | uniform vec3 stroke; 6 | 7 | void main() { 8 | color = stroke; 9 | } 10 | -------------------------------------------------------------------------------- /test/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sketch.h" 3 | 4 | int main() { 5 | Sketch * s = new Sketch(); 6 | s->run(); 7 | delete(s); 8 | } 9 | -------------------------------------------------------------------------------- /include/shaders/main.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 out_color; 4 | 5 | uniform vec3 fillColor; 6 | 7 | void main() { 8 | out_color = vec4(fillColor, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /include/shaders/main.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec2 in_pos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 projection; 6 | 7 | void main() { 8 | gl_Position = projection * model * vec4(in_pos, 0.0, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /include/shaders/point.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | uniform mat4 model; 4 | uniform mat4 projection; 5 | uniform int strokeWeight; 6 | 7 | void main() { 8 | gl_PointSize = strokeWeight * 2; 9 | gl_Position = projection * model * vec4(0.0, 0.0, 0.0, 1.0); 10 | } 11 | -------------------------------------------------------------------------------- /test/include/sketch.h: -------------------------------------------------------------------------------- 1 | #ifndef SKETCH_H 2 | #define SKETCH_H 3 | 4 | #include "psketch.h" 5 | 6 | class Sketch : public PSketch { 7 | public: 8 | Sketch(); 9 | void setup(); 10 | void draw(); 11 | void keyEvent(int key, int action); 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /include/shaders/line.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec2 in_pos; 4 | layout (location = 1) in vec2 in_norm; 5 | 6 | uniform mat4 projection; 7 | uniform mat4 model; 8 | 9 | void main() { 10 | gl_Position = projection * model * vec4(in_pos + in_norm, 0, 1); 11 | } 12 | -------------------------------------------------------------------------------- /include/shaders/point.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec3 color; 4 | 5 | uniform vec3 stroke; 6 | 7 | void main() { 8 | float r = 0.0, delta = 0.0, alpha = 1.0; 9 | vec2 cxy = 2.0 * gl_PointCoord - 1.0; 10 | r = dot(cxy, cxy); 11 | if (r > 1.0) { 12 | discard; 13 | } 14 | color = stroke * (alpha); 15 | } 16 | -------------------------------------------------------------------------------- /include/pline.h: -------------------------------------------------------------------------------- 1 | #ifndef PLINE_H 2 | #define PLINE_H 3 | 4 | #define GLEW_STATIC 5 | #include 6 | #include 7 | #include "glm/glm.hpp" 8 | #include "glm/gtc/matrix_transform.hpp" 9 | 10 | class PLine { 11 | public: 12 | PLine(); 13 | ~PLine(); 14 | GLuint getVao(); 15 | private: 16 | GLuint vao; 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/pquad.h: -------------------------------------------------------------------------------- 1 | #ifndef PQUAD_H 2 | #define PQUAD_H 3 | 4 | #define GLEW_STATIC 5 | #include 6 | #include 7 | #include "glm/glm.hpp" 8 | #include "glm/gtc/matrix_transform.hpp" 9 | 10 | class PQuad { 11 | public: 12 | PQuad(); 13 | ~PQuad(); 14 | GLuint getVao(); 15 | private: 16 | GLuint vao; 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/pcircle.h: -------------------------------------------------------------------------------- 1 | #ifndef PCIRCLE_H 2 | #define PCIRCLE_H 3 | 4 | #define GLEW_STATIC 5 | #include 6 | #include 7 | #include "glm/glm.hpp" 8 | #include "glm/gtc/matrix_transform.hpp" 9 | 10 | class PCircle { 11 | public: 12 | PCircle(); 13 | ~PCircle(); 14 | GLuint getVao(); 15 | private: 16 | GLuint vao; 17 | int res = 360; 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | project(processing-cpp-test) 3 | 4 | set(SRC src/main.cpp 5 | src/sketch.cpp) 6 | 7 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") 8 | include_directories(include /usr/local/include /usr/local/include/processing-cpp) 9 | add_executable(processing-cpp-test ${SRC}) 10 | if(APPLE) 11 | target_link_libraries(processing-cpp-test "/usr/local/lib/libprocessing-cpp.dylib") 12 | elseif(UNIX) 13 | target_link_libraries(processing-cpp-test "/usr/local/lib/libprocessing-cpp.so") 14 | endif(APPLE) 15 | -------------------------------------------------------------------------------- /test/src/sketch.cpp: -------------------------------------------------------------------------------- 1 | #include "sketch.h" 2 | 3 | int t = 0; 4 | 5 | Sketch::Sketch() : PSketch() { 6 | size(800, 800); 7 | } 8 | 9 | void Sketch::setup() { 10 | stroke(255, 255, 255); 11 | } 12 | 13 | void Sketch::draw() { 14 | background(242); 15 | for(int i = 0; i < 360; i+=3) { 16 | float x = cos(radians(i)) * 50 + WIDTH / 2; 17 | float y = sin(radians(i)) * 100 + HEIGHT / 2; 18 | float w = sin(radians(t + i)) * 200; 19 | w = abs(w); 20 | 21 | float col = map(i, 0, 360, 0, 255); 22 | fill(col, col, col); 23 | 24 | fill(col, 0, 88); 25 | ellipse(x, y, w, w); 26 | } 27 | t++; 28 | } 29 | 30 | 31 | void Sketch::keyEvent(int key, int action) { 32 | } 33 | -------------------------------------------------------------------------------- /include/pshader.h: -------------------------------------------------------------------------------- 1 | #ifndef PSHADER_H 2 | #define PSHADER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | std::string load(std::string path); 13 | 14 | class PShader { 15 | public: 16 | PShader(std::string vertexPath, std::string fragmentPath); 17 | ~PShader(); 18 | 19 | void bind(); 20 | void unbind(); 21 | GLuint getID(); 22 | 23 | void uniform3f(GLchar * uniformVariable, glm::vec3 value); 24 | void uniform4m(GLchar * uniformVariable, glm::mat4 value); 25 | void uniform1i(GLchar * uniformVariable, int value); 26 | void uniform1f(GLchar * uniformVariable, float value); 27 | private: 28 | GLuint id; 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/pcircle.cpp: -------------------------------------------------------------------------------- 1 | #include "pcircle.h" 2 | 3 | PCircle::PCircle() { 4 | float vertices[2*res+2]; 5 | vertices[0] = 0.0f; 6 | vertices[1] = 0.0f; 7 | for(int i = 0; i < res; i++) { 8 | vertices[2+2*i] = cos(i); 9 | vertices[2+2*i+1] = sin(i); 10 | } 11 | 12 | glGenVertexArrays(1, &vao); 13 | glBindVertexArray(vao); 14 | 15 | GLuint vbo; 16 | glGenBuffers(1, &vbo); 17 | glBindBuffer(GL_ARRAY_BUFFER, vbo); 18 | glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 19 | glEnableVertexAttribArray(0); 20 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); 21 | glBindBuffer(GL_ARRAY_BUFFER, 0); 22 | glBindVertexArray(0); 23 | } 24 | 25 | PCircle::~PCircle() { 26 | 27 | } 28 | 29 | GLuint PCircle::getVao() { 30 | return vao; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /cmake-modules/FindSOIL.cmake: -------------------------------------------------------------------------------- 1 | # Find SOIL 2 | # Find the SOIL includes and library 3 | # 4 | # SOIL_INCLUDE_DIRS - where to find SOIL.h, etc. 5 | # SOIL_LIBRARIES - List of libraries when using SOIL. 6 | # SOIL_FOUND - True if SOIL found. 7 | # 8 | # Based on the FindZLIB.cmake module. 9 | 10 | IF (SOIL_INCLUDE_DIR) 11 | # Already in cache, be silent 12 | SET(SOIL_FIND_QUIETLY TRUE) 13 | ENDIF (SOIL_INCLUDE_DIR) 14 | 15 | FIND_PATH(SOIL_INCLUDE_DIR SOIL.h PATH_SUFFIXES include/SOIL include) 16 | 17 | SET(SOIL_NAMES SOIL Soil soil) 18 | FIND_LIBRARY(SOIL_LIBRARY NAMES ${SOIL_NAMES} ) 19 | MARK_AS_ADVANCED( SOIL_LIBRARY SOIL_INCLUDE_DIR ) 20 | 21 | # Per-recommendation 22 | SET(SOIL_INCLUDE_DIRS "${SOIL_INCLUDE_DIR}") 23 | SET(SOIL_LIBRARIES "${SOIL_LIBRARY}") 24 | 25 | # handle the QUIETLY and REQUIRED arguments and set SOIL_FOUND to TRUE if 26 | # all listed variables are TRUE 27 | INCLUDE(FindPackageHandleStandardArgs) 28 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SOIL DEFAULT_MSG SOIL_LIBRARIES SOIL_INCLUDE_DIRS) 29 | -------------------------------------------------------------------------------- /src/pquad.cpp: -------------------------------------------------------------------------------- 1 | #include "pquad.h" 2 | 3 | PQuad::PQuad() { 4 | float vertices[] = { 5 | 1.0f, 1.0f, 6 | -1.0f, 1.0f, 7 | -1.0f, -1.0f, 8 | 1.0f, -1.0f 9 | }; 10 | 11 | unsigned int indices[] = { 12 | 0, 1, 2, 13 | 0, 2, 3 14 | }; 15 | 16 | glGenVertexArrays(1, &vao); 17 | glBindVertexArray(vao); 18 | 19 | GLuint vbo; 20 | glGenBuffers(1, &vbo); 21 | glBindBuffer(GL_ARRAY_BUFFER, vbo); 22 | glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 23 | glEnableVertexAttribArray(0); 24 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); 25 | 26 | GLuint ibo; 27 | glGenBuffers(1, &ibo); 28 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 29 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 30 | 31 | glBindBuffer(GL_ARRAY_BUFFER, 0); 32 | glBindVertexArray(0); 33 | } 34 | 35 | PQuad::~PQuad() { 36 | 37 | } 38 | 39 | GLuint PQuad::getVao() { 40 | return vao; 41 | } 42 | 43 | 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # processing-cpp 2 | 3 | `processing-cpp` is a port in C++ of the Processing library originally written in Java 4 | 5 | This port was made by [Clément Chaine](https://github.com/cchaine). 6 | 7 |

8 | capture d ecran 2018-11-01 a 21 35 10 9 |

10 | 11 | ## Install 12 | 13 | ``` 14 | git clone https://github.com/cchaine/processing-cpp.git 15 | cd processing-cpp 16 | cmake . 17 | make install 18 | ``` 19 | 20 | ## Getting started 21 | 22 | To start using the processing-cpp library, you need to create a `Sketch` class that inherits from the `PSketch` class 23 | 24 | ```cpp 25 | #ifndef SKETCH_H 26 | #define SKETCH_H 27 | 28 | #include "psketch.h" 29 | 30 | class Sketch : public PSketch { 31 | public: 32 | Sketch(); 33 | void setup(); 34 | void draw(); 35 | void keyEvent(int key, int action); 36 | }; 37 | 38 | #endif 39 | ``` 40 | 41 | ```cpp 42 | #include "sketch.h" 43 | 44 | int main() { 45 | Sketch * s = new Sketch(); 46 | s->run(); 47 | delete(s); 48 | } 49 | ``` 50 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | project(processing-cpp) 3 | set(CMAKE_BUILD_TYPE Debug) 4 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake-modules") 5 | 6 | set(SRC src/psketch.cpp 7 | src/pshader.cpp 8 | src/pquad.cpp 9 | src/pcircle.cpp 10 | src/pline.cpp) 11 | 12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 ") 13 | add_library(processing-cpp SHARED ${SRC}) 14 | 15 | find_package(OpenGL) 16 | find_package(GLEW REQUIRED) 17 | find_package(glfw3 REQUIRED) 18 | find_package(SOIL REQUIRED) 19 | set(INCLUDE_DIRS ${GLEW_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS} ${SOIL_INCLUDE_LIBS} ${OPENGL_INCLUDE_DIRS} "include") 20 | set(LIBRARIES glfw ${GLEW_LIBRARIES} ${PNG_LIBRARIES} ${SOIL_LIBRARIES} ${OPENGL_LIBRARY}) 21 | 22 | include_directories(${INCLUDE_DIRS}) 23 | target_link_libraries(processing-cpp ${LIBRARIES}) 24 | 25 | install(TARGETS processing-cpp DESTINATION "lib") 26 | install(FILES "include/pline.h" "include/shaders/line.vert" "include/shaders/line.frag" "include/psketch.h" "include/pcircle.h" "include/shaders/point.frag" "include/shaders/point.vert" "include/pquad.h" "include/pshader.h" "include/shaders/main.vert" "include/shaders/main.frag" DESTINATION "include/processing-cpp") 27 | -------------------------------------------------------------------------------- /src/pline.cpp: -------------------------------------------------------------------------------- 1 | #include "pline.h" 2 | 3 | PLine::PLine() { 4 | float vertices[] = { 5 | -1.0, 0.0, 6 | -1.0, 0.0, 7 | 1.0, 0.0, 8 | 1.0, 0.0 9 | }; 10 | 11 | unsigned int indices[] = { 12 | 0, 1, 2, 13 | 1, 2, 3 14 | }; 15 | 16 | float normals[] = { 17 | 0.0, -1.0, 18 | 0.0, 1.0, 19 | 0.0, -1.0, 20 | 0.0, 1.0 21 | }; 22 | 23 | glGenVertexArrays(1, &this->vao); 24 | glBindVertexArray(this->vao); 25 | 26 | GLuint vbo; 27 | glGenBuffers(1, &vbo); 28 | glBindBuffer(GL_ARRAY_BUFFER, vbo); 29 | glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 30 | glEnableVertexAttribArray(0); 31 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); 32 | 33 | GLuint ibo; 34 | glGenBuffers(1, &ibo); 35 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 36 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 37 | 38 | GLuint nbo; 39 | glGenBuffers(1, &nbo); 40 | glBindBuffer(GL_ARRAY_BUFFER, nbo); 41 | glBufferData(GL_ARRAY_BUFFER, sizeof(normals), normals, GL_STATIC_DRAW); 42 | glEnableVertexAttribArray(1); 43 | glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); 44 | 45 | } 46 | 47 | PLine::~PLine() { 48 | 49 | } 50 | 51 | GLuint PLine::getVao() { 52 | return this->vao; 53 | } 54 | -------------------------------------------------------------------------------- /.tdlist: -------------------------------------------------------------------------------- 1 | tdlist|203 2 | popStyle()::1f|1 3 | pushStyle()::1f|2 4 | redraw()::1f|3 5 | cursor()::1f|4 6 | frameRate()::1f|8 7 | frameRate::1f|9 8 | height::1f|11 9 | noCursor()::1f|12 10 | size()::1f|18 11 | width::1f|20 12 | ellipse rendering::0f|41 13 | createShape()::0f|47 14 | loadShape()::0f|48 15 | PShape type::0f|49 16 | arc()::0f|50 17 | ellipse()::1f|51 18 | line()::1f|52 19 | point()::1f|53 20 | quad()::0f|54 21 | rect()::1f|55 22 | triangle()::0f|56 23 | ellipseMode()::1f|65 24 | rectMode()::1f|66 25 | strokeCap()::1f|67 26 | strokeJoin()::1f|68 27 | strokeWeight()::1f|69 28 | endShape()::0f|75 29 | vertex()::0f|77 30 | shape()::0f|78 31 | shapeMode()::0f|79 32 | mouse managment::0f|80 33 | keyboard managment::0f|81 34 | popMatrix()::1f|92 35 | pushMatrix()::1f|94 36 | rotate()::1f|96 37 | scale()::1f|99 38 | translate()::1f|102 39 | background()::1f|103 40 | colorMode()::1f|105 41 | fill()::1f|106 42 | allow fill(int)::1i|107 43 | noFill()::0f|108 44 | noStroke()::0f|109 45 | stroke()::1f|110 46 | noise()::0f|183 47 | noiseDetail()::0f|184 48 | noiseSeed()::0f|185 49 | random()::0f|186 50 | randomGaussian()::0f|187 51 | randomSeed()::0f|188 52 | beginShape()::0f|191 53 | createImage()::0f|192 54 | PImage::0f|193 55 | image()::0f|194 56 | imageMode()::0f|195 57 | loadImage()::0f|196 58 | requestImage()::0f|197 59 | texture()::0f|198 60 | textureMode()::0f|199 61 | textureWrap()::0f|200 62 | text::0f|201 63 | map::0f|202 64 | -------------------------------------------------------------------------------- /src/pshader.cpp: -------------------------------------------------------------------------------- 1 | #include "pshader.h" 2 | 3 | PShader::PShader(std::string vertexPath, std::string fragmentPath) { 4 | std::string vertexCodeStr = load(vertexPath); 5 | const char* vertexCode = vertexCodeStr.c_str(); 6 | GLuint vertex = glCreateShader(GL_VERTEX_SHADER); 7 | glShaderSource(vertex, 1, &vertexCode, NULL); 8 | glCompileShader(vertex); 9 | GLint success; 10 | GLchar infoLog[512]; 11 | glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); 12 | if(!success) { 13 | glGetShaderInfoLog(vertex, 512, NULL, infoLog); 14 | std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; 15 | exit(-1); 16 | } 17 | 18 | std::string fragmentCodeStr = load(fragmentPath); 19 | const char* fragmentCode = fragmentCodeStr.c_str(); 20 | GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER); 21 | glShaderSource(fragment, 1, &fragmentCode, NULL); 22 | glCompileShader(fragment); 23 | glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); 24 | if(!success) { 25 | glGetShaderInfoLog(fragment, 512, NULL, infoLog); 26 | std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; 27 | exit(-1); 28 | } 29 | 30 | this->id = glCreateProgram(); 31 | glAttachShader(this->id, vertex); 32 | glAttachShader(this->id, fragment); 33 | glLinkProgram(this->id); 34 | glDeleteShader(vertex); 35 | glDeleteShader(fragment); 36 | } 37 | 38 | PShader::~PShader() { 39 | 40 | } 41 | 42 | void PShader::bind() { 43 | glUseProgram(this->id); 44 | } 45 | 46 | void PShader::unbind() { 47 | glUseProgram(0); 48 | } 49 | 50 | void PShader::uniform3f(GLchar * uniformVariable, glm::vec3 value) { 51 | this->bind(); 52 | GLint uniformLocation = glGetUniformLocation(this->id, uniformVariable); 53 | glUniform3f(uniformLocation, value.x, value.y, value.z); 54 | } 55 | 56 | void PShader::uniform4m(GLchar * uniformVariable, glm::mat4 value) { 57 | this->bind(); 58 | GLint uniformLocation = glGetUniformLocation(this->id, uniformVariable); 59 | glUniformMatrix4fv(uniformLocation, 1, GL_FALSE, glm::value_ptr(value)); 60 | } 61 | 62 | void PShader::uniform1i(GLchar * uniformVariable, int value) { 63 | this->bind(); 64 | GLint uniformLocation = glGetUniformLocation(this->id, uniformVariable); 65 | glUniform1i(uniformLocation, value); 66 | } 67 | 68 | std::string load(std::string path) { 69 | std::string content; 70 | std::ifstream fileStream(path, std::ios::in); 71 | if(!fileStream.is_open()) { 72 | std::cerr << "ERROR::FILELOADER::FILE DOESN'T EXIST" << std::endl; 73 | exit(-1); 74 | } 75 | std::string line = ""; 76 | while(!fileStream.eof()) { 77 | getline(fileStream, line); 78 | content.append(line + "\n"); 79 | } 80 | fileStream.close(); 81 | return content; 82 | } 83 | 84 | void PShader::uniform1f(GLchar * uniformVariable, float value) { 85 | this->bind(); 86 | GLint uniformLocation = glGetUniformLocation(this->id, uniformVariable); 87 | glUniform1f(uniformLocation, value); 88 | } 89 | 90 | GLuint PShader::getID() { 91 | return this->id; 92 | } 93 | -------------------------------------------------------------------------------- /include/psketch.h: -------------------------------------------------------------------------------- 1 | #ifndef PSKETCH_H 2 | #define PSKETCH_H 3 | 4 | #define GLEW_STATIC 5 | #define GLM_ENABLE_EXPERIMENTAL 6 | #include 7 | #include 8 | #include "glm/glm.hpp" 9 | #include 10 | #include "glm/gtc/matrix_transform.hpp" 11 | #include 12 | #include 13 | #include 14 | 15 | #include "pshader.h" 16 | #include "pquad.h" 17 | #include "pcircle.h" 18 | #include "pline.h" 19 | 20 | void key_callback(GLFWwindow * window, int key, int scancode, int action, int mode); 21 | 22 | enum ColorMode { RGB, HSB }; 23 | enum LineMode { ROUND, BEVEL, MILTER, SQUARE }; 24 | 25 | struct PTransformations { 26 | glm::vec2 translate = glm::vec2(0.0f, 0.0f); 27 | float rotate = 0.0f; 28 | glm::vec2 scale = glm::vec2(1.0f, 1.0f); 29 | }; 30 | 31 | struct PStyle { 32 | glm::vec3 fillColor = glm::vec3(1.0f, 1.0f, 1.0f); 33 | glm::vec3 stroke = glm::vec3(1.0f, 1.0f, 1.0f); 34 | int strokeWeight = 1; 35 | LineMode strokeCap = ROUND; 36 | LineMode strokeJoin = MILTER; 37 | }; 38 | 39 | class PSketch { 40 | public: 41 | PSketch(); 42 | ~PSketch(); 43 | virtual void run() final; 44 | 45 | virtual void setup(){}; 46 | virtual void draw(){}; 47 | 48 | virtual void background(int r, int g, int b) final; 49 | virtual void background(int c) final; 50 | virtual void frameRate(int frameRate) final; 51 | virtual void noLoop() final; 52 | virtual void fill(int r, int g, int b) final; 53 | virtual void fill(int c) final; 54 | virtual void rect(int x, int y, int width, int height) final; 55 | virtual void point(int x, int y) final; 56 | virtual void strokeWeight(int value) final; 57 | virtual void size(int width, int height) final; 58 | virtual void ellipse(int x, int y, int width, int height) final; 59 | virtual void translate(float x, float y) final; 60 | virtual void rotate(float angle) final; 61 | virtual void scale(float xRate, float yRate) final; 62 | virtual void scale(float rate) final; 63 | virtual void pushMatrix() final; 64 | virtual void popMatrix() final; 65 | virtual void rectMode(int mode) final; 66 | virtual void ellipseMode(int mode) final; 67 | virtual void colorMode(ColorMode mode) final; 68 | virtual void stroke(int r, int g, int b) final; 69 | virtual void noCursor() final; 70 | virtual void cursor() final; 71 | virtual void redraw() final; 72 | virtual void keyEvent(int key, int action) {}; 73 | virtual void strokeCap(LineMode kind) final; 74 | virtual void strokeJoin(LineMode kind) final; 75 | virtual void pushStyle() final; 76 | virtual void popStyle() final; 77 | virtual void line(int x1, int y1, int x2, int y2) final; 78 | virtual float map(float value, float start1, float stop1, float start2, float stop2) final; 79 | virtual float radians(float degree) final; 80 | 81 | protected: 82 | int WIDTH = 100; 83 | int HEIGHT = 100; 84 | int FRAMERATE = 0; 85 | double MOUSEX = 0; 86 | double MOUSEY = 0; 87 | const int CENTER = 0; 88 | const int CORNER = 1; 89 | 90 | private: 91 | GLFWwindow * window = nullptr; 92 | int target_fps = 60; 93 | PShader * shader = nullptr; 94 | PShader * pointShader = nullptr; 95 | PShader * lineShader = nullptr; 96 | PQuad * quadObj = nullptr; 97 | PCircle * circleObj = nullptr; 98 | PLine * lineObj = nullptr; 99 | GLuint pointVao; 100 | std::vector transformations_stack = std::vector(); 101 | std::vector style_stack = std::vector(); 102 | bool needRedraw = false; 103 | 104 | glm::mat4 genModelMat(int x, int y, int width, int height); 105 | glm::vec3 HSBtoRGB(int h, int s, int b); 106 | 107 | PStyle style; 108 | PTransformations transformations; 109 | int RECTMODE = 1; 110 | int ELLIPSEMODE = 0; 111 | ColorMode COLORMODE = RGB; 112 | }; 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /src/psketch.cpp: -------------------------------------------------------------------------------- 1 | #include "psketch.h" 2 | 3 | PSketch* thisPointerForCallback; 4 | PSketch::PSketch(){ 5 | // rand init 6 | srand(time(NULL)); 7 | 8 | thisPointerForCallback = this; 9 | } 10 | 11 | PSketch::~PSketch() { 12 | } 13 | 14 | void key_callback(GLFWwindow * window, int key, int scancode, int action, int mode){ 15 | thisPointerForCallback->keyEvent(key, action); 16 | } 17 | 18 | void PSketch::run() { 19 | if(!glfwInit()) { 20 | exit(-1); 21 | } 22 | 23 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 24 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 25 | glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 26 | glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 27 | glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 28 | 29 | this->window = glfwCreateWindow(this->WIDTH, this->HEIGHT, "processing-cpp", nullptr, nullptr); 30 | glfwMakeContextCurrent(this->window); 31 | glfwSetKeyCallback(this->window, key_callback); 32 | 33 | glewExperimental = GL_TRUE; 34 | glewInit(); 35 | glEnable(GL_PROGRAM_POINT_SIZE); 36 | 37 | int widthW, heightW; 38 | glfwGetFramebufferSize(this->window, &widthW, &heightW); 39 | glViewport(0, 0, widthW, heightW); 40 | 41 | // setup 42 | 43 | glm::mat4 projection = glm::ortho(0.0f, static_cast(WIDTH), 0.0f, static_cast(HEIGHT), -1.0f, 1.0f); 44 | // rect setup 45 | shader = new PShader("/usr/local/include/processing-cpp/main.vert", "/usr/local/include/processing-cpp/main.frag"); 46 | shader->uniform4m((char*)"projection", projection); 47 | quadObj = new PQuad(); 48 | 49 | circleObj = new PCircle(); 50 | // point setup 51 | pointShader = new PShader("/usr/local/include/processing-cpp/point.vert", "/usr/local/include/processing-cpp/point.frag"); 52 | pointShader->uniform4m((char*)"projection", projection); 53 | // line setup 54 | lineShader = new PShader("/usr/local/include/processing-cpp/line.vert", "/usr/local/include/processing-cpp/line.frag"); 55 | lineShader->uniform4m((char*)"projection", projection); 56 | lineObj = new PLine(); 57 | 58 | // gen the vao for the point render 59 | glGenVertexArrays(1, &pointVao); 60 | 61 | this->setup(); 62 | 63 | // framerate regulation init 64 | float interval = 1.0 / this->target_fps; 65 | float previousTime = glfwGetTime(); 66 | // fps count init 67 | float previousCount = glfwGetTime(); 68 | int frameCount = 0; 69 | 70 | while (!glfwWindowShouldClose(this->window)) { 71 | glfwGetCursorPos(window, &MOUSEX, &MOUSEY); 72 | // reverts the mouseY axis 73 | MOUSEY = HEIGHT - MOUSEY; 74 | 75 | this->draw(); 76 | 77 | //Reset matrix 78 | if(transformations_stack.size() != 0) { 79 | std::cerr << "ERROR::SKETCH::A MATRIX WAS NOT POPED AT THE END OF THE DRAW FUNCTION" << std::endl; 80 | exit(-1); 81 | } 82 | 83 | // resets the transformation 84 | this->transformations = PTransformations(); 85 | this->transformations_stack.clear(); 86 | 87 | glfwSwapBuffers(this->window); 88 | glfwPollEvents(); 89 | 90 | // framerate regulation 91 | while(glfwGetTime() - previousTime < interval && !glfwWindowShouldClose(this->window) && !needRedraw) { 92 | glfwPollEvents(); 93 | } 94 | previousTime = glfwGetTime(); 95 | 96 | // fps count 97 | frameCount++; 98 | if(glfwGetTime() - previousCount > 1.0) { 99 | this->FRAMERATE = frameCount; 100 | previousCount = glfwGetTime(); 101 | frameCount = 0; 102 | } 103 | 104 | //Resets the redraw flag 105 | needRedraw = false; 106 | } 107 | 108 | glfwTerminate(); 109 | } 110 | 111 | void PSketch::background(int r, int g, int b) { 112 | glClearColor(float(r) / 255.0, float(g) / 255.0, float(b) / 255.0, 1.0f); 113 | glClear(GL_COLOR_BUFFER_BIT); 114 | } 115 | 116 | void PSketch::background(int c) { 117 | background(c, c, c); 118 | } 119 | 120 | void PSketch::frameRate(int frameRate) { 121 | this->target_fps = frameRate; 122 | } 123 | 124 | void PSketch::fill(int r, int g, int b) { 125 | if(COLORMODE == HSB) { 126 | glm::vec3 hsb = HSBtoRGB(r, g, b); 127 | this->style.fillColor = glm::vec3(float(hsb.r) / 255.0, float(hsb.g) / 255.0, float(hsb.b) / 255.0); 128 | } else { 129 | this->style.fillColor = glm::vec3(float(r) / 255.0, float(g) / 255.0, float(b) / 255.0); 130 | } 131 | } 132 | 133 | void PSketch::fill(int c) { 134 | if(COLORMODE != HSB) { 135 | fill(c, c, c); 136 | } else { 137 | std::cerr << "ERROR::SKETCH::CANNOT USE 1 VALUE FOR A HSB COLOR" << std::endl; 138 | exit(-1); 139 | } 140 | } 141 | 142 | void PSketch::rect(int x, int y, int width, int height) { 143 | shader->bind(); 144 | shader->uniform3f((char*)"fillColor", this->style.fillColor); 145 | 146 | glm::mat4 model = genModelMat(x + RECTMODE*(width / 2), y - RECTMODE*(width / 2), width, height); 147 | shader->uniform4m((char*)"model", model); 148 | 149 | glBindVertexArray(quadObj->getVao()); 150 | glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 151 | glBindVertexArray(0); 152 | shader->unbind(); 153 | } 154 | 155 | void PSketch::noLoop() { 156 | frameRate(0); 157 | } 158 | 159 | void PSketch::point(int x, int y) { 160 | pointShader->uniform1i((char*)"strokeWeight", this->style.strokeWeight); 161 | pointShader->uniform3f((char*)"stroke", this->style.stroke); 162 | 163 | glm::mat4 model = genModelMat(x, y, 0, 0); 164 | pointShader->uniform4m((char*)"model", model); 165 | 166 | pointShader->bind(); 167 | glBindVertexArray(pointVao); 168 | glDrawArrays(GL_POINTS, 0, 1); 169 | glBindVertexArray(0); 170 | pointShader->unbind(); 171 | } 172 | 173 | void PSketch::strokeWeight(int value) { 174 | this->style.strokeWeight = value; 175 | if(value > 120) { 176 | this->style.strokeWeight = 120; 177 | } 178 | } 179 | 180 | void PSketch::size(int width, int height) { 181 | if(this->window == nullptr) { 182 | this->WIDTH = width; 183 | this->HEIGHT = height; 184 | }else{ 185 | std::cerr << "ERROR::SKETCH::SIZE SHOULD BE CALLED FROM THE SKETCH CONSTRUCTOR" << std::endl; 186 | exit(-1); 187 | } 188 | } 189 | 190 | void PSketch::ellipse(int x, int y, int width, int height) { 191 | shader->bind(); 192 | shader->uniform3f((char*)"fillColor", this->style.fillColor); 193 | 194 | glm::mat4 model = genModelMat(x + ELLIPSEMODE*(width / 2), y - ELLIPSEMODE*(height / 2), width, height); 195 | shader->uniform4m((char*)"model", model); 196 | 197 | glBindVertexArray(circleObj->getVao()); 198 | glDrawArrays(GL_TRIANGLE_FAN, 0, 362); 199 | glBindVertexArray(0); 200 | shader->unbind(); 201 | } 202 | 203 | void PSketch::translate(float x, float y) { 204 | this->transformations.translate.x += x; 205 | this->transformations.translate.y += y; 206 | } 207 | 208 | void PSketch::rotate(float angle) { 209 | this->transformations.rotate += angle; 210 | } 211 | 212 | void PSketch::scale(float xRate, float yRate) { 213 | this->transformations.scale.x += xRate; 214 | this->transformations.scale.y += yRate; 215 | } 216 | 217 | void PSketch::scale(float rate) { 218 | scale(rate, rate); 219 | } 220 | 221 | glm::mat4 PSketch::genModelMat(int x, int y, int width, int height) { 222 | glm::mat4 model = glm::mat4(1.0f); 223 | model = glm::translate(model, glm::vec3(x + transformations.translate.x, y + transformations.translate.y, 0)); 224 | model = glm::rotate(model, transformations.rotate, glm::vec3(0, 0, 1)); 225 | model = glm::scale(model, glm::vec3((width / 2) * transformations.scale.x, (height / 2) * transformations.scale.y, 1)); 226 | return model; 227 | } 228 | 229 | void PSketch::pushMatrix() { 230 | transformations_stack.push_back(transformations); 231 | } 232 | 233 | void PSketch::popMatrix() { 234 | if(transformations_stack.size() == 0) { 235 | std::cerr << "ERROR::SKETCH::PUSHMATRIX SHOULD BE CALLED BEFORE POPMATRIX" << std::endl; 236 | exit(-1); 237 | } 238 | transformations = transformations_stack.back(); 239 | transformations_stack.pop_back(); 240 | } 241 | 242 | void PSketch::ellipseMode(int mode) { 243 | if(mode == CENTER || mode == CORNER) { 244 | ELLIPSEMODE = mode; 245 | } else { 246 | std::cerr << "ERROR::SKETCH::THIS IS NOT A VALID ELLIPSEMODE" << std::endl; 247 | exit(-1); 248 | } 249 | } 250 | 251 | void PSketch::rectMode(int mode) { 252 | if(mode == CENTER || mode == CORNER) { 253 | RECTMODE = mode; 254 | } else { 255 | std::cerr << "ERROR::SKETCH::THIS IS NOT A VALID RECTMODE" << std::endl; 256 | exit(-1); 257 | } 258 | } 259 | 260 | void PSketch::colorMode(ColorMode mode) { 261 | if(mode == HSB || mode == RGB) { 262 | this->COLORMODE = mode; 263 | } else { 264 | std::cerr << "ERROR::SKETCH::THIS IS NOT A VALID COLORMODE" << std::endl; 265 | exit(-1); 266 | } 267 | } 268 | 269 | glm::vec3 PSketch::HSBtoRGB(int h, int s, int b) { 270 | glm::vec3 rgb; 271 | glm::vec3 hsb = glm::vec3(float(h) / 255.0, float(s) / 255.0, float(b) / 255.0); 272 | 273 | int i = floor(hsb.r * 6); 274 | float f = hsb.r * 6 - i; 275 | float p = hsb.b * (1 - hsb.g); 276 | float q = hsb.b * (1 - f * hsb.g); 277 | float t = hsb.b * (1 - (1 - f) * hsb.g); 278 | 279 | switch(i % 6){ 280 | case 0: rgb.r = hsb.b, rgb.g = t, rgb.b = p; break; 281 | case 1: rgb.r = q, rgb.g = hsb.b, rgb.b = p; break; 282 | case 2: rgb.r = p, rgb.g = hsb.b, rgb.b = t; break; 283 | case 3: rgb.r = p, rgb.g = q, rgb.b = hsb.b; break; 284 | case 4: rgb.r = t, rgb.g = p, rgb.b = hsb.b; break; 285 | case 5: rgb.r = hsb.b, rgb.g = p, rgb.b = q; break; 286 | } 287 | rgb.r *= 255; 288 | rgb.g *= 255; 289 | rgb.b *= 255; 290 | return rgb; 291 | } 292 | 293 | void PSketch::stroke(int r, int g, int b) { 294 | if(COLORMODE == HSB) { 295 | glm::vec3 hsb = HSBtoRGB(r, g, b); 296 | this->style.stroke = glm::vec3(float(hsb.r) / 255.0, float(hsb.g) / 255.0, float(hsb.b) / 255.0); 297 | } else { 298 | this->style.stroke = glm::vec3(float(r) / 255.0, float(g) / 255.0, float(b) / 255.0); 299 | } 300 | } 301 | 302 | void PSketch::noCursor() { 303 | glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); 304 | } 305 | 306 | void PSketch::cursor() { 307 | glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); 308 | } 309 | 310 | void PSketch::redraw() { 311 | needRedraw = true; 312 | } 313 | 314 | void PSketch::strokeCap(LineMode kind) { 315 | if(kind == ROUND || kind == SQUARE) { 316 | this->style.strokeCap = kind; 317 | } else { 318 | std::cerr << "ERROR::SKETCH::THIS IS NOT A VALID STROKECAP" << std::endl; 319 | exit(-1); 320 | } 321 | } 322 | 323 | void PSketch::strokeJoin(LineMode kind) { 324 | if(kind == ROUND || kind == MILTER || kind == BEVEL) { 325 | this->style.strokeJoin = kind; 326 | } else { 327 | std::cerr << "ERROR::SKETCH::THIS IS NOT A VALID STROKEJOIN" << std::endl; 328 | exit(-1); 329 | } 330 | } 331 | 332 | void PSketch::pushStyle() { 333 | style_stack.push_back(style); 334 | } 335 | 336 | void PSketch::popStyle() { 337 | if(style_stack.size() == 0) { 338 | std::cerr << "ERROR::SKETCH::PUSHSTYLE SHOULD BE CALLED BEFORE POPSTYLE" << std::endl; 339 | exit(-1); 340 | } 341 | style = style_stack.back(); 342 | style_stack.pop_back(); 343 | } 344 | 345 | void PSketch::line(int x1, int y1, int x2, int y2) { 346 | float dist = sqrt(pow(x2-x1, 2) + pow(y2-y1, 2)) / 2; 347 | float angle = atan2(y2-y1, x2 - x1); 348 | 349 | glm::mat4 model = glm::mat4(); 350 | model = glm::translate(model, glm::vec3(x1, y1, 0.0)); 351 | model = glm::rotate(model, angle, glm::vec3(0.0, 0.0, 1.0)); 352 | model = glm::translate(model, glm::vec3(dist, 0.0, 0.0)); 353 | model = glm::rotate(model, 0.0f, glm::vec3(0.0f, 0.0f, 1.0f)); 354 | model = glm::scale(model, glm::vec3(dist, float(style.strokeWeight) / 2.0, 0.0f)); 355 | lineShader->uniform4m((char*)"model", model); 356 | 357 | lineShader->uniform3f((char*)"stroke", style.stroke); 358 | 359 | lineShader->bind(); 360 | glBindVertexArray(lineObj->getVao()); 361 | glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 362 | glBindVertexArray(0); 363 | lineShader->unbind(); 364 | 365 | if(style.strokeCap == ROUND) { 366 | point(x1, y1); 367 | point(x2, y2); 368 | } 369 | } 370 | 371 | float PSketch::map(float value, float start1, float stop1, float start2, float stop2) { 372 | if(start1 <= value && value <= stop1) { 373 | return (stop2 - start2) / (stop1 - start1) * value; 374 | } else { 375 | std::cerr << "ERROR::MAP::VALUE BOUNDARIES ARE NOT CORRECT" << std::endl; 376 | exit(-1); 377 | } 378 | } 379 | 380 | float PSketch::radians(float degree) { 381 | return degree * M_PI / 180.0; 382 | } 383 | --------------------------------------------------------------------------------