diff --git a/CMakeLists.txt b/CMakeLists.txt index 61301a1..18cea82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,4 +22,6 @@ add_subdirectory(DataAnalysis) add_subdirectory(Objects) add_subdirectory(Widgets) add_subdirectory(LibraryViewer) -add_subdirectory(Sketch3D) \ No newline at end of file +add_subdirectory(RasterRender) +add_subdirectory(Sketch3D) +add_subdirectory(GeometryEditor2D) \ No newline at end of file diff --git a/GeometryEditor2D/CMakeLists.txt b/GeometryEditor2D/CMakeLists.txt new file mode 100644 index 0000000..1cc6125 --- /dev/null +++ b/GeometryEditor2D/CMakeLists.txt @@ -0,0 +1,22 @@ +project(GeometryEditor2D) + +### ---------------------- Externals --------------------- ### +set(BINDINGS_INCLUDE ../Externals/glfw/include) +set(BINDINGS_LIBS glfw Imgui) + +### ---------------------- Static Library --------------------- ### +file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp") +file(GLOB HEADERS "./public/*.hpp" "./public/*/*.hpp") + +add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) + +target_include_directories(${PROJECT_NAME} PUBLIC ./public/ ${BINDINGS_INCLUDE} ./ext/) +target_link_libraries(${PROJECT_NAME} PUBLIC Graphics Connection Widgets Math RasterRender) +target_link_libraries(${PROJECT_NAME} PUBLIC ${BINDINGS_LIBS}) + +### -------------------------- Applications -------------------------- ### +add_executable(geomEdit2d ./applications/Entry.cpp) +target_link_libraries(geomEdit2d ${PROJECT_NAME}) + +file(COPY "rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") +file(COPY "rsc/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") diff --git a/GeometryEditor2D/applications/Entry.cpp b/GeometryEditor2D/applications/Entry.cpp new file mode 100644 index 0000000..6062084 --- /dev/null +++ b/GeometryEditor2D/applications/Entry.cpp @@ -0,0 +1,39 @@ + +#include "EditorWidget.hpp" + +#include "GraphicApplication.hpp" + +using namespace tp; + +class EditorGUI : public Application { +public: + EditorGUI() { + Vec2F renderResolution = { 1000, 1000 }; + auto canvas = this->mGraphics->getCanvas(); + mGui = new EditorWidget(canvas, &geometry, renderResolution); + // + } + + ~EditorGUI() override { delete mGui; } + + void processFrame(EventHandler* eventHandler) override { + auto rec = RectF({ 0, 0 }, mWindow->getSize()); + mGui->proc(*eventHandler, rec, rec); + } + + void drawFrame(Canvas* canvas) override { mGui->draw(*canvas); } + +private: + Geometry geometry; + EditorWidget* mGui; +}; + +int main() { + GlobalGUIConfig mConfig; + gGlobalGUIConfig = &mConfig; + + { + EditorGUI gui; + gui.run(); + } +} diff --git a/GeometryEditor2D/private/Geometry.cpp b/GeometryEditor2D/private/Geometry.cpp new file mode 100644 index 0000000..e69de29 diff --git a/GeometryEditor2D/private/Render.cpp b/GeometryEditor2D/private/Render.cpp new file mode 100644 index 0000000..5d18f1c --- /dev/null +++ b/GeometryEditor2D/private/Render.cpp @@ -0,0 +1,76 @@ +#include "Render.hpp" + +#include "GraphicsApi.hpp" + +using namespace tp; + +struct Shape { + float buffer[6] = { + 0, 0, 1, 0, 0, 1, + }; + + GLuint vbo_id = 0; + GLuint vbo_len = 6; + + Shape() { + glGenBuffers(1, &vbo_id); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ARRAY_BUFFER, sizeof(buffer), buffer, GL_STATIC_COPY); + } + + void drawCall() { + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), nullptr); + glEnableVertexAttribArray(0); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + glDisableVertexAttribArray(0); + glBindVertexArray(0); + } + + ~Shape() { glDeleteBuffers(1, &vbo_id); } +}; + +Render::Render(Vec2F renderResolution) : + mRenderBuffer(renderResolution) { + + mDefaultShader.load("rsc/shaders/default.vert", nullptr, "rsc/shaders/default.frag", true); +} + +Render::~Render() {} + +uint4 Render::getRenderBuffer() { return mRenderBuffer.texId(); } + +Vec2F Render::getBufferSize() { return mRenderBuffer.getSize(); } + +void Render::render(const Geometry& geometry, Vec2F size) { + + static Shape shape; + + mRenderBuffer.mClearCol = { 0.1f, 0.1f, 0.1f, 1.f }; + + mRenderBuffer.beginDraw(); + mRenderBuffer.clear(); + + { + mDefaultShader.bind(); + + static auto uniform_color = mDefaultShader.getu("Color"); + static auto uniform_scale = mDefaultShader.getu("Viewport"); + + RGBA col = { 0, 0, 1.f, 1.f }; + RectF viewport = { 0.0f, 0.0f, 1.f, 1.f }; + viewport.w = viewport.z * (size.y / size.x); + + glUniform4fv(uniform_color, 1, &col.r); + glUniform4fv(uniform_scale, 1, &viewport.x); + + shape.drawCall(); + + mDefaultShader.unbind(); + } + + mRenderBuffer.endDraw(); +} diff --git a/GeometryEditor2D/public/EditorWidget.hpp b/GeometryEditor2D/public/EditorWidget.hpp new file mode 100644 index 0000000..1288b32 --- /dev/null +++ b/GeometryEditor2D/public/EditorWidget.hpp @@ -0,0 +1,68 @@ +#include "Widgets.hpp" +#include "Render.hpp" + +namespace tp { + template + class ViewportWidget : public Widget { + public: + explicit ViewportWidget(Canvas* canvas, Geometry* geometry, Vec2F renderResolution) : + mRender(renderResolution) { + this->createConfig("ViewportWidget"); + mImage = canvas->createImageFromTextId(mRender.getRenderBuffer(), mRender.getBufferSize()); + mCanvas = canvas; + } + + ~ViewportWidget() { mCanvas->deleteImageHandle(mImage); } + + void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { + this->mArea = aArea; + this->mVisible = areaParent.isOverlap(aArea); + if (!this->mVisible) return; + + mRender.render(*mGeometry, this->mArea.size); + } + + void draw(Canvas& canvas) override { + if (!this->mVisible) return; + + canvas.drawImage(this->mArea, &mImage); + } + + public: + Render mRender; + Geometry* mGeometry = nullptr; + Canvas* mCanvas = nullptr; + Canvas::ImageHandle mImage; + }; + + template + class EditorWidget : public Widget { + public: + EditorWidget(Canvas* canvas, Geometry* geometry, Vec2F renderResolution) : + mViewport(canvas, geometry, renderResolution) { + this->createConfig("EditorWidget"); + this->addColor("Base", "Base"); + } + + void proc(const Events& events, const RectF& areaParent, const RectF& aArea) override { + this->mArea = aArea; + this->mVisible = areaParent.isOverlap(aArea); + if (!this->mVisible) return; + + mSplitView.proc(events, aArea, aArea); + mViewport.proc(events, aArea, mSplitView.getFirst()); + } + + void draw(Canvas& canvas) override { + if (!this->mVisible) return; + + canvas.rect(this->mArea, this->getColor("Base")); + mSplitView.draw(canvas); + mViewport.draw(canvas); + } + + public: + ViewportWidget mViewport; + SplitView mSplitView; + }; +} \ No newline at end of file diff --git a/GeometryEditor2D/public/Geometry.hpp b/GeometryEditor2D/public/Geometry.hpp new file mode 100644 index 0000000..13f4571 --- /dev/null +++ b/GeometryEditor2D/public/Geometry.hpp @@ -0,0 +1,8 @@ +#pragma once + +namespace tp { + class Geometry { + public: + Geometry() = default; + }; +} \ No newline at end of file diff --git a/GeometryEditor2D/public/Render.hpp b/GeometryEditor2D/public/Render.hpp new file mode 100644 index 0000000..310e9ed --- /dev/null +++ b/GeometryEditor2D/public/Render.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "Geometry.hpp" +#include "Rect.hpp" + +#include "FrameBuffer.hpp" +#include "Shader.hpp" + +namespace tp { + class Render { + public: + explicit Render(Vec2F renderResolution); + ~Render(); + + void render(const Geometry& geometry, Vec2F size); + uint4 getRenderBuffer(); + Vec2F getBufferSize(); + + private: + RenderBuffer mRenderBuffer; + RenderShader mDefaultShader; + }; +} \ No newline at end of file diff --git a/GeometryEditor2D/rsc/Font.ttf b/GeometryEditor2D/rsc/Font.ttf new file mode 100644 index 0000000..8a63054 Binary files /dev/null and b/GeometryEditor2D/rsc/Font.ttf differ diff --git a/GeometryEditor2D/rsc/shaders/default.frag b/GeometryEditor2D/rsc/shaders/default.frag new file mode 100644 index 0000000..0850bdc --- /dev/null +++ b/GeometryEditor2D/rsc/shaders/default.frag @@ -0,0 +1,9 @@ +#version 330 core + +uniform vec4 Color; + +out vec4 FragColor; + +void main() { + FragColor = vec4(1.f); +} \ No newline at end of file diff --git a/GeometryEditor2D/rsc/shaders/default.vert b/GeometryEditor2D/rsc/shaders/default.vert new file mode 100644 index 0000000..2ba27d7 --- /dev/null +++ b/GeometryEditor2D/rsc/shaders/default.vert @@ -0,0 +1,22 @@ +#version 330 core + +layout(location = 0) in vec2 point; + +uniform vec4 Viewport; + +void main() { + vec2 transformedPoint = point; + + transformedPoint.x = transformedPoint.x - Viewport.x; + transformedPoint.y = transformedPoint.y - Viewport.y; + + transformedPoint.x = transformedPoint.x / Viewport.z; + transformedPoint.y = transformedPoint.y / Viewport.w; + + transformedPoint.y = -transformedPoint.y; + + transformedPoint.y = transformedPoint.y * 2; + transformedPoint.x = transformedPoint.x * 2; + + gl_Position = vec4(transformedPoint.x - 1, transformedPoint.y + 1, 1.0, 1.0); +} \ No newline at end of file diff --git a/Graphics/public/Graphics.hpp b/Graphics/public/Graphics.hpp index 6eb5aa6..4d35595 100644 --- a/Graphics/public/Graphics.hpp +++ b/Graphics/public/Graphics.hpp @@ -62,7 +62,7 @@ namespace tp { ImageHandle createImageFromTextId(ualni id, Vec2F size); void deleteImageHandle(ImageHandle image); - void drawImage(const RectF& rec, ImageHandle* image, halnf angle, halnf alpha, halnf rounding); + void drawImage(const RectF& rec, ImageHandle* image, halnf angle = 0, halnf alpha = 1.f, halnf rounding = 0.f); private: Buffer mScissors; @@ -71,7 +71,9 @@ namespace tp { class Graphics { public: - explicit Graphics(Window* window) : mGui(window), mCanvas(window) {} + explicit Graphics(Window* window) : + mGui(window), + mCanvas(window) {} void procBegin() { mCanvas.procBegin(); @@ -88,14 +90,12 @@ namespace tp { mGui.drawBegin(); } - void drawEnd() { + void drawEnd() { mCanvas.drawEnd(); mGui.drawEnd(); } - Canvas* getCanvas() { - return &mCanvas; - } + Canvas* getCanvas() { return &mCanvas; } private: Canvas mCanvas; diff --git a/RasterRender/CMakeLists.txt b/RasterRender/CMakeLists.txt new file mode 100644 index 0000000..fd8c89c --- /dev/null +++ b/RasterRender/CMakeLists.txt @@ -0,0 +1,15 @@ +project(RasterRender) + +### ---------------------- Externals --------------------- ### +set(BINDINGS_INCLUDE ${GLEW_INCLUDE_DIR}) +set(BINDINGS_LIBS ${GLEW_LIB}) + +### ---------------------- Static Library --------------------- ### +file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp") +file(GLOB HEADERS "./public/*.hpp" "./public/*/*.hpp") + +add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) + +target_include_directories(${PROJECT_NAME} PUBLIC ./public/ ${BINDINGS_INCLUDE} ./ext/) +target_link_libraries(${PROJECT_NAME} PUBLIC Math Connection) +target_link_libraries(${PROJECT_NAME} PUBLIC ${BINDINGS_LIBS}) \ No newline at end of file diff --git a/Sketch3D/private/FrameBuffer.cpp b/RasterRender/private/FrameBuffer.cpp similarity index 71% rename from Sketch3D/private/FrameBuffer.cpp rename to RasterRender/private/FrameBuffer.cpp index 0804fae..a500e5e 100644 --- a/Sketch3D/private/FrameBuffer.cpp +++ b/RasterRender/private/FrameBuffer.cpp @@ -5,20 +5,26 @@ #include void glerr(GLenum type) { printf("GL ERROR\n"); } -#define AssertGL(x) { x; GLenum __gle = glGetError(); if (__gle != GL_NO_ERROR) glerr(__gle); } +#define AssertGL(x) \ + { \ + x; \ + GLenum __gle = glGetError(); \ + if (__gle != GL_NO_ERROR) glerr(__gle); \ + } using namespace tp; RenderBuffer::RenderBuffer(const Vec2F& size) : mSize(size) { - mDrawBuffers[0] = {GL_COLOR_ATTACHMENT0}; + mDrawBuffers[0] = { GL_COLOR_ATTACHMENT0 }; // --------- texture --------- AssertGL(glGenTextures(1, &mTextureId)); AssertGL(glBindTexture(GL_TEXTURE_2D, mTextureId)); // Give an empty image to OpenGL ( the last "0" ) - AssertGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)size.x, (GLsizei)size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); + AssertGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei) size.x, (GLsizei) size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0) + ); // Poor filtering. Needed AssertGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); AssertGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); @@ -26,7 +32,7 @@ RenderBuffer::RenderBuffer(const Vec2F& size) : // --------- depth --------- AssertGL(glGenRenderbuffers(1, &mDepthBufferID)); AssertGL(glBindRenderbuffer(GL_RENDERBUFFER, mDepthBufferID)); - AssertGL(glRenderbufferStorage(GL_RENDERBUFFER, GLW_CONTEXT_DEPTH_COMPONENT, (GLsizei)size.x, (GLsizei)size.y)); + AssertGL(glRenderbufferStorage(GL_RENDERBUFFER, GLW_CONTEXT_DEPTH_COMPONENT, (GLsizei) size.x, (GLsizei) size.y)); // ------------ framebuffer ------------ AssertGL(glGenFramebuffers(1, &mFrameBufferID)); @@ -49,18 +55,24 @@ RenderBuffer::RenderBuffer(const Vec2F& size, tp::uint1 samples) : AssertGL(glGenTextures(1, &mTextureId)); AssertGL(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextureId)); #ifdef ENV_OS_ANDROID - AssertGL(glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, (GLsizei)size.x, (GLsizei)size.y, GL_TRUE)); + AssertGL( + glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, (GLsizei) size.x, (GLsizei) size.y, GL_TRUE) + ); #else - AssertGL(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, (GLsizei)size.x, (GLsizei)size.y, GL_TRUE)); + AssertGL( + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, (GLsizei) size.x, (GLsizei) size.y, GL_TRUE) + ); #endif // !? - //AssertGL(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - //AssertGL(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + // AssertGL(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + // AssertGL(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); // ------- depth ------- AssertGL(glGenRenderbuffers(1, &mDepthBufferID)); AssertGL(glBindRenderbuffer(GL_RENDERBUFFER, mDepthBufferID)); - AssertGL(glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GLW_CONTEXT_DEPTH_COMPONENT, (GLsizei)size.x, (GLsizei)size.y)); + AssertGL(glRenderbufferStorageMultisample( + GL_RENDERBUFFER, samples, GLW_CONTEXT_DEPTH_COMPONENT, (GLsizei) size.x, (GLsizei) size.y + )); // ------- fbuff ------- AssertGL(glGenFramebuffers(1, &mFrameBufferID)); @@ -72,9 +84,7 @@ RenderBuffer::RenderBuffer(const Vec2F& size, tp::uint1 samples) : glBindFramebuffer(GL_FRAMEBUFFER, 0); } -uint4 RenderBuffer::buffId() const { - return mFrameBufferID; -} +uint4 RenderBuffer::buffId() const { return mFrameBufferID; } void RenderBuffer::beginDraw() { AssertGL(glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID)); @@ -82,7 +92,7 @@ void RenderBuffer::beginDraw() { } void RenderBuffer::setViewport(const RectF& viewport) { - AssertGL(glViewport((GLsizei)viewport.x, (GLsizei)viewport.y, (GLsizei)viewport.z, (GLsizei)viewport.w)); + AssertGL(glViewport((GLsizei) viewport.x, (GLsizei) viewport.y, (GLsizei) viewport.z, (GLsizei) viewport.w)); } void RenderBuffer::clear() { @@ -102,9 +112,6 @@ RenderBuffer::~RenderBuffer() { glDeleteRenderbuffers(1, &mDepthBufferID); } -uint4 RenderBuffer::texId() const { - return mTextureId; -} +uint4 RenderBuffer::texId() const { return mTextureId; } const Vec2F& RenderBuffer::getSize() const { return mSize; } - diff --git a/Sketch3D/private/Shader.cpp b/RasterRender/private/Shader.cpp similarity index 100% rename from Sketch3D/private/Shader.cpp rename to RasterRender/private/Shader.cpp diff --git a/Sketch3D/private/Texture.cpp b/RasterRender/private/Texture.cpp similarity index 100% rename from Sketch3D/private/Texture.cpp rename to RasterRender/private/Texture.cpp diff --git a/Sketch3D/public/FrameBuffer.hpp b/RasterRender/public/FrameBuffer.hpp similarity index 100% rename from Sketch3D/public/FrameBuffer.hpp rename to RasterRender/public/FrameBuffer.hpp diff --git a/Sketch3D/public/GraphicsApi.hpp b/RasterRender/public/GraphicsApi.hpp similarity index 100% rename from Sketch3D/public/GraphicsApi.hpp rename to RasterRender/public/GraphicsApi.hpp diff --git a/Sketch3D/public/Shader.hpp b/RasterRender/public/Shader.hpp similarity index 99% rename from Sketch3D/public/Shader.hpp rename to RasterRender/public/Shader.hpp index 8442e4d..253cdba 100644 --- a/Sketch3D/public/Shader.hpp +++ b/RasterRender/public/Shader.hpp @@ -13,14 +13,15 @@ namespace tp { void geom_bind_source(const char* geom_src); void compile(); - + void bind(); uint4 getu(const char* uid); void unbind(); + void load(const char* vert, const char* geom, const char* frag, bool paths); + private: bool compile_shader(const char* ShaderCode, uint4 ShaderID); - void load(const char* vert, const char* geom, const char* frag, bool paths); private: uint4 programm; diff --git a/Sketch3D/public/Texture.hpp b/RasterRender/public/Texture.hpp similarity index 100% rename from Sketch3D/public/Texture.hpp rename to RasterRender/public/Texture.hpp diff --git a/Sketch3D/CMakeLists.txt b/Sketch3D/CMakeLists.txt index 21fef33..248c80d 100644 --- a/Sketch3D/CMakeLists.txt +++ b/Sketch3D/CMakeLists.txt @@ -1,8 +1,8 @@ project(Sketch3D) ### ---------------------- Externals --------------------- ### -set(BINDINGS_INCLUDE ../Externals/glfw/include ${GLEW_INCLUDE_DIR}) -set(BINDINGS_LIBS glfw Imgui ${GLEW_LIB}) +set(BINDINGS_INCLUDE ../Externals/glfw/include) +set(BINDINGS_LIBS glfw Imgui) ### ---------------------- Static Library --------------------- ### file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp") @@ -11,12 +11,12 @@ file(GLOB HEADERS "./public/*.hpp" "./public/*/*.hpp") add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) target_include_directories(${PROJECT_NAME} PUBLIC ./public/ ${BINDINGS_INCLUDE} ./ext/) -target_link_libraries(${PROJECT_NAME} PUBLIC Graphics Connection Widgets Math) +target_link_libraries(${PROJECT_NAME} PUBLIC Graphics Connection Widgets Math RasterRender) target_link_libraries(${PROJECT_NAME} PUBLIC ${BINDINGS_LIBS}) ### -------------------------- Applications -------------------------- ### add_executable(Sketch3DApp ./applications/Entry.cpp) target_link_libraries(Sketch3DApp ${PROJECT_NAME}) - + file(COPY "rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") file(COPY "applications/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")