From f05890a8024519516e2f9ea8ac1d51b96eeab560 Mon Sep 17 00:00:00 2001 From: koala999 Date: Sun, 11 Dec 2022 16:20:41 +0800 Subject: [PATCH 01/68] try: im-opengl test --- DataVis.vcxproj | 2 ++ DataVis.vcxproj.filters | 6 ++++++ TODO.md | 2 +- src/imapp/KcImOglPaint.cpp | 17 +++++++++++++++++ src/imapp/KcImOglPaint.h | 17 +++++++++++++++++ src/imapp/KcImPlot2d.cpp | 4 ++-- src/layout/KvLayoutElement.cpp | 2 +- 7 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 src/imapp/KcImOglPaint.cpp create mode 100644 src/imapp/KcImOglPaint.h diff --git a/DataVis.vcxproj b/DataVis.vcxproj index e1d692a..7d96417 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -152,6 +152,7 @@ + @@ -320,6 +321,7 @@ + diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index 8aa23f9..5d0e18c 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -421,6 +421,9 @@ layout + + imapp + @@ -966,5 +969,8 @@ layout + + imapp + \ No newline at end of file diff --git a/TODO.md b/TODO.md index a6ac06a..68e4be9 100644 --- a/TODO.md +++ b/TODO.md @@ -6,7 +6,7 @@ 1. title等设置 2. 各种类型的axis 3. 分离axis -4. x轴与y轴的交换 +4. x轴与y轴的交换 --> ok 5. plot3d的legend布局 --> ok 6. colorbar --> ok 7. axis的反向设置 --> ok diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp new file mode 100644 index 0000000..d68db64 --- /dev/null +++ b/src/imapp/KcImOglPaint.cpp @@ -0,0 +1,17 @@ +#include "KcImOglPaint.h" +#include "imgui.h" +#include "glad.h" + + +void oglDrawLineStrip(const ImDrawList* parent_list, const ImDrawCmd* cmd) +{ + cmd->UserCallbackData; + glClearColor(1, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); +} + +void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) +{ + auto dl = ImGui::GetWindowDrawList(); + dl->AddCallback(oglDrawLineStrip, nullptr); +} diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h new file mode 100644 index 0000000..cc148dd --- /dev/null +++ b/src/imapp/KcImOglPaint.h @@ -0,0 +1,17 @@ +#pragma once +#include "KcImPaint.h" + + +// ImGuiOpenGLKvPaintʵ + +class KcImOglPaint : public KcImPaint +{ + using super_ = KcImPaint; + +public: + + using super_::super_; + + void drawLineStrip(point_getter fn, unsigned count) override; + +}; diff --git a/src/imapp/KcImPlot2d.cpp b/src/imapp/KcImPlot2d.cpp index 2f7c065..5ac1456 100644 --- a/src/imapp/KcImPlot2d.cpp +++ b/src/imapp/KcImPlot2d.cpp @@ -1,5 +1,5 @@ #include "KcImPlot2d.h" -#include "KcImPaint.h" +#include "KcImOglPaint.h" #include "plot/KcAxis.h" #include "plot/KcCoord2d.h" #include "KuStrUtil.h" @@ -7,7 +7,7 @@ KcImPlot2d::KcImPlot2d(const std::string_view& name) : KvImWindow(name) - , KvPlot2d(std::make_shared(camera_), std::make_shared()) + , KvPlot2d(std::make_shared(camera_), std::make_shared()) { minSize_[0] = 180, minSize_[1] = 180; dynamic_ = true; diff --git a/src/layout/KvLayoutElement.cpp b/src/layout/KvLayoutElement.cpp index fce73c1..d7d013b 100644 --- a/src/layout/KvLayoutElement.cpp +++ b/src/layout/KvLayoutElement.cpp @@ -4,7 +4,7 @@ void KvLayoutElement::arrange_(const rect_t& rc, int dim) { - assert(rc.upper()[dim] > rc.lower()[dim]); + // assert(rc.upper()[dim] > rc.lower()[dim]); oRect_.lower()[dim] = rc.lower()[dim]; oRect_.upper()[dim] = rc.upper()[dim]; -- Gitee From 8ebbe22cd21b71e2f1de21745f0306fdbf9571fc Mon Sep 17 00:00:00 2001 From: koala999 Date: Sun, 11 Dec 2022 22:06:59 +0800 Subject: [PATCH 02/68] =?UTF-8?q?new:=20=E5=B0=81=E8=A3=85opengl=E7=9A=84s?= =?UTF-8?q?hader?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataVis.vcxproj | 4 ++ DataVis.vcxproj.filters | 15 +++++ src/base/KuPathUtil.cpp | 4 +- src/base/KuPathUtil.h | 2 +- src/opengl/KcGlslProgram.cpp | 65 ++++++++++++++++++ src/opengl/KcGlslProgram.h | 78 ++++++++++++++++++++++ src/opengl/KcGlslShader.cpp | 123 +++++++++++++++++++++++++++++++++++ src/opengl/KcGlslShader.h | 55 ++++++++++++++++ 8 files changed, 343 insertions(+), 3 deletions(-) create mode 100644 src/opengl/KcGlslProgram.cpp create mode 100644 src/opengl/KcGlslProgram.h create mode 100644 src/opengl/KcGlslShader.cpp create mode 100644 src/opengl/KcGlslShader.h diff --git a/DataVis.vcxproj b/DataVis.vcxproj index 7d96417..32de1b2 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -178,6 +178,8 @@ + + @@ -352,6 +354,8 @@ + + diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index 5d0e18c..57482e4 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -40,6 +40,9 @@ {042ff681-4dc1-456c-bc11-8be0a9bc789c} + + {6c8e049e-5599-45c4-9e5a-62bc4d398592} + @@ -424,6 +427,12 @@ imapp + + opengl + + + opengl + @@ -972,5 +981,11 @@ imapp + + opengl + + + opengl + \ No newline at end of file diff --git a/src/base/KuPathUtil.cpp b/src/base/KuPathUtil.cpp index 2d7c5df..e5e57e4 100644 --- a/src/base/KuPathUtil.cpp +++ b/src/base/KuPathUtil.cpp @@ -407,9 +407,9 @@ bool KuPathUtil::setCwd(const std::string& path) } -bool KuPathUtil::exist(const std::string& path) +bool KuPathUtil::exist(const std::string_view& path) { - return -1 != ::_access(path.c_str(), 0); + return -1 != ::_access(path.data(), 0); } diff --git a/src/base/KuPathUtil.h b/src/base/KuPathUtil.h index a74dae9..adafab4 100644 --- a/src/base/KuPathUtil.h +++ b/src/base/KuPathUtil.h @@ -178,7 +178,7 @@ public: // 路径是否存在 - static bool exist(const std::string& path); + static bool exist(const std::string_view& path); // 结合当前目录解析relpath,返回绝对路径 diff --git a/src/opengl/KcGlslProgram.cpp b/src/opengl/KcGlslProgram.cpp new file mode 100644 index 0000000..c8d9d53 --- /dev/null +++ b/src/opengl/KcGlslProgram.cpp @@ -0,0 +1,65 @@ +#include "KcGlslProgram.h" + + +KcGlslProgram::KcGlslProgram() +{ + scheduleLink_ = true; + handle_ = 0; + programBinaryRetrievableHint_ = false; + programSeparable_ = false; + + resetBindingLocations_(); +} + + +KcGlslProgram::~KcGlslProgram() +{ + if (handle()) + deleteProgram(); +} + + +void KcGlslProgram::resetBindingLocations_() +{ + // standard uniform binding + modelViewMatrix_ = -1; + projectionMatrix_ = -1; + modelViewProjectionMatrix_ = -1; + normalMatrix_ = -1; + + // vertex attrib binding + vertexPosition_ = -1; + vertexNormal_ = -1; + vertexColor_ = -1; + vertexSecondaryColor_ = -1; + vertexFogCoord_ = -1; + vertexTexCoord0_ = -1; + vertexTexCoord1_ = -1; + vertexTexCoord2_ = -1; + vertexTexCoord3_ = -1; + vertexTexCoord4_ = -1; + vertexTexCoord5_ = -1; + vertexTexCoord6_ = -1; + vertexTexCoord7_ = -1; + vertexTexCoord8_ = -1; + vertexTexCoord9_ = -1; + vertexTexCoord10_ = -1; +} + + +bool KcGlslProgram::reload() +{ + return true; +} + + +void KcGlslProgram::createProgram() +{ + +} + + +void KcGlslProgram::deleteProgram() +{ + +} \ No newline at end of file diff --git a/src/opengl/KcGlslProgram.h b/src/opengl/KcGlslProgram.h new file mode 100644 index 0000000..720c697 --- /dev/null +++ b/src/opengl/KcGlslProgram.h @@ -0,0 +1,78 @@ +#pragma once +#include +#include +#include +#include + +class KcGlslShader; + +// OpenGLProgramװڰShader +// ʼ汾οVisualization Library + +class KcGlslProgram +{ +public: + + // Constructor. + KcGlslProgram(); + + // Destructor. Calls deleteProgram(). + ~KcGlslProgram(); + + + // Reloads all the shaders source and recompiles them and relinks. Returns true on success. + bool reload(); + + // Calls glCreateProgram() in order to acquire a GLSL program handle + // The program is created only if handle() == 0 + void createProgram(); + + // Deletes the GLSL program calling glDeleteProgram(handle()) + // After this function handle() will return 0. + void deleteProgram(); + + // The handle of the GLSL program as returned by glCreateProgram() + unsigned int handle() const { return handle_; } + + +private: + void resetBindingLocations_(); + +private: + + std::vector> shaders_; + std::map fragDataLocation_; + unsigned int handle_; + bool scheduleLink_; + + // glProgramParameter + bool programBinaryRetrievableHint_; + bool programSeparable_; + + // VL standard uniforms + + int worldMatrix_; + int modelViewMatrix_; + int projectionMatrix_; + int modelViewProjectionMatrix_; + int normalMatrix_; + + // VL standard vertex attributes + + int vertexPosition_; + int vertexNormal_; + int vertexColor_; + int vertexSecondaryColor_; + int vertexFogCoord_; + int vertexTexCoord0_; + int vertexTexCoord1_; + int vertexTexCoord2_; + int vertexTexCoord3_; + int vertexTexCoord4_; + int vertexTexCoord5_; + int vertexTexCoord6_; + int vertexTexCoord7_; + int vertexTexCoord8_; + int vertexTexCoord9_; + int vertexTexCoord10_; +}; \ No newline at end of file diff --git a/src/opengl/KcGlslShader.cpp b/src/opengl/KcGlslShader.cpp new file mode 100644 index 0000000..9c76915 --- /dev/null +++ b/src/opengl/KcGlslShader.cpp @@ -0,0 +1,123 @@ +#include "KcGlslShader.h" +#include "KuPathUtil.h" +#include "KuFileUtil.h" +#include "glad.h" + + +KcGlslShader::KcGlslShader(KeType type, const std::string_view& path_or_source) + : type_(type) +{ + if (KuPathUtil::exist(path_or_source)) { + path_ = path_or_source; + source_ = KuFileUtil::readAsString(path_); + } + else { + source_ = path_or_source; + } + + compile(); +} + + +KcGlslShader::~KcGlslShader() +{ + deleteShader_(); +} + + +void KcGlslShader::createShader_() +{ + const static GLenum mapShaderType[] = { + GL_VERTEX_SHADER, + GL_FRAGMENT_SHADER, + GL_GEOMETRY_SHADER, + GL_TESS_CONTROL_SHADER, + GL_TESS_EVALUATION_SHADER + }; + + if (!handle()) + handle_ = glCreateShader(mapShaderType[type_]); +} + + +void KcGlslShader::deleteShader_() +{ + if (handle()) { + glDeleteShader(handle()); + handle_ = 0; + } +} + + +std::string KcGlslShader::getShaderSource() const +{ + if (handle()) { + GLint len = 0; + glGetShaderiv(handle(), GL_SHADER_SOURCE_LENGTH, &len); + if (len) { + std::vector src; + src.resize(len); + GLint len_written = 0; + glGetShaderSource(handle(), len, &len_written, &src[0]); + return src.data(); + } + } + + return ""; +} + + +bool KcGlslShader::compile() +{ + if (compiled()) + return true; + + // make sure shader object exists + createShader_(); + + // assign sources + const char* source[] = { source_.c_str() }; + glShaderSource(handle(), 1, source, NULL); + + // compile the shader + glCompileShader(handle()); + + return compiled(); +} + + +bool KcGlslShader::compiled() const +{ + assert(handle()); + + int status = 0; + glGetShaderiv(handle(), GL_COMPILE_STATUS, &status); + return status == GL_TRUE; +} + + +bool KcGlslShader::reload() +{ + if (!path_.empty()) { + source_ = KuFileUtil::readAsString(path_); + return compile(); + } + + return false; +} + + +std::string KcGlslShader::infoLog() const +{ + assert(handle()); + + int max_length = 0; + glGetShaderiv(handle(), GL_INFO_LOG_LENGTH, &max_length); + if (max_length == 0) + return ""; + + std::vector log_buffer; + log_buffer.resize(max_length); + glGetShaderInfoLog(handle(), max_length, NULL, log_buffer.data()); + return log_buffer.data(); +} diff --git a/src/opengl/KcGlslShader.h b/src/opengl/KcGlslShader.h new file mode 100644 index 0000000..0544af8 --- /dev/null +++ b/src/opengl/KcGlslShader.h @@ -0,0 +1,55 @@ +#pragma once +#include + + +// ʵOpenGLshaderװ +// ʼ汾οVisualization Library + +class KcGlslShader +{ +public: + + enum KeType + { + k_shader_vertex, + k_shader_fragment + }; + + KcGlslShader(KeType type, const std::string_view& path_or_source); + + ~KcGlslShader(); + + // Reloads the shader source and recompiles it. Returns true on success. + bool reload(); + + // The handle of this OpenGL shader object as returned by glCreateShader() + unsigned int handle() const { return handle_; } + + // Retrieves the shader source using glGetShaderSource() + std::string getShaderSource() const; + + // Compiles the shader + // This function also create the shader if handle() == 0 using the OpenGL function glCreateShader() + bool compile(); + + // Returns true if the shader has been succesfully compiled. + // The check is done using the OpenGL function glGetShaderiv() + bool compiled() const; + + // Returns a String object containing this shader's info log as returned by glGetShaderInfoLog(), see also http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderInfoLog.xml for more information. + std::string infoLog() const; + +private: + + // Creates the shader using the OpenGL function glCreateShader() + void createShader_(); + + // Deletes the shader using the OpenGL function glDeleteShader() + void deleteShader_(); + +private: + KeType type_; + std::string path_; + std::string source_; + unsigned int handle_{ 0 }; +}; -- Gitee From 9149db8629689a3ddeb32c73e26bd915d84196ca Mon Sep 17 00:00:00 2001 From: koala999cn Date: Tue, 13 Dec 2022 09:01:02 +0800 Subject: [PATCH 03/68] =?UTF-8?q?new:=20=E5=B0=81=E8=A3=85opengl=E7=9A=84v?= =?UTF-8?q?bo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataVis.vcxproj | 6 + DataVis.vcxproj.filters | 18 +++ src/imapp/KcImOglPaint.cpp | 46 ++++++- src/opengl/KcGlslProgram.cpp | 197 ++++++++++++++++++++++++++++- src/opengl/KcGlslProgram.h | 90 ++++++++++++- src/opengl/KcGlslShader.cpp | 19 +-- src/opengl/KcGlslShader.h | 10 +- src/opengl/KcGpuBuffer.cpp | 111 ++++++++++++++++ src/opengl/KcGpuBuffer.h | 78 ++++++++++++ src/opengl/KcVertexAttribute.cpp | 149 ++++++++++++++++++++++ src/opengl/KcVertexAttribute.h | 108 ++++++++++++++++ src/opengl/KcVertexDeclaration.cpp | 57 +++++++++ src/opengl/KcVertexDeclaration.h | 34 +++++ 13 files changed, 902 insertions(+), 21 deletions(-) create mode 100644 src/opengl/KcGpuBuffer.cpp create mode 100644 src/opengl/KcGpuBuffer.h create mode 100644 src/opengl/KcVertexAttribute.cpp create mode 100644 src/opengl/KcVertexAttribute.h create mode 100644 src/opengl/KcVertexDeclaration.cpp create mode 100644 src/opengl/KcVertexDeclaration.h diff --git a/DataVis.vcxproj b/DataVis.vcxproj index 32de1b2..475da84 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -178,8 +178,11 @@ + + + @@ -356,6 +359,9 @@ + + + diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index 57482e4..644f720 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -433,6 +433,15 @@ opengl + + opengl + + + opengl + + + opengl + @@ -987,5 +996,14 @@ opengl + + opengl + + + opengl + + + opengl + \ No newline at end of file diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index d68db64..e41e1c6 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -1,13 +1,55 @@ #include "KcImOglPaint.h" #include "imgui.h" #include "glad.h" +#include "opengl/KcGlslProgram.h" +#include "opengl/KcGlslShader.h" +#include "opengl/KcBufferObject.h" + + +namespace kPrivate +{ + const static char* vertex_shader_glsl_130 = + "uniform mat4 ProjMtx;\n" + "in vec2 Position;\n" + "in vec4 Color;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" + "}\n"; + + const static char* fragment_shader_glsl_130 = + "in vec4 Frag_Color;\n" + "out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color;\n" + "}\n"; +} void oglDrawLineStrip(const ImDrawList* parent_list, const ImDrawCmd* cmd) { + KcGlslProgram prog; + prog.attachShader(new KcGlslShader(KcGlslShader::k_shader_vertex, kPrivate::vertex_shader_glsl_130)); + prog.attachShader(new KcGlslShader(KcGlslShader::k_shader_fragment, kPrivate::fragment_shader_glsl_130)); + std::string info; + + if (!prog.shaderAt(0)->compile()) + info = prog.shaderAt(0)->infoLog(); + prog.shaderAt(1)->compile(); + prog.link(); + + auto oldProg = prog.currentProgram(); + prog.useProgram(); + cmd->UserCallbackData; - glClearColor(1, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); + + int count(100); + glDrawArrays(GL_LINE_STRIP, 0, count); + + prog.useProgram(oldProg); } void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) diff --git a/src/opengl/KcGlslProgram.cpp b/src/opengl/KcGlslProgram.cpp index c8d9d53..bd4e5eb 100644 --- a/src/opengl/KcGlslProgram.cpp +++ b/src/opengl/KcGlslProgram.cpp @@ -1,4 +1,7 @@ #include "KcGlslProgram.h" +#include "glad.h" +#include "KcGlslShader.h" +#include KcGlslProgram::KcGlslProgram() @@ -15,7 +18,7 @@ KcGlslProgram::KcGlslProgram() KcGlslProgram::~KcGlslProgram() { if (handle()) - deleteProgram(); + destroy(); } @@ -53,13 +56,199 @@ bool KcGlslProgram::reload() } -void KcGlslProgram::createProgram() +void KcGlslProgram::create() { + if (handle() == 0) { + scheduleRelinking_(); + handle_ = glCreateProgram(); + assert(handle() && glIsProgram(handle())); + } +} + + +void KcGlslProgram::destroy() +{ + if (handle()) { + glDeleteProgram(handle()); + handle_ = 0; + } + resetBindingLocations_(); + scheduleRelinking_(); +} + + +bool KcGlslProgram::link(bool forceRelink) +{ + if (linked() && !forceRelink) + return true; + + resetBindingLocations_(); + + if (shaderCount() == 0) + return false; // no shaders + + create(); + + // pre-link operations + preLink_(); + + // link the program + + glLinkProgram(handle()); + + scheduleLink_ = !linkStatus(); + + // check link error + if (!linked()) + return false; + + // post-link operations + postLink_(); + + return true; +} + + +void KcGlslProgram::preLink_() +{ + +} + + +void KcGlslProgram::postLink_() +{ + +} + + +bool KcGlslProgram::linkStatus() const +{ + if (handle() == 0) + return false; + + int status = 0; + glGetProgramiv(handle(), GL_LINK_STATUS, &status); + return status == GL_TRUE; +} + + +std::string KcGlslProgram::infoLog() const +{ + if (handle() == 0) + return "GLSL program object not yet created!"; + + int max_length = 0; + glGetProgramiv(handle(), GL_INFO_LOG_LENGTH, &max_length); + std::vector log_buffer; + log_buffer.resize(max_length + 1); + glGetProgramInfoLog(handle(), max_length, NULL, log_buffer.data()); + return log_buffer.data(); +} + + +bool KcGlslProgram::validate() const +{ + if (handle() == 0) + return false; + GLint status = 0; + glValidateProgram(handle()); + glGetProgramiv(handle(), GL_VALIDATE_STATUS, &status); + return status == GL_TRUE; } -void KcGlslProgram::deleteProgram() +void KcGlslProgram::bindAttribLocation(unsigned int index, const std::string_view& name) { + create(); + scheduleRelinking_(); + glBindAttribLocation(handle(), index, name.data()); +} + + +int KcGlslProgram::getAttribLocation(const std::string_view& name) const +{ + return glGetAttribLocation(handle(), name.data()); +} + + +bool KcGlslProgram::attachShader(KcGlslShader* shader) +{ + create(); + + scheduleRelinking_(); + + detachShader(shader); + shaders_.emplace_back(shader); + + glAttachShader(handle(), shader->handle()); + + return shader->compileStatus(); +} + + +bool KcGlslProgram::detachShader(KcGlslShader* shader) +{ + // if it fails the shader has never been attached to any GLSL program + for (auto i = shaders_.cbegin(); i != shaders_.cend(); ++i) { + if (i->get() == shader) { + if (shader->handle()) + glDetachShader(handle(), shader->handle()); + shaders_.erase(i); + return true; + } + } + + return false; +} + + +void KcGlslProgram::detachAllShaders(bool deleteShaders) +{ + for (auto i = shaders_.cbegin(); i != shaders_.cend(); ++i) + if ((*i)->handle()) { + glDetachShader(handle(), (*i)->handle()); + if (deleteShaders) (*i)->destroy(); + } + + shaders_.clear(); + scheduleRelinking_(); +} + -} \ No newline at end of file +int KcGlslProgram::getUniformLocation(const std::string_view& name) const +{ + return glGetUniformLocation(handle(), name.data()); +} + + +void KcGlslProgram::getUniformfv(int location, float* params) const +{ + glGetUniformfv(handle(), location, params); +} + + +void KcGlslProgram::getUniformiv(int location, int* params) const +{ + glGetUniformiv(handle(), location, params); +} + + +void KcGlslProgram::useProgram() const +{ + useProgram(handle()); +} + + +unsigned KcGlslProgram::currentProgram() +{ + GLint prog; + glGetIntegerv(GL_CURRENT_PROGRAM, &prog); + return static_cast(prog); +} + + +void KcGlslProgram::useProgram(unsigned prog) +{ + glUseProgram(prog); +} diff --git a/src/opengl/KcGlslProgram.h b/src/opengl/KcGlslProgram.h index 720c697..17221ca 100644 --- a/src/opengl/KcGlslProgram.h +++ b/src/opengl/KcGlslProgram.h @@ -25,19 +25,105 @@ public: // Calls glCreateProgram() in order to acquire a GLSL program handle // The program is created only if handle() == 0 - void createProgram(); + void create(); // Deletes the GLSL program calling glDeleteProgram(handle()) // After this function handle() will return 0. - void deleteProgram(); + void destroy(); // The handle of the GLSL program as returned by glCreateProgram() unsigned int handle() const { return handle_; } + // Links the GLSLProgram calling glLinkProgram(handle()) only if the program needs to be linked. + bool link(bool forceRelink = false); + + bool linkStatus() const; + + // Returns true if the program has been succesfully linked. + bool linked() const { return handle_ && !scheduleLink_; } + + // Returns the info log of this GLSL program using the OpenGL function glGetProgramInfoLog() + std::string infoLog() const; + + // Returns true if the validation of this GLSL program is succesful + bool validate() const; + + /** Equivalent to glBindAttribLocation(handle(), index, name.c_str()) with the difference that this function will automatically create a GLSL program if none is present + * and it will schedule a re-link since the new specified bindings take effect after linking the GLSL program. */ + void bindAttribLocation(unsigned int index, const std::string_view& name); + + // Eqivalento to glGetAttribLocation(handle(), name). + // The program must be linked before calling this function. + int getAttribLocation(const std::string_view& name) const; + + + // --------------- shaders --------------- + + /** + * Attaches the GLSLShader to this GLSLProgram + * Attaching a shader triggers the compilation of the shader (if not already compiled) and relinking of the program. + */ + bool attachShader(KcGlslShader* shader); + + // Detaches a GLSLShader from the GLSLShader (note: it does NOT schedule a relink of the program) + bool detachShader(KcGlslShader* shader); + + // Detaches all the shaders and deletes them according to deleteShaders (note that the GLSL Program remains still valid). + // Use this function when your GLSL program compiled well, you don't want to re-link or re-compile it and you want to save + // some memory by discarding unnecessary shaders objects. + // this method will schedules a relinking + void detachAllShaders(bool deleteShaders); + + // Returns the number of KcGlslShader objects bound to this GLSLProgram + unsigned shaderCount() const { return shaders_.size(); } + + // Returns the i-th KcGlslShader objects bound to this GLSLProgram + const KcGlslShader* shaderAt(unsigned i) const { return shaders_[i].get(); } + + //! Returns the i-th GLSLShader objects bound to this GLSLProgram + KcGlslShader* shaderAt(unsigned i) { return shaders_[i].get(); } + + + // --------------- uniform variables --------------- + + /** + * Returns the binding index of the given uniform. + */ + int getUniformLocation(const std::string_view& name) const; + + // general uniform getters: use these to access to all the types supported by your GLSL implementation, + // and not only the ordinary fvec2, fvec3, fvec4, ivec2, ivec3, ivec4, fmat2, fmat3, fmat4 + + // Equivalent to glGetUniformfv(handle(), location, params) + void getUniformfv(int location, float* params) const; + + void getUniformfv(const std::string_view& name, float* params) const { + getUniformfv(getUniformLocation(name), params); + } + + // Equivalent to glGetUniformiv(handle(), location, params) + void getUniformiv(int location, int* params) const; + + // Equivalent to getUniformiv(getUniformLocation(name) + void getUniformiv(const char* name, int* params) const { + getUniformiv(getUniformLocation(name), params); + } + + void useProgram() const; + + static unsigned currentProgram(); + + static void useProgram(unsigned prog); private: void resetBindingLocations_(); + //! Schedules a relink of the GLSL program. + void scheduleRelinking_() { scheduleLink_ = true; } + + void preLink_(); + void postLink_(); + private: std::vector> shaders_; diff --git a/src/opengl/KcGlslShader.cpp b/src/opengl/KcGlslShader.cpp index 9c76915..c421da4 100644 --- a/src/opengl/KcGlslShader.cpp +++ b/src/opengl/KcGlslShader.cpp @@ -21,11 +21,11 @@ KcGlslShader::KcGlslShader(KeType type, const std::string_view& path_or_source) KcGlslShader::~KcGlslShader() { - deleteShader_(); + destroy(); } -void KcGlslShader::createShader_() +void KcGlslShader::create_() { const static GLenum mapShaderType[] = { GL_VERTEX_SHADER, @@ -37,10 +37,12 @@ void KcGlslShader::createShader_() if (!handle()) handle_ = glCreateShader(mapShaderType[type_]); + + assert(glIsShader(handle())); // TODO: } -void KcGlslShader::deleteShader_() +void KcGlslShader::destroy() { if (handle()) { glDeleteShader(handle()); @@ -69,11 +71,11 @@ std::string KcGlslShader::getShaderSource() const bool KcGlslShader::compile() { - if (compiled()) + if (compileStatus()) return true; // make sure shader object exists - createShader_(); + create_(); // assign sources const char* source[] = { source_.c_str() }; @@ -82,13 +84,14 @@ bool KcGlslShader::compile() // compile the shader glCompileShader(handle()); - return compiled(); + return compileStatus(); } -bool KcGlslShader::compiled() const +bool KcGlslShader::compileStatus() const { - assert(handle()); + if (!handle()) + return false; int status = 0; glGetShaderiv(handle(), GL_COMPILE_STATUS, &status); diff --git a/src/opengl/KcGlslShader.h b/src/opengl/KcGlslShader.h index 0544af8..845eab2 100644 --- a/src/opengl/KcGlslShader.h +++ b/src/opengl/KcGlslShader.h @@ -34,18 +34,18 @@ public: // Returns true if the shader has been succesfully compiled. // The check is done using the OpenGL function glGetShaderiv() - bool compiled() const; + bool compileStatus() const; // Returns a String object containing this shader's info log as returned by glGetShaderInfoLog(), see also http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderInfoLog.xml for more information. std::string infoLog() const; + // Deletes the shader using the OpenGL function glDeleteShader() + void destroy(); + private: // Creates the shader using the OpenGL function glCreateShader() - void createShader_(); - - // Deletes the shader using the OpenGL function glDeleteShader() - void deleteShader_(); + void create_(); private: KeType type_; diff --git a/src/opengl/KcGpuBuffer.cpp b/src/opengl/KcGpuBuffer.cpp new file mode 100644 index 0000000..78b8afe --- /dev/null +++ b/src/opengl/KcGpuBuffer.cpp @@ -0,0 +1,111 @@ +#include "KcGpuBuffer.h" +#include +#include "glad.h" + + +void KcGpuBuffer::create_() +{ + if (handle() == 0) { + assert(bytesCount() == 0); + glGenBuffers(1, &handle_); + bytes_ = 0; + } +} + + +void KcGpuBuffer::destroy() +{ + if (handle() != 0) { + glDeleteBuffers(1, &handle_); + handle_ = 0; + bytes_ = 0; + } +} + + +void KcGpuBuffer::setData(const void* data, unsigned bytes, KeUsage usage) +{ + const static GLenum glUsages[] = { + GL_STREAM_DRAW, + GL_STREAM_READ, + GL_STREAM_COPY, + GL_STATIC_DRAW, + GL_STATIC_READ, + GL_STATIC_COPY, + GL_DYNAMIC_DRAW, + GL_DYNAMIC_READ, + GL_DYNAMIC_COPY + }; + + create_(); + + // we use the GL_ARRAY_BUFFER slot to send the data for no special reason + GLuint last_array_buffer; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); + + glBindBuffer(GL_ARRAY_BUFFER, handle()); + glBufferData(GL_ARRAY_BUFFER, bytes, data, glUsages[usage]); + + if (last_array_buffer != handle()) + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + + bytes_ = bytes; + usage_ = usage; +} + + +void KcGpuBuffer::setSubData(const void* data, unsigned bytes, int offset) +{ + assert(handle() && data); + assert(bytes + offset <= bytesCount()); + + GLuint last_array_buffer; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); + + glBindBuffer(GL_ARRAY_BUFFER, handle()); + glBufferSubData(GL_ARRAY_BUFFER, offset, bytes, data); + + if (last_array_buffer != handle()) + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); +} + + +void* KcGpuBuffer::map(KeAccess access) +{ + const static GLenum glAccess[] = { + GL_READ_ONLY, + GL_WRITE_ONLY, + GL_READ_WRITE + }; + + create_(); + + GLuint last_array_buffer; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); + + glBindBuffer(GL_ARRAY_BUFFER, handle()); + void* ptr = glMapBuffer(GL_ARRAY_BUFFER, glAccess[access]); + + if (last_array_buffer != handle()) + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + + return ptr; +} + + +bool KcGpuBuffer::unmap() +{ + assert(handle()); + + GLuint last_array_buffer; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); + + glBindBuffer(GL_ARRAY_BUFFER, handle()); + + bool ok = glUnmapBuffer(GL_ARRAY_BUFFER) == GL_TRUE; + + if (last_array_buffer != handle()) + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + + return true; +} diff --git a/src/opengl/KcGpuBuffer.h b/src/opengl/KcGpuBuffer.h new file mode 100644 index 0000000..db10dce --- /dev/null +++ b/src/opengl/KcGpuBuffer.h @@ -0,0 +1,78 @@ +#pragma once + + +// װopenglbuffer objectйز + +class KcGpuBuffer +{ +public: + + ~KcGpuBuffer() { + destroy(); + } + + unsigned int handle() const { return handle_; } + + unsigned bytesCount() const { return bytes_; } + + void destroy(); + + enum KeUsage + { + k_stream_draw, // Data is specified once and used at most a few times as the source of drawing and image specification commands. + k_stream_read, // Data is copied once from an OpenGL buffer and is used at most a few times by the application as data values. + k_stream_copy, // Data is copied once from an OpenGL buffer and is used at most a few times as the source for drawing or image specification commands. + k_static_draw, // Data is specified once and used many times as the source of drawing or image specification commands. + k_static_read, // Data is copied once from an OpenGL buffer and is used many times by the application as data values. + k_static_copy, // Data is copied once from an OpenGL buffer and is used many times as the source for drawing or image specification commands. + k_dynamic_draw, // Data is specified many times and used many times as the source of drawing and image specification commands. + k_dynamic_read, // Data is copied many times from an OpenGL buffer and is used many times by the application as data values. + k_dynamic_copy // Data is copied many times from an OpenGL buffer and is used many times as the source for drawing or image specification commands. + }; + + // Modifies the BufferObject using the supplied data. + // Use this function to initialize or resize the BufferObject and set it's usage flag. + // If data == NULL the buffer will be allocated but no data will be written to the BufferObject. + // If data != NULL such data will be copied into the BufferObject. + void setData(const void* data, unsigned bytes, KeUsage usage); + + // Modifies an existing BufferObject using the supplied data. + // @note You can use this function only on already initialized BufferObjects, use setBufferData() to initialize a BufferObject. + // @param[in] data Must be != NULL, pointer to the data being written to the BufferObject. + void setSubData(const void* data, unsigned bytes, int offset); + + enum KeAccess + { + k_read_only, + k_write_only, + k_read_write + }; + + // Maps a BufferObject so that it can be read or written by the CPU. + // You can map only one BufferObject at a time and you must unmap it before using the BufferObject again or mapping another one. + void* map(KeAccess access); + + + // Unmaps a previously mapped BufferObject. + // @return Returs true or false based on what's specified in the OpenGL specs: + // "UnmapBuffer returns TRUE unless data values in the buffer's data store have + // become corrupted during the period that the buffer was mapped. Such corruption + // can be the result of a screen resolution change or other window system-dependent + // event that causes system heaps such as those for high-performance graphics memory + // to be discarded. GL implementations must guarantee that such corruption can + // occur only during the periods that a buffer's data store is mapped. If such corruption + // has occurred, UnmapBuffer returns FALSE, and the contents of the buffer's + // data store become undefined." + bool unmap(); + +private: + + void create_(); + +private: + + unsigned int handle_{ 0 }; + unsigned bytes_{ 0 }; + KeUsage usage_{ k_static_draw }; + +}; \ No newline at end of file diff --git a/src/opengl/KcVertexAttribute.cpp b/src/opengl/KcVertexAttribute.cpp new file mode 100644 index 0000000..d098c67 --- /dev/null +++ b/src/opengl/KcVertexAttribute.cpp @@ -0,0 +1,149 @@ +#include "KcVertexAttribute.h" +#include + + +KcVertexAttribute::KcVertexAttribute(unsigned loc, KeFormat fmt, unsigned offset, + KeSemantic semantic, unsigned semanticIndex) +{ + location_ = loc; + format_ = fmt; + bytesOffset_ = offset; + semantic_ = semantic; + semanticIndex_ = semanticIndex; +} + + +unsigned KcVertexAttribute::byteSize() const +{ + switch(format_) + { + case k_short1: + case k_short1_norm: + return 2; + + case k_color: + case k_color_argb: + case k_color_abgr: + case k_float: + case k_ubyte4: + case k_ubyte4_norm: + case k_short2: + case k_short2_norm: + return 4; + + case k_short3: + case k_short3_norm: + return 6; + + case k_float2: + case k_short4: + case k_short4_norm: + return 8; + + case k_float3: + return 12; + + case k_float4: + return 16; + } + + assert(false); + return 0; +} + + +KcVertexAttribute::KeFormat KcVertexAttribute::baseType() const +{ + switch(format_) + { + case k_float1: + case k_float2: + case k_float3: + case k_float4: + return k_float; + + case k_ubyte4: + case k_ubyte4_norm: + return k_ubyte4; + + case k_short1: + case k_short2: + case k_short2_norm: + case k_short3: + case k_short4: + case k_short4_norm: + return k_short; + + default: + break; + } + + return format_; +} + + +unsigned KcVertexAttribute::componentCount() const +{ + switch(format_) + { + case k_color: + case k_color_argb: + case k_color_abgr: + case k_short1: + case k_short1_norm: + case k_float1: + return 1; + + case k_float2: + case k_short2: + case k_short2_norm: + return 2; + + case k_short3: + case k_short3_norm: + case k_float3: + return 3; + + case k_float4: + case k_ubyte4: + case k_ubyte4_norm: + case k_short4: + case k_short4_norm: + return 4; + } + + assert(false); + return 0; +} + + +unsigned KcVertexAttribute::componentByteSize() const +{ + switch(format_) + { + case k_color: + case k_color_argb: + case k_color_abgr: + case k_float1: + case k_float2: + case k_float3: + case k_float4: + return 4; + + case k_ubyte4: + case k_ubyte4_norm: + return 1; + + case k_short1: + case k_short2: + case k_short3: + case k_short4: + case k_short1_norm: + case k_short2_norm: + case k_short3_norm: + case k_short4_norm: + return 2; + } + + return 0; +} diff --git a/src/opengl/KcVertexAttribute.h b/src/opengl/KcVertexAttribute.h new file mode 100644 index 0000000..562fb68 --- /dev/null +++ b/src/opengl/KcVertexAttribute.h @@ -0,0 +1,108 @@ +#pragma once + +/// ʼ汾οNebula3 + +/** This class declares the usage of a single vertex buffer as a component + of a complete VertexDeclaration. + @remarks + Several vertex buffers can be used to supply the input geometry for a + rendering operation, and in each case a vertex buffer can be used in + different ways for different operations; the buffer itself does not + define the semantics (position, normal etc), the VertexAttribute + class does. +*/ +class KcVertexAttribute +{ +public: + + /// Vertex attribute semantics, used to identify the meaning of vertex buffer contents + enum KeSemantic + { + k_position, /// Position, 3 reals per vertex + k_normal, /// Normal, 3 reals per vertex + k_tangent, /// Tangent (X axis if normal is Z) + k_binormal, /// Binormal (Y axis if normal is Z) + k_texcoord, /// Texture coordinates + k_diffuse, /// Diffuse colours + k_specular, /// Specular colours + k_blend_weights, /// Blending weights + k_blend_indices, /// Blending indices + k_semantic_count /// The number of VertexElementSemantic elements + }; + + enum KeFormat + { + k_float, //> one-component float, expanded to (float, 0, 0, 1) + k_float1 = k_float, + k_float2, //> two-component float, expanded to (float, float, 0, 1) + k_float3, //> three-component float, expanded to (float, float, float, 1) + k_float4, //> four-component float + k_ubyte4, //> four-component unsigned byte + k_short, + k_short1 = k_short, + k_short2, //> two-component signed short, expanded to (value, value, 0, 1) + k_short3, + k_short4, //> four-component signed short + k_ubyte4_norm, //> four-component normalized unsigned byte (value / 255.0f) + k_short1_norm, + k_short2_norm, //> two-component normalized signed short (value / 32767.0f) + k_short3_norm, + k_short4_norm, //> four-component normalized signed short (value / 32767.0f) + + k_color, /// alias to more specific colour type - use the current rendersystem's colour packing + k_color_argb, /// D3D style compact color + k_color_abgr /// GL style compact color + }; + + KcVertexAttribute() = default; + + KcVertexAttribute(unsigned loc, KeFormat fmt, unsigned offset, KeSemantic semantic, unsigned semanticIndex = 0); + + /// Gets the vertex buffer index from where this attribute draws it's values + unsigned location() const { return location_; } + + /// Gets the offset into the buffer where this attribute starts + unsigned offset() const { return bytesOffset_; } + + /// Gets the data format of this attribute + KeFormat format() const { return format_; } + + /// Gets the meaning of this attribute + KeSemantic semantic() const { return semantic_; } + + /// Gets the index of this attribute, only applicable for repeating elements + unsigned semanticIndex() const { return semanticIndex_; } + + // caculate the size in byte of attribute with this format + unsigned byteSize() const; + + KeFormat baseType() const; + + // get # of component per attribute + unsigned componentCount() const; + + // get the size in byte of per-component + unsigned componentByteSize() const; + +private: + + /// The meaning of the attribute + KeSemantic semantic_{ k_position }; + + /// The semantic index for the attribute. A semantic index modifies a semantic, + /// with an integer index number. A semantic index is only needed in a case + /// where there is more than one attribute with the same semantic. + /// only applicable for some attributes like texture coords. + unsigned semanticIndex_{ 0 }; + + /// The data type of the attribute data. + KeFormat format_; + + /// An integer value that identifies the input-assembler. + unsigned location_{ 0 }; + + /// The offset in the buffer that this attribute starts at. + /// Use 0 for convenience to define the current attribute directly after the previous one, + /// including any packing if necessary. + unsigned bytesOffset_{ 0 }; +}; \ No newline at end of file diff --git a/src/opengl/KcVertexDeclaration.cpp b/src/opengl/KcVertexDeclaration.cpp new file mode 100644 index 0000000..629f9e0 --- /dev/null +++ b/src/opengl/KcVertexDeclaration.cpp @@ -0,0 +1,57 @@ +#include "KcVertexDeclaration.h" + + +const KcVertexAttribute* KcVertexDeclaration::findAttribute(KcVertexAttribute::KeSemantic semantic, unsigned semanticIdx) const +{ + for(unsigned i = 0; i < attributeCount(); i++) { + const auto& attr = getAttribute(i); + if(attr.semantic() == semantic && attr.semanticIndex() == semanticIdx) + return &attr; + } + + return nullptr; +} + + +unsigned KcVertexDeclaration::calcVertexSize() const +{ + unsigned s(0); + for (unsigned i = 0; i < attributeCount(); i++) + s += getAttribute(i).byteSize(); + + return s; +} + + +bool KcVertexDeclaration::hasSemantic(KcVertexAttribute::KeSemantic semantic) const +{ + for(unsigned i = 0; i < attributeCount(); i++) + if(getAttribute(i).semantic() == semantic) + return true; + + return false; +} + + +bool KcVertexDeclaration::hasColor() const +{ + for(unsigned i = 0; i < attributeCount(); i++) { + if(getAttribute(i).semantic() == KcVertexAttribute::k_diffuse || + getAttribute(i).semantic() == KcVertexAttribute::k_specular) + return true; + } + + return false; +} + + +unsigned KcVertexDeclaration::texCoordCount() const +{ + unsigned c(0); + for(unsigned i = 0; i < attributeCount(); i++) { + if(getAttribute(i).semantic() == KcVertexAttribute::k_texcoord) + ++c; + } + + return c; +} \ No newline at end of file diff --git a/src/opengl/KcVertexDeclaration.h b/src/opengl/KcVertexDeclaration.h new file mode 100644 index 0000000..37332ce --- /dev/null +++ b/src/opengl/KcVertexDeclaration.h @@ -0,0 +1,34 @@ +#pragma once +#include "KcVertexAttribute.h" +#include + + +class KcVertexDeclaration +{ +public: + + void pushAttribute(const KcVertexAttribute& attr) { + attrs_.push_back(attr); + } + + KcVertexAttribute& getAttribute(unsigned idx) { return attrs_[idx]; } + const KcVertexAttribute& getAttribute(unsigned idx) const { return attrs_[idx]; } + + const KcVertexAttribute* findAttribute(KcVertexAttribute::KeSemantic semantic, unsigned semanticIdx) const; + + unsigned attributeCount() const { return attrs_.size(); } + + unsigned calcVertexSize() const; // 벼ռֽڵĴС + + bool hasSemantic(KcVertexAttribute::KeSemantic semantic) const; + + // ԪǷɫֵ + bool hasColor() const; + + // ԪԪصĿ + unsigned texCoordCount() const; + +private: + std::vector attrs_; +}; + -- Gitee From 4ca8a8e52d17e93c98ab3d9a15fff0bb00ecb912 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Tue, 13 Dec 2022 11:40:28 +0800 Subject: [PATCH 04/68] =?UTF-8?q?new:=20=E5=B0=81=E8=A3=85opengl=E7=9A=84v?= =?UTF-8?q?bo=E6=B8=B2=E6=9F=93=E8=BF=87=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataVis.vcxproj | 2 ++ DataVis.vcxproj.filters | 6 ++++ src/opengl/KcGpuBuffer.cpp | 8 ++++- src/opengl/KcGpuBuffer.h | 2 ++ src/opengl/KcRenderObject.cpp | 30 ++++++++++++++++++ src/opengl/KcRenderObject.h | 51 ++++++++++++++++++++++++++++++ src/opengl/KcVertexAttribute.cpp | 28 ++++++++++------ src/opengl/KcVertexAttribute.h | 6 ++-- src/opengl/KcVertexDeclaration.cpp | 24 +++++++++++++- src/opengl/KcVertexDeclaration.h | 2 ++ 10 files changed, 144 insertions(+), 15 deletions(-) create mode 100644 src/opengl/KcRenderObject.cpp create mode 100644 src/opengl/KcRenderObject.h diff --git a/DataVis.vcxproj b/DataVis.vcxproj index 475da84..0807130 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -181,6 +181,7 @@ + @@ -360,6 +361,7 @@ + diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index 644f720..fdcfd09 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -442,6 +442,9 @@ opengl + + opengl + @@ -1005,5 +1008,8 @@ opengl + + opengl + \ No newline at end of file diff --git a/src/opengl/KcGpuBuffer.cpp b/src/opengl/KcGpuBuffer.cpp index 78b8afe..2761e34 100644 --- a/src/opengl/KcGpuBuffer.cpp +++ b/src/opengl/KcGpuBuffer.cpp @@ -23,6 +23,12 @@ void KcGpuBuffer::destroy() } +void KcGpuBuffer::bind() const +{ + glBindBuffer(GL_ARRAY_BUFFER, handle()); +} + + void KcGpuBuffer::setData(const void* data, unsigned bytes, KeUsage usage) { const static GLenum glUsages[] = { @@ -47,7 +53,7 @@ void KcGpuBuffer::setData(const void* data, unsigned bytes, KeUsage usage) glBufferData(GL_ARRAY_BUFFER, bytes, data, glUsages[usage]); if (last_array_buffer != handle()) - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); // TODO: Ƿָֻģʽ bytes_ = bytes; usage_ = usage; diff --git a/src/opengl/KcGpuBuffer.h b/src/opengl/KcGpuBuffer.h index db10dce..1b59fd0 100644 --- a/src/opengl/KcGpuBuffer.h +++ b/src/opengl/KcGpuBuffer.h @@ -13,6 +13,8 @@ public: unsigned int handle() const { return handle_; } + void bind() const; + unsigned bytesCount() const { return bytes_; } void destroy(); diff --git a/src/opengl/KcRenderObject.cpp b/src/opengl/KcRenderObject.cpp new file mode 100644 index 0000000..18d86c2 --- /dev/null +++ b/src/opengl/KcRenderObject.cpp @@ -0,0 +1,30 @@ +#include "KcRenderObject.h" +#include "glad.h" +#include "KcGpuBuffer.h" +#include "KcGlslProgram.h" +#include "KcVertexDeclaration.h" + + +void KcRenderObject::draw() const +{ + const static GLenum glModes[] = { + GL_POINTS, + GL_LINES, + GL_LINE_STRIP, + GL_LINE_LOOP, + GL_TRIANGLES, + GL_TRIANGLE_STRIP, + GL_TRIANGLE_FAN, + GL_QUADS, + GL_QUAD_STRIP, + GL_POLYGON + }; + + // TODO: ˴ûбͻָrender״̬ + + vbo_->bind(); // vbo + vertexDecl_->declare(); // vboݹ + prog_->useProgram(); // shader + + glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vertexDecl_->calcVertexSize()); +} diff --git a/src/opengl/KcRenderObject.h b/src/opengl/KcRenderObject.h new file mode 100644 index 0000000..1ca277e --- /dev/null +++ b/src/opengl/KcRenderObject.h @@ -0,0 +1,51 @@ +#pragma once +#include + +class KcGpuBuffer; +class KcGlslProgram; +class KcVertexDeclaration; + + +// װȾ󣺰vboshader + +class KcRenderObject +{ +public: + + enum KeType + { + k_points, // Draws a point at each of the n vertices + k_lines, // Draws a series of unconnected line segments. Segments are drawn between v0 and v1, + // between v2 and v3, and so on.If n is odd, the last segment is drawn between vnC3and vnC2, and vnC1 is ignored. + k_line_strip, // Draws a line segment from v0 to v1, then from v1 to v2, and so on, finally drawing the segment + // from vnC2 to vnC1.Thus, a total of nC1 line segments are drawn.Nothing is drawn unless n + // is larger than 1. There are no restrictions on the vertices describing a line strip(or a line loop); the lines can intersect arbitrarily. + k_line_loop, // Same as k_line_strip, except that a final line segment is drawn from vnC1 to v0, completing a loop. + k_triangles, // Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v3, v4, v5, and so on. + // If n isnt a multiple of 3, the final one or two vertices are ignored + k_triangle_strip, // Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v2, v1, v3(note the order), then v2, v3, v4, and so on. + // The ordering is to ensure that the triangles are all drawn with the same orientation so that + // the strip can correctly form part of a surface. + // Preserving the orientation is important for some operations, such as culling. + // n must be at least 3 for anything to be drawn. + k_triangle_fan, // Same as k_triangle_strip, except that the vertices are v0, v1, v2, then v0, v2, v3, then v0, v3, v4, and so on + k_quads, // Draws a series of quadrilaterals (four-sided polygons) using vertices v0, v1, v2, v3, + // then v4, v5, v6, v7, and so on.If n isnt a multiple of 4, the final one, two, or three vertices are ignored. + k_quad_strip, // Draws a series of quadrilaterals (four-sided polygons) beginning with v0, v1, v3, v2, + // then v2, v3, v5, v4, then v4, v5, v7, v6, and so on + // n must be at least 4 before anything is drawn.If n is odd, the final vertex is ignored. + k_polygon // Draws a polygon using the points v0, ... , vnC1 as vertices. + // n must be at least 3, or nothing is drawn.In addition, the polygon specified must + // not intersect itselfand must be convex. If the vertices dont satisfy these conditions, the + // results are unpredictable. + }; + + + void draw() const; + +private: + KeType type_; + std::shared_ptr prog_; + std::shared_ptr vbo_; + std::shared_ptr vertexDecl_; +}; diff --git a/src/opengl/KcVertexAttribute.cpp b/src/opengl/KcVertexAttribute.cpp index d098c67..c057108 100644 --- a/src/opengl/KcVertexAttribute.cpp +++ b/src/opengl/KcVertexAttribute.cpp @@ -21,9 +21,6 @@ unsigned KcVertexAttribute::byteSize() const case k_short1_norm: return 2; - case k_color: - case k_color_argb: - case k_color_abgr: case k_float: case k_ubyte4: case k_ubyte4_norm: @@ -86,9 +83,6 @@ unsigned KcVertexAttribute::componentCount() const { switch(format_) { - case k_color: - case k_color_argb: - case k_color_abgr: case k_short1: case k_short1_norm: case k_float1: @@ -121,9 +115,6 @@ unsigned KcVertexAttribute::componentByteSize() const { switch(format_) { - case k_color: - case k_color_argb: - case k_color_abgr: case k_float1: case k_float2: case k_float3: @@ -147,3 +138,22 @@ unsigned KcVertexAttribute::componentByteSize() const return 0; } + + +bool KcVertexAttribute::normalized() const +{ + switch (format_) + { + case k_ubyte4_norm: + case k_short1_norm: + case k_short2_norm: + case k_short3_norm: + case k_short4_norm: + return true; + + default: + break; + } + + return false; +} diff --git a/src/opengl/KcVertexAttribute.h b/src/opengl/KcVertexAttribute.h index 562fb68..9750007 100644 --- a/src/opengl/KcVertexAttribute.h +++ b/src/opengl/KcVertexAttribute.h @@ -48,10 +48,6 @@ public: k_short2_norm, //> two-component normalized signed short (value / 32767.0f) k_short3_norm, k_short4_norm, //> four-component normalized signed short (value / 32767.0f) - - k_color, /// alias to more specific colour type - use the current rendersystem's colour packing - k_color_argb, /// D3D style compact color - k_color_abgr /// GL style compact color }; KcVertexAttribute() = default; @@ -84,6 +80,8 @@ public: // get the size in byte of per-component unsigned componentByteSize() const; + bool normalized() const; + private: /// The meaning of the attribute diff --git a/src/opengl/KcVertexDeclaration.cpp b/src/opengl/KcVertexDeclaration.cpp index 629f9e0..0a275fd 100644 --- a/src/opengl/KcVertexDeclaration.cpp +++ b/src/opengl/KcVertexDeclaration.cpp @@ -1,4 +1,6 @@ #include "KcVertexDeclaration.h" +#include "glad.h" +#include const KcVertexAttribute* KcVertexDeclaration::findAttribute(KcVertexAttribute::KeSemantic semantic, unsigned semanticIdx) const @@ -54,4 +56,24 @@ unsigned KcVertexDeclaration::texCoordCount() const } return c; -} \ No newline at end of file +} + + +void KcVertexDeclaration::declare() const +{ + for (unsigned i = 0; i < attributeCount(); i++) { + auto& attr = getAttribute(i); + glEnableVertexAttribArray(attr.location()); + int type = attr.baseType(); + if (type == KcVertexAttribute::k_float) + type = GL_FLOAT; + else if (type == KcVertexAttribute::k_short) + type = GL_SHORT; + else { + assert(false); + } + + glVertexAttribPointer(attr.location(), attr.componentCount(), type, + attr.normalized() ? GL_TRUE : GL_FALSE, 0, (void*)attr.offset()); // TODO: stride + } +} diff --git a/src/opengl/KcVertexDeclaration.h b/src/opengl/KcVertexDeclaration.h index 37332ce..6b885f5 100644 --- a/src/opengl/KcVertexDeclaration.h +++ b/src/opengl/KcVertexDeclaration.h @@ -7,6 +7,8 @@ class KcVertexDeclaration { public: + void declare() const; // ʹopenglvertexԸʽ + void pushAttribute(const KcVertexAttribute& attr) { attrs_.push_back(attr); } -- Gitee From 67093afd50306be18422c95e38a7b1d40380f9c1 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Tue, 13 Dec 2022 16:24:53 +0800 Subject: [PATCH 05/68] =?UTF-8?q?refactor:=20=E5=AE=8C=E5=96=84ImGui?= =?UTF-8?q?=E4=BE=A7=E7=9A=843d=E7=BA=BF=E6=AE=B5=E7=BB=98=E5=88=B6?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base/KtMatrix4.h | 10 +++- src/base/KtProjector3d.h | 44 +++++++++--------- src/imapp/KcImOglPaint.cpp | 74 +++++++++++++++++------------- src/imapp/KcImOglPaint.h | 9 ++++ src/imapp/KcImPaint.h | 2 +- src/opengl/KcRenderObject.cpp | 4 +- src/opengl/KcRenderObject.h | 18 +++++++- src/opengl/KcVertexDeclaration.cpp | 2 + 8 files changed, 104 insertions(+), 59 deletions(-) diff --git a/src/base/KtMatrix4.h b/src/base/KtMatrix4.h index 9a195fb..b4f2752 100644 --- a/src/base/KtMatrix4.h +++ b/src/base/KtMatrix4.h @@ -67,7 +67,15 @@ public: m3.m10(), m3.m11(), m3.m12(), 0, m3.m20(), m3.m21(), m3.m22(), 0, 0, 0, 0, 1 ) {} - + + template + KtMatrix4(const KtMatrix4& rhs) { + m00() = rhs.m00(), m01() = rhs.m01(), m02() = rhs.m02(), m03() = rhs.m03(), + m10() = rhs.m10(), m11() = rhs.m11(), m12() = rhs.m12(), m13() = rhs.m13(), + m20() = rhs.m20(), m21() = rhs.m21(), m22() = rhs.m22(), m23() = rhs.m23(), + m30() = rhs.m30(), m31() = rhs.m31(), m32() = rhs.m32(), m33() = rhs.m33(); + } + static mat4 zero() { return mat4(); } diff --git a/src/base/KtProjector3d.h b/src/base/KtProjector3d.h index 4520527..e362a21 100644 --- a/src/base/KtProjector3d.h +++ b/src/base/KtProjector3d.h @@ -50,6 +50,24 @@ public: const mat4& projMatrix() const { return projMat_; } mat4& projMatrix() { return projMat_; } + const mat4& getMvMat() const { + if (modelMats_.empty()) + return viewMat_; + + if (!mvMat_) + mvMat_ = viewMat_ * modelMats_.back(); + return mvMat_.value(); + } + + const mat4& getMvpMat() const { + if (modelMats_.empty()) + return vpMat_; + + if (!mvpMat_) + mvpMat_ = vpMat_ * modelMats_.back(); + return mvpMat_.value(); + } + const rect& viewport() const { return vp_; } void setViewport(const rect& vp); @@ -61,8 +79,8 @@ public: void updateProjectMatrixs(); vec4 localToWorld(const vec4& pt) const { return modelMats_.empty() ? pt : modelMats_.back() * pt; } - vec4 localToEye(const vec4& pt) const { return getMvMat_() * pt; } - vec4 localToClip(const vec4& pt) const { return getMvpMat_() * pt; } + vec4 localToEye(const vec4& pt) const { return getMvMat() * pt; } + vec4 localToClip(const vec4& pt) const { return getMvpMat() * pt; } vec4 localToNdc(const vec4& pt) const { return clipToNdc(localToClip(pt)); } vec4 localToViewport(const vec4& pt) const { return clipToViewport(localToClip(pt)); } vec4 localToScreen(const vec4& pt) const { return clipToScreen(localToClip(pt)); } @@ -117,24 +135,6 @@ private: void resetModelRelatedMats_(); - const mat4& getMvMat_() const { - if (modelMats_.empty()) - return viewMat_; - - if (!mvMat_) - mvMat_ = viewMat_ * modelMats_.back(); - return mvMat_.value(); - } - - const mat4& getMvpMat_() const { - if (modelMats_.empty()) - return vpMat_; - - if (!mvpMat_) - mvpMat_ = vpMat_ * modelMats_.back(); - return mvpMat_.value(); - } - const mat4& getMMatR_() const { if (!mMatR_) mMatR_ = modelMats_.back().getInverse(); @@ -146,7 +146,7 @@ private: return getViewMatR_(); if (!mvMatR_) - mvMatR_ = getMvMat_().getInverse(); + mvMatR_ = getMvMat().getInverse(); return mvMatR_.value(); } @@ -155,7 +155,7 @@ private: return getVpMatR_(); if (!mvpMatR_) - mvpMatR_ = getMvpMat_().getInverse(); + mvpMatR_ = getMvpMat().getInverse(); return mvpMatR_.value(); } diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index e41e1c6..8995dd7 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -3,57 +3,67 @@ #include "glad.h" #include "opengl/KcGlslProgram.h" #include "opengl/KcGlslShader.h" -#include "opengl/KcBufferObject.h" +#include "opengl/KcGpuBuffer.h" +#include "opengl/KcVertexDeclaration.h" namespace kPrivate { const static char* vertex_shader_glsl_130 = - "uniform mat4 ProjMtx;\n" + "uniform mat4 matMvp;\n" "in vec2 Position;\n" - "in vec4 Color;\n" - "out vec4 Frag_Color;\n" "void main()\n" "{\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" + " gl_Position = matMvp * vec4(Position.xyz, 1);\n" "}\n"; +} - const static char* fragment_shader_glsl_130 = - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color;\n" - "}\n"; + +void oglDrawCallback(const ImDrawList* parent_list, const ImDrawCmd* cmd) +{ + auto objs = (std::vector>*)cmd->UserCallbackData; + for (auto& i : *objs) + i->draw(); } -void oglDrawLineStrip(const ImDrawList* parent_list, const ImDrawCmd* cmd) +void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) { - KcGlslProgram prog; - prog.attachShader(new KcGlslShader(KcGlslShader::k_shader_vertex, kPrivate::vertex_shader_glsl_130)); - prog.attachShader(new KcGlslShader(KcGlslShader::k_shader_fragment, kPrivate::fragment_shader_glsl_130)); - std::string info; + auto prog = std::make_shared(); + prog->attachShader(new KcGlslShader(KcGlslShader::k_shader_vertex, kPrivate::vertex_shader_glsl_130)); + prog->shaderAt(0)->compile(); + prog->link(); - if (!prog.shaderAt(0)->compile()) - info = prog.shaderAt(0)->infoLog(); - prog.shaderAt(1)->compile(); - prog.link(); + objs_.emplace_back(new KcRenderObject(KcRenderObject::k_line_strip, prog)); - auto oldProg = prog.currentProgram(); - prog.useProgram(); + auto decl = std::make_shared(); + KcVertexAttribute attr(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); + decl->pushAttribute(attr); + + auto vbo = std::make_shared(); + std::vector vtx; + for (unsigned i = 0; i < count; i++) // װ + vtx.push_back(fn(i)); + vbo->setData(vtx.data(), vtx.size() * sizeof(point3f), KcGpuBuffer::k_stream_draw); + objs_.back()->setVbo(vbo, decl); + objs_.back()->setProjMatrix(camera_.getMvpMat()); +} - cmd->UserCallbackData; - - int count(100); - glDrawArrays(GL_LINE_STRIP, 0, count); - prog.useProgram(oldProg); +void KcImOglPaint::beginPaint() +{ + objs_.clear(); + super_::beginPaint(); } -void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) + +void KcImOglPaint::endPaint() { - auto dl = ImGui::GetWindowDrawList(); - dl->AddCallback(oglDrawLineStrip, nullptr); + if (!objs_.empty()) { + auto dl = ImGui::GetWindowDrawList(); + dl->AddCallback(oglDrawCallback, &objs_); + dl->AddCallback(ImDrawCallback_ResetRenderState, nullptr); // imguiָȾ״̬ + } + + super_::endPaint(); } diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index cc148dd..6872e78 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -1,5 +1,8 @@ #pragma once #include "KcImPaint.h" +#include +#include +#include "opengl/KcRenderObject.h" // ImGuiOpenGLKvPaintʵ @@ -12,6 +15,12 @@ public: using super_::super_; + void beginPaint() override; + void endPaint() override; + void drawLineStrip(point_getter fn, unsigned count) override; + +private: + std::vector> objs_; }; diff --git a/src/imapp/KcImPaint.h b/src/imapp/KcImPaint.h index 2b5fc84..b14bada 100644 --- a/src/imapp/KcImPaint.h +++ b/src/imapp/KcImPaint.h @@ -85,7 +85,7 @@ private: void drawLinePattern_(const ImVec2& from, const ImVec2& to, const std::vector& pat); -private: +protected: camera_type& camera_; color_t clr_{ 0, 0, 0, 1 }; float_t lineWidth_{ 1 }; diff --git a/src/opengl/KcRenderObject.cpp b/src/opengl/KcRenderObject.cpp index 18d86c2..26c338d 100644 --- a/src/opengl/KcRenderObject.cpp +++ b/src/opengl/KcRenderObject.cpp @@ -23,8 +23,8 @@ void KcRenderObject::draw() const // TODO: ˴ûбͻָrender״̬ vbo_->bind(); // vbo - vertexDecl_->declare(); // vboݹ + vtxDecl_->declare(); // vboݹ prog_->useProgram(); // shader - glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vertexDecl_->calcVertexSize()); + glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vtxDecl_->calcVertexSize()); } diff --git a/src/opengl/KcRenderObject.h b/src/opengl/KcRenderObject.h index 1ca277e..73dd8d8 100644 --- a/src/opengl/KcRenderObject.h +++ b/src/opengl/KcRenderObject.h @@ -1,5 +1,6 @@ #pragma once #include +#include "KtMatrix4.h" class KcGpuBuffer; class KcGlslProgram; @@ -41,11 +42,26 @@ public: }; + KcRenderObject(KeType type, std::shared_ptr prog) + : type_(type), prog_(prog) {} + + KcRenderObject(const KcRenderObject& rhs) + : type_(rhs.type_), prog_(rhs.prog_), vbo_(rhs.vbo_), vtxDecl_(rhs.vtxDecl_) {} + + void setVbo(std::shared_ptr vbo, std::shared_ptr vtxDecl) { + vbo_ = vbo, vtxDecl_ = vtxDecl; + } + + void setProjMatrix(const float4x4<>& projMat) { + projMat_ = projMat; + } + void draw() const; private: KeType type_; std::shared_ptr prog_; std::shared_ptr vbo_; - std::shared_ptr vertexDecl_; + std::shared_ptr vtxDecl_; + float4x4<> projMat_; }; diff --git a/src/opengl/KcVertexDeclaration.cpp b/src/opengl/KcVertexDeclaration.cpp index 0a275fd..c71f3bc 100644 --- a/src/opengl/KcVertexDeclaration.cpp +++ b/src/opengl/KcVertexDeclaration.cpp @@ -69,6 +69,8 @@ void KcVertexDeclaration::declare() const type = GL_FLOAT; else if (type == KcVertexAttribute::k_short) type = GL_SHORT; + else if (type == KcVertexAttribute::k_ubyte4) + type = GL_UNSIGNED_BYTE; else { assert(false); } -- Gitee From 84cbf5e8ae1c1531fa43f47849a6f0097d28788b Mon Sep 17 00:00:00 2001 From: koala999 Date: Tue, 13 Dec 2022 19:00:16 +0800 Subject: [PATCH 06/68] =?UTF-8?q?add:=20=E5=AE=9E=E7=8E=B0opengl=E7=BB=98?= =?UTF-8?q?=E5=88=B6linestrip=EF=BC=8C=E8=B4=A8=E9=87=8F=E5=92=8C=E6=95=88?= =?UTF-8?q?=E7=8E=87=E9=83=BD=E6=9E=81=E5=A4=A7=E6=8F=90=E5=8D=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 19 ++++++++++++++++++- src/opengl/KcRenderObject.cpp | 2 ++ src/opengl/KcRenderObject.h | 8 ++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 8995dd7..e13f1d5 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -11,10 +11,19 @@ namespace kPrivate { const static char* vertex_shader_glsl_130 = "uniform mat4 matMvp;\n" - "in vec2 Position;\n" + "in vec3 Position;\n" + "out vec4 Frag_Color;\n" "void main()\n" "{\n" " gl_Position = matMvp * vec4(Position.xyz, 1);\n" + " Frag_Color = vec4(1, 0, 0, 1);\n" + "}\n"; + + const static char* fragment_shader_glsl_130 = + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color;\n" "}\n"; } @@ -31,8 +40,12 @@ void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) { auto prog = std::make_shared(); prog->attachShader(new KcGlslShader(KcGlslShader::k_shader_vertex, kPrivate::vertex_shader_glsl_130)); + prog->attachShader(new KcGlslShader(KcGlslShader::k_shader_fragment, kPrivate::fragment_shader_glsl_130)); prog->shaderAt(0)->compile(); + prog->shaderAt(1)->compile(); + auto info = prog->shaderAt(0)->infoLog(); prog->link(); + assert(prog->linked() && prog->linkStatus()); objs_.emplace_back(new KcRenderObject(KcRenderObject::k_line_strip, prog)); @@ -47,6 +60,10 @@ void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) vbo->setData(vtx.data(), vtx.size() * sizeof(point3f), KcGpuBuffer::k_stream_draw); objs_.back()->setVbo(vbo, decl); objs_.back()->setProjMatrix(camera_.getMvpMat()); + auto vp = viewport(); // openglviewportԭ½ǣ˴Ҫתyֵ + vp.lower().y() = ImGui::GetWindowViewport()->Size.y - vp.upper().y() - vp.height(); // TODO: ??? + vp.setExtent(1, viewport().height()); + objs_.back()->setViewport(vp); } diff --git a/src/opengl/KcRenderObject.cpp b/src/opengl/KcRenderObject.cpp index 26c338d..77095ad 100644 --- a/src/opengl/KcRenderObject.cpp +++ b/src/opengl/KcRenderObject.cpp @@ -25,6 +25,8 @@ void KcRenderObject::draw() const vbo_->bind(); // vbo vtxDecl_->declare(); // vboݹ prog_->useProgram(); // shader + glUniformMatrix4fv(0, 1, GL_TRUE, projMat_.data()); + glViewport(vp_.lower().x(), vp_.upper().y(), vp_.width(), vp_.height()); glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vtxDecl_->calcVertexSize()); } diff --git a/src/opengl/KcRenderObject.h b/src/opengl/KcRenderObject.h index 73dd8d8..77cdfc8 100644 --- a/src/opengl/KcRenderObject.h +++ b/src/opengl/KcRenderObject.h @@ -1,6 +1,7 @@ #pragma once #include #include "KtMatrix4.h" +#include "KtAABB.h" class KcGpuBuffer; class KcGlslProgram; @@ -11,6 +12,8 @@ class KcVertexDeclaration; class KcRenderObject { + using rect_t = KtAABB; + public: enum KeType @@ -56,6 +59,10 @@ public: projMat_ = projMat; } + void setViewport(const rect_t& vp) { + vp_ = vp; + } + void draw() const; private: @@ -64,4 +71,5 @@ private: std::shared_ptr vbo_; std::shared_ptr vtxDecl_; float4x4<> projMat_; + rect_t vp_; }; -- Gitee From 10a34b4659135384f92a7b03209bd0ca54cbf391 Mon Sep 17 00:00:00 2001 From: koala999 Date: Tue, 13 Dec 2022 20:52:31 +0800 Subject: [PATCH 07/68] =?UTF-8?q?new:=20=E5=BC=95=E5=85=A5KsShaderManager?= =?UTF-8?q?=E7=AE=80=E5=8C=96opengl=20shader=E7=9A=84=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataVis.vcxproj | 4 ++ DataVis.vcxproj.filters | 12 +++++ src/imapp/KcImOglPaint.cpp | 92 ++++++++++++++-------------------- src/imapp/KcImOglPaint.h | 4 ++ src/opengl/KcGlslProgram.cpp | 9 ++-- src/opengl/KcGlslProgram.h | 4 +- src/opengl/KcLineObject.cpp | 22 ++++++++ src/opengl/KcLineObject.h | 28 +++++++++++ src/opengl/KcRenderObject.h | 4 +- src/opengl/KsShaderManager.cpp | 70 ++++++++++++++++++++++++++ src/opengl/KsShaderManager.h | 43 ++++++++++++++++ 11 files changed, 231 insertions(+), 61 deletions(-) create mode 100644 src/opengl/KcLineObject.cpp create mode 100644 src/opengl/KcLineObject.h create mode 100644 src/opengl/KsShaderManager.cpp create mode 100644 src/opengl/KsShaderManager.h diff --git a/DataVis.vcxproj b/DataVis.vcxproj index 0807130..e10e8cf 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -181,9 +181,11 @@ + + @@ -361,9 +363,11 @@ + + diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index fdcfd09..2aaf1ea 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -445,6 +445,12 @@ opengl + + opengl + + + opengl + @@ -1011,5 +1017,11 @@ opengl + + opengl + + + opengl + \ No newline at end of file diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index e13f1d5..9c0a8c2 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -5,49 +5,54 @@ #include "opengl/KcGlslShader.h" #include "opengl/KcGpuBuffer.h" #include "opengl/KcVertexDeclaration.h" +#include "opengl/KcLineObject.h" namespace kPrivate { - const static char* vertex_shader_glsl_130 = - "uniform mat4 matMvp;\n" - "in vec3 Position;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " gl_Position = matMvp * vec4(Position.xyz, 1);\n" - " Frag_Color = vec4(1, 0, 0, 1);\n" - "}\n"; + void oglDrawCallback(const ImDrawList* parent_list, const ImDrawCmd* cmd) + { + auto objs = (std::vector>*)cmd->UserCallbackData; + for (auto& i : *objs) + i->draw(); + } +} - const static char* fragment_shader_glsl_130 = - "varying vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " gl_FragColor = Frag_Color;\n" - "}\n"; +void KcImOglPaint::beginPaint() +{ + objs_.clear(); + super_::beginPaint(); } -void oglDrawCallback(const ImDrawList* parent_list, const ImDrawCmd* cmd) +void KcImOglPaint::endPaint() { - auto objs = (std::vector>*)cmd->UserCallbackData; - for (auto& i : *objs) - i->draw(); + if (!objs_.empty()) { + auto dl = ImGui::GetWindowDrawList(); + dl->AddCallback(kPrivate::oglDrawCallback, &objs_); + dl->AddCallback(ImDrawCallback_ResetRenderState, nullptr); // imguiָȾ״̬ + } + + super_::endPaint(); } -void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) +void KcImOglPaint::pushRenderObject_(KcRenderObject* obj) { - auto prog = std::make_shared(); - prog->attachShader(new KcGlslShader(KcGlslShader::k_shader_vertex, kPrivate::vertex_shader_glsl_130)); - prog->attachShader(new KcGlslShader(KcGlslShader::k_shader_fragment, kPrivate::fragment_shader_glsl_130)); - prog->shaderAt(0)->compile(); - prog->shaderAt(1)->compile(); - auto info = prog->shaderAt(0)->infoLog(); - prog->link(); - assert(prog->linked() && prog->linkStatus()); + obj->setProjMatrix(camera_.getMvpMat()); - objs_.emplace_back(new KcRenderObject(KcRenderObject::k_line_strip, prog)); + auto vp = viewport(); // openglviewportԭ½ǣ˴Ҫתyֵ + vp.lower().y() = ImGui::GetWindowViewport()->Size.y - vp.upper().y() - vp.height(); // TODO: ??? + vp.setExtent(1, viewport().height()); + obj->setViewport(vp); + + objs_.emplace_back(obj); +} + + +void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) +{ + auto obj = new KcLineObject(KcRenderObject::k_line_strip); auto decl = std::make_shared(); KcVertexAttribute attr(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); @@ -58,29 +63,8 @@ void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) for (unsigned i = 0; i < count; i++) // װ vtx.push_back(fn(i)); vbo->setData(vtx.data(), vtx.size() * sizeof(point3f), KcGpuBuffer::k_stream_draw); - objs_.back()->setVbo(vbo, decl); - objs_.back()->setProjMatrix(camera_.getMvpMat()); - auto vp = viewport(); // openglviewportԭ½ǣ˴Ҫתyֵ - vp.lower().y() = ImGui::GetWindowViewport()->Size.y - vp.upper().y() - vp.height(); // TODO: ??? - vp.setExtent(1, viewport().height()); - objs_.back()->setViewport(vp); -} - - -void KcImOglPaint::beginPaint() -{ - objs_.clear(); - super_::beginPaint(); -} - -void KcImOglPaint::endPaint() -{ - if (!objs_.empty()) { - auto dl = ImGui::GetWindowDrawList(); - dl->AddCallback(oglDrawCallback, &objs_); - dl->AddCallback(ImDrawCallback_ResetRenderState, nullptr); // imguiָȾ״̬ - } - - super_::endPaint(); -} + obj->setVbo(vbo, decl); + obj->setColor(clr_); + pushRenderObject_(obj); +} \ No newline at end of file diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index 6872e78..54bd023 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -21,6 +21,10 @@ public: void drawLineStrip(point_getter fn, unsigned count) override; +private: + + void pushRenderObject_(KcRenderObject* obj); + private: std::vector> objs_; }; diff --git a/src/opengl/KcGlslProgram.cpp b/src/opengl/KcGlslProgram.cpp index bd4e5eb..cf3486e 100644 --- a/src/opengl/KcGlslProgram.cpp +++ b/src/opengl/KcGlslProgram.cpp @@ -172,13 +172,13 @@ int KcGlslProgram::getAttribLocation(const std::string_view& name) const } -bool KcGlslProgram::attachShader(KcGlslShader* shader) +bool KcGlslProgram::attachShader(std::shared_ptr shader) { create(); scheduleRelinking_(); - detachShader(shader); + detachShader(shader.get()); shaders_.emplace_back(shader); glAttachShader(handle(), shader->handle()); @@ -234,8 +234,11 @@ void KcGlslProgram::getUniformiv(int location, int* params) const } -void KcGlslProgram::useProgram() const +void KcGlslProgram::useProgram() { + if (!linked()) + link(true); + useProgram(handle()); } diff --git a/src/opengl/KcGlslProgram.h b/src/opengl/KcGlslProgram.h index 17221ca..18e68a6 100644 --- a/src/opengl/KcGlslProgram.h +++ b/src/opengl/KcGlslProgram.h @@ -63,7 +63,7 @@ public: * Attaches the GLSLShader to this GLSLProgram * Attaching a shader triggers the compilation of the shader (if not already compiled) and relinking of the program. */ - bool attachShader(KcGlslShader* shader); + bool attachShader(std::shared_ptr shader); // Detaches a GLSLShader from the GLSLShader (note: it does NOT schedule a relink of the program) bool detachShader(KcGlslShader* shader); @@ -109,7 +109,7 @@ public: getUniformiv(getUniformLocation(name), params); } - void useProgram() const; + void useProgram(); static unsigned currentProgram(); diff --git a/src/opengl/KcLineObject.cpp b/src/opengl/KcLineObject.cpp new file mode 100644 index 0000000..bb523c5 --- /dev/null +++ b/src/opengl/KcLineObject.cpp @@ -0,0 +1,22 @@ +#include "KcLineObject.h" +#include "glad.h" +#include "KsShaderManager.h" +#include "opengl/KcGlslProgram.h" + + +KcLineObject::KcLineObject(KeType type) + : super_(type, KsShaderManager::singleton().programMono()) +{ + +} + + +void KcLineObject::draw() const +{ + glLineWidth(lineWidth_); + prog_->useProgram(); + //auto loc = prog_->getUniformLocation("vColor"); + glUniform4f(1, lineColor_[0], lineColor_[1], lineColor_[2], lineColor_[3]); + super_::draw(); +} + diff --git a/src/opengl/KcLineObject.h b/src/opengl/KcLineObject.h new file mode 100644 index 0000000..df63a7f --- /dev/null +++ b/src/opengl/KcLineObject.h @@ -0,0 +1,28 @@ +#pragma once +#include "KcRenderObject.h" + + +// openglߵvboshaderԼuniformװ + +class KcLineObject : public KcRenderObject +{ + using super_ = KcRenderObject; + +public: + + KcLineObject(KeType type = k_line_strip); + + void setColor(const float4& clr) { + lineColor_ = clr; + } + + void setWidth(float w) { + lineWidth_ = w; + } + + void draw() const override; + +private: + float4 lineColor_{1, 0, 0, 1}; + float lineWidth_{ 1 }; +}; \ No newline at end of file diff --git a/src/opengl/KcRenderObject.h b/src/opengl/KcRenderObject.h index 77cdfc8..072c83e 100644 --- a/src/opengl/KcRenderObject.h +++ b/src/opengl/KcRenderObject.h @@ -63,9 +63,9 @@ public: vp_ = vp; } - void draw() const; + virtual void draw() const; -private: +protected: KeType type_; std::shared_ptr prog_; std::shared_ptr vbo_; diff --git a/src/opengl/KsShaderManager.cpp b/src/opengl/KsShaderManager.cpp new file mode 100644 index 0000000..69b68a2 --- /dev/null +++ b/src/opengl/KsShaderManager.cpp @@ -0,0 +1,70 @@ +#include "KsShaderManager.h" +#include "KcGlslShader.h" +#include "KcGlslProgram.h" +#include + + +KsShaderManager::KsShaderManager() +{ + +} + + +KsShaderManager::~KsShaderManager() +{ + +} + + +KsShaderManager::shader_ptr KsShaderManager::vertexShaderMono() +{ + const static char* vertex_shader_mono = + "uniform mat4 mvpMat;\n" + "uniform vec4 vColor;\n" + "in vec3 position;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_Position = mvpMat * vec4(position, 1);\n" + " Frag_Color = vColor;\n" + "}\n"; + + if (vertexShaderMono_ == nullptr) { + vertexShaderMono_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_mono); + assert(vertexShaderMono_->compileStatus()); + } + + return vertexShaderMono_; +} + + +KsShaderManager::shader_ptr KsShaderManager::fragShaderNaive() +{ + const static char* frag_shader_naive = + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color;\n" + "}\n"; + + if (fragShaderNaive_ == nullptr) { + fragShaderNaive_ = std::make_shared(KcGlslShader::k_shader_fragment, frag_shader_naive); + assert(fragShaderNaive_->compileStatus()); + } + + return fragShaderNaive_; +} + + +KsShaderManager::program_ptr KsShaderManager::programMono() +{ + if (progMono_ == nullptr) { + progMono_ = std::make_shared(); + progMono_->attachShader(vertexShaderMono()); + progMono_->attachShader(fragShaderNaive()); + progMono_->link(); + assert(progMono_->linked() && progMono_->linkStatus()); + } + + return progMono_; +} \ No newline at end of file diff --git a/src/opengl/KsShaderManager.h b/src/opengl/KsShaderManager.h new file mode 100644 index 0000000..f017e38 --- /dev/null +++ b/src/opengl/KsShaderManager.h @@ -0,0 +1,43 @@ +#pragma once +#include +#include "KtSingleton.h" + +class KcGlslShader; +class KcGlslProgram; + +// װõopengl shaders + +class KsShaderManager +{ +public: + using singleton_type = KtSingleton; + friend singleton_type; + + static KsShaderManager& singleton() { + return *singleton_type::instance(); + } + + using shader_ptr = std::shared_ptr; + using program_ptr = std::shared_ptr; + + shader_ptr vertexShaderMono(); + + shader_ptr fragShaderNaive(); + + program_ptr programMono(); + +private: + KsShaderManager(); + ~KsShaderManager(); + + KsShaderManager(const KsShaderManager&) = delete; + void operator=(const KsShaderManager&) = delete; + + +private: + + shader_ptr vertexShaderMono_; + shader_ptr fragShaderNaive_; + + program_ptr progMono_; +}; -- Gitee From 7d299dbc1a8b996bdcf20cc6fa0ee99fbcdd81aa Mon Sep 17 00:00:00 2001 From: koala999cn Date: Wed, 14 Dec 2022 09:06:10 +0800 Subject: [PATCH 08/68] =?UTF-8?q?new:=20=E5=AE=9E=E7=8E=B0opengl=E7=BB=98?= =?UTF-8?q?=E5=88=B6points?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataVis.vcxproj | 2 ++ DataVis.vcxproj.filters | 6 ++++++ src/imapp/KcImOglPaint.cpp | 23 +++++++++++++++++++++++ src/imapp/KcImOglPaint.h | 2 ++ src/imapp/KcImPaint.h | 2 +- src/imapp/KcImPlot3d.cpp | 4 ++-- src/opengl/KcLineObject.cpp | 1 - src/opengl/KcPointObject.cpp | 20 ++++++++++++++++++++ src/opengl/KcPointObject.h | 29 +++++++++++++++++++++++++++++ src/plot/KcScatter.h | 2 +- src/plot/KvPaint.cpp | 22 +++++++++++++++------- 11 files changed, 101 insertions(+), 12 deletions(-) create mode 100644 src/opengl/KcPointObject.cpp create mode 100644 src/opengl/KcPointObject.h diff --git a/DataVis.vcxproj b/DataVis.vcxproj index e10e8cf..d740bb1 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -182,6 +182,7 @@ + @@ -364,6 +365,7 @@ + diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index 2aaf1ea..5eb0cff 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -451,6 +451,9 @@ opengl + + opengl + @@ -1023,5 +1026,8 @@ opengl + + opengl + \ No newline at end of file diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 9c0a8c2..3e7c228 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -5,6 +5,7 @@ #include "opengl/KcGlslShader.h" #include "opengl/KcGpuBuffer.h" #include "opengl/KcVertexDeclaration.h" +#include "opengl/KcPointObject.h" #include "opengl/KcLineObject.h" @@ -50,6 +51,27 @@ void KcImOglPaint::pushRenderObject_(KcRenderObject* obj) } +void KcImOglPaint::drawPoints(point_getter fn, unsigned count) +{ + auto obj = new KcPointObject; + + auto decl = std::make_shared(); + KcVertexAttribute attr(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); + decl->pushAttribute(attr); + + auto vbo = std::make_shared(); + std::vector vtx; + for (unsigned i = 0; i < count; i++) // װ + vtx.push_back(fn(i)); + vbo->setData(vtx.data(), vtx.size() * sizeof(point3f), KcGpuBuffer::k_stream_draw); + + obj->setVbo(vbo, decl); + obj->setColor(clr_); + obj->setSize(pointSize_); + pushRenderObject_(obj); +} + + void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) { auto obj = new KcLineObject(KcRenderObject::k_line_strip); @@ -66,5 +88,6 @@ void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) obj->setVbo(vbo, decl); obj->setColor(clr_); + obj->setWidth(lineWidth_); pushRenderObject_(obj); } \ No newline at end of file diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index 54bd023..5b3e995 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -18,6 +18,8 @@ public: void beginPaint() override; void endPaint() override; + void drawPoints(point_getter fn, unsigned count) override; + void drawLineStrip(point_getter fn, unsigned count) override; diff --git a/src/imapp/KcImPaint.h b/src/imapp/KcImPaint.h index b14bada..f048aed 100644 --- a/src/imapp/KcImPaint.h +++ b/src/imapp/KcImPaint.h @@ -90,7 +90,7 @@ protected: color_t clr_{ 0, 0, 0, 1 }; float_t lineWidth_{ 1 }; int lineStyle_{ 0 }; - float_t pointSize_{ 2 }; + float_t pointSize_{ 1 }; KtMatrix4 vp_; // 任 diff --git a/src/imapp/KcImPlot3d.cpp b/src/imapp/KcImPlot3d.cpp index 3675cc7..6542c87 100644 --- a/src/imapp/KcImPlot3d.cpp +++ b/src/imapp/KcImPlot3d.cpp @@ -1,12 +1,12 @@ #include "KcImPlot3d.h" -#include "KcImPaint.h" +#include "KcImOglPaint.h" #include "imgui.h" #include "plot/KcCoord3d.h" #include "KuStrUtil.h" KcImPlot3d::KcImPlot3d(const std::string_view& name) - : KvPlot3d(std::make_shared(camera_), std::make_shared()) + : KvPlot3d(std::make_shared(camera_), std::make_shared()) , KvImWindow(name) , trackball_(orient_) { diff --git a/src/opengl/KcLineObject.cpp b/src/opengl/KcLineObject.cpp index bb523c5..76a1c67 100644 --- a/src/opengl/KcLineObject.cpp +++ b/src/opengl/KcLineObject.cpp @@ -15,7 +15,6 @@ void KcLineObject::draw() const { glLineWidth(lineWidth_); prog_->useProgram(); - //auto loc = prog_->getUniformLocation("vColor"); glUniform4f(1, lineColor_[0], lineColor_[1], lineColor_[2], lineColor_[3]); super_::draw(); } diff --git a/src/opengl/KcPointObject.cpp b/src/opengl/KcPointObject.cpp new file mode 100644 index 0000000..c670bfa --- /dev/null +++ b/src/opengl/KcPointObject.cpp @@ -0,0 +1,20 @@ +#include "KcPointObject.h" +#include "glad.h" +#include "KsShaderManager.h" +#include "opengl/KcGlslProgram.h" + + +KcPointObject::KcPointObject() + : super_(k_points, KsShaderManager::singleton().programMono()) +{ + +} + + +void KcPointObject::draw() const +{ + glPointSize(pointSize_); + prog_->useProgram(); + glUniform4f(1, pointColor_[0], pointColor_[1], pointColor_[2], pointColor_[3]); + super_::draw(); +} diff --git a/src/opengl/KcPointObject.h b/src/opengl/KcPointObject.h new file mode 100644 index 0000000..080e69b --- /dev/null +++ b/src/opengl/KcPointObject.h @@ -0,0 +1,29 @@ +#pragma once +#include "KcRenderObject.h" + + +// openglvboshaderԼuniformװ + +class KcPointObject : public KcRenderObject +{ + using super_ = KcRenderObject; + +public: + + KcPointObject(); + + void setColor(const float4& clr) { + pointColor_ = clr; + } + + void setSize(float s) { + pointSize_ = s; + } + + void draw() const override; + +private: + float4 pointColor_{ 1, 0, 0, 1 }; + float pointSize_{ 2 }; +}; + diff --git a/src/plot/KcScatter.h b/src/plot/KcScatter.h index 0870025..e324e5b 100644 --- a/src/plot/KcScatter.h +++ b/src/plot/KcScatter.h @@ -35,5 +35,5 @@ private: protected: KpPen scatPen_; KpBrush scatBrush_; - float size_{ 3 }; + float size_{ 1 }; }; diff --git a/src/plot/KvPaint.cpp b/src/plot/KvPaint.cpp index 3f6f0a3..10e3f95 100644 --- a/src/plot/KvPaint.cpp +++ b/src/plot/KvPaint.cpp @@ -4,8 +4,11 @@ void KvPaint::drawPoints(const point3 pts[], unsigned count) { - for (unsigned i = 0; i < count; i++) - drawPoint(pts[i]); + auto getter = [pts](unsigned idx) { + return pts[idx]; + }; + + drawPoints(getter, count); } @@ -18,8 +21,11 @@ void KvPaint::drawPoints(point_getter fn, unsigned count) void KvPaint::drawLineStrip(const point3 pts[], unsigned count) { - for (unsigned i = 1; i < count; i++) - drawLine(pts[i - 1], pts[i]); + auto getter = [pts](unsigned idx) { + return pts[idx]; + }; + + drawLineStrip(getter, count); } @@ -32,9 +38,11 @@ void KvPaint::drawLineStrip(point_getter fn, unsigned count) void KvPaint::drawLineLoop(const point3 pts[], unsigned count) { - drawLineStrip(pts, count); - if (count > 2) - drawLine(pts[count - 1], pts[0]); + auto getter = [pts](unsigned idx) { + return pts[idx]; + }; + + drawLineLoop(getter, count); } -- Gitee From 2c89620a119f91fe0a6ac408c532ae2876e91f6e Mon Sep 17 00:00:00 2001 From: koala999cn Date: Wed, 14 Dec 2022 10:09:12 +0800 Subject: [PATCH 09/68] =?UTF-8?q?fix:=20=E5=88=A0=E9=99=A4colorBar?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E5=B8=83=E5=B1=80=E5=90=8C=E6=AD=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KvPlot.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index a5c9b36..36f9bb7 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -201,6 +201,7 @@ void KvPlot::syncLegendAndColorBar_(KvPlottable* removedPlt, KvPlottable* addedP } else { assert(colorBar_); + KuLayoutHelper::take(colorBar_); if (colorBar_) delete colorBar_; colorBar_ = nullptr; } -- Gitee From e2c09ea3e13958b23638955bbc72d3b42b221de6 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Wed, 14 Dec 2022 11:27:32 +0800 Subject: [PATCH 10/68] clean code --- src/imapp/KcImOglPaint.cpp | 31 ++++++++++++++++++++++++++++++- src/imapp/KcImOglPaint.h | 2 ++ src/opengl/KcPointObject.cpp | 4 ++++ src/opengl/KcRenderObject.h | 4 ++-- src/plot/KvPlot.cpp | 6 +++++- 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 3e7c228..bce7109 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -43,7 +43,7 @@ void KcImOglPaint::pushRenderObject_(KcRenderObject* obj) obj->setProjMatrix(camera_.getMvpMat()); auto vp = viewport(); // openglviewportԭ½ǣ˴Ҫתyֵ - vp.lower().y() = ImGui::GetWindowViewport()->Size.y - vp.upper().y() - vp.height(); // TODO: ??? + vp.lower().y() = ImGui::GetWindowViewport()->Size.y - (vp.upper().y() + vp.height()); vp.setExtent(1, viewport().height()); obj->setViewport(vp); @@ -51,6 +51,35 @@ void KcImOglPaint::pushRenderObject_(KcRenderObject* obj) } +void KcImOglPaint::drawPoint(const point3& pt) +{ + super_::drawPoint(pt); + +#if 0 // TODO: + auto progId = KcGlslProgram::currentProgram(); + + KcGlslProgram::useProgram(0); // shaderʹù̶߻ + + glMatrixMode(GL_PROJECTION); + glLoadMatrixd(camera_.projMatrix().data()); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixd(camera_.viewMatrix().data()); + + glPointSize(pointSize_); + glEnable(GL_POINT_SMOOTH); + glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); + //glEnable(GL_BLEND); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBegin(GL_POINTS); + glColor4f(clr_.r(), clr_.g(), clr_.b(), clr_.a()); + glVertex3f(pt.x(), pt.y(), pt.z()); + glEnd(); + + KcGlslProgram::useProgram(progId); +#endif +} + + void KcImOglPaint::drawPoints(point_getter fn, unsigned count) { auto obj = new KcPointObject; diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index 5b3e995..d8e5ede 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -18,6 +18,8 @@ public: void beginPaint() override; void endPaint() override; + void drawPoint(const point3& pt) override; + void drawPoints(point_getter fn, unsigned count) override; void drawLineStrip(point_getter fn, unsigned count) override; diff --git a/src/opengl/KcPointObject.cpp b/src/opengl/KcPointObject.cpp index c670bfa..1ea7d3e 100644 --- a/src/opengl/KcPointObject.cpp +++ b/src/opengl/KcPointObject.cpp @@ -14,6 +14,10 @@ KcPointObject::KcPointObject() void KcPointObject::draw() const { glPointSize(pointSize_); + glEnable(GL_POINT_SMOOTH); + glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); + //glEnable(GL_BLEND); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); prog_->useProgram(); glUniform4f(1, pointColor_[0], pointColor_[1], pointColor_[2], pointColor_[3]); super_::draw(); diff --git a/src/opengl/KcRenderObject.h b/src/opengl/KcRenderObject.h index 072c83e..981e3f8 100644 --- a/src/opengl/KcRenderObject.h +++ b/src/opengl/KcRenderObject.h @@ -59,7 +59,7 @@ public: projMat_ = projMat; } - void setViewport(const rect_t& vp) { + void setViewport(const rect_t& vp) { // TODO: Ƶȥͳһ vp_ = vp; } @@ -71,5 +71,5 @@ protected: std::shared_ptr vbo_; std::shared_ptr vtxDecl_; float4x4<> projMat_; - rect_t vp_; + rect_t vp_; // 浥ӿڣֶ֧രڻ }; diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index 36f9bb7..b1646eb 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -212,7 +212,11 @@ void KvPlot::syncLegendAndColorBar_(KvPlottable* removedPlt, KvPlottable* addedP legend_->addItem(addedPlt); } else { - assert(colorBar_ == nullptr); + assert(colorBar_ == nullptr); // TODO: ͨ + if (colorBar_) { + KuLayoutHelper::take(colorBar_); + delete colorBar_; + } colorBar_ = new KcColorBar(addedPlt); } } -- Gitee From efa1b9645d7276af4331b58208873262d6859fa8 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Wed, 14 Dec 2022 16:03:18 +0800 Subject: [PATCH 11/68] add: getNormalMatrix --- src/base/KtProjector3d.h | 52 ++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/base/KtProjector3d.h b/src/base/KtProjector3d.h index e362a21..3bcea6d 100644 --- a/src/base/KtProjector3d.h +++ b/src/base/KtProjector3d.h @@ -50,23 +50,15 @@ public: const mat4& projMatrix() const { return projMat_; } mat4& projMatrix() { return projMat_; } - const mat4& getMvMat() const { - if (modelMats_.empty()) - return viewMat_; + // get the model-view matrix + const mat4& getMvMat() const; - if (!mvMat_) - mvMat_ = viewMat_ * modelMats_.back(); - return mvMat_.value(); - } + // get the model-view-projection matrix + const mat4& getMvpMat() const; - const mat4& getMvpMat() const { - if (modelMats_.empty()) - return vpMat_; - - if (!mvpMat_) - mvpMat_ = vpMat_ * modelMats_.back(); - return mvpMat_.value(); - } + // ط任 + // model-viewתã=(mv(-1))T + mat4 getNormalMatrix() const; const rect& viewport() const { return vp_; } void setViewport(const rect& vp); @@ -246,6 +238,36 @@ private: }; +template const typename KtProjector::mat4& +KtProjector::getMvMat() const +{ + if (modelMats_.empty()) + return viewMat_; + + if (!mvMat_) + mvMat_ = viewMat_ * modelMats_.back(); + return mvMat_.value(); +} + + +template const typename KtProjector::mat4& +KtProjector::getMvpMat() const { + if (modelMats_.empty()) + return vpMat_; + + if (!mvpMat_) + mvpMat_ = vpMat_ * modelMats_.back(); + return mvpMat_.value(); +} + + +template typename KtProjector::mat4 +KtProjector::getNormalMatrix() const +{ + return getMvMat().getInverse().getTranspose(); +} + + template void KtProjector::setViewport(const rect& vp) { -- Gitee From f233170152800b2b484b2723029df0c017b08456 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Thu, 15 Dec 2022 10:38:06 +0800 Subject: [PATCH 12/68] =?UTF-8?q?add:=20=E4=BD=BF=E7=94=A8opengl=E5=9B=BA?= =?UTF-8?q?=E5=AE=9A=E7=AE=A1=E7=BA=BF=E7=BB=98=E5=88=B6=E5=8D=95=E4=B8=AA?= =?UTF-8?q?point?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 133 +++++++++++++++++++++++++++++-------- src/imapp/KcImOglPaint.h | 6 ++ src/plot/KpContext.h | 3 +- 3 files changed, 114 insertions(+), 28 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index bce7109..ed85484 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -11,16 +11,33 @@ namespace kPrivate { - void oglDrawCallback(const ImDrawList* parent_list, const ImDrawCmd* cmd) + void oglDrawVbos(const ImDrawList* parent_list, const ImDrawCmd* cmd) { auto objs = (std::vector>*)cmd->UserCallbackData; for (auto& i : *objs) i->draw(); } + + void oglDrawFns(const ImDrawList* parent_list, const ImDrawCmd* cmd) + { + auto fns = (std::vector>*)cmd->UserCallbackData; + for (auto& i : *fns) + i(); + } + + // colorwidthúã˴Ҫstyle + void oglDrawLine(int style, const KcImOglPaint::point3& from, const KcImOglPaint::point3& to) + { + glBegin(GL_LINES); + glVertex3f(from.x(), from.y(), from.z()); + glVertex3f(to.x(), to.y(), to.z()); + glEnd(); + } } void KcImOglPaint::beginPaint() { + fns_.clear(); objs_.clear(); super_::beginPaint(); } @@ -28,9 +45,15 @@ void KcImOglPaint::beginPaint() void KcImOglPaint::endPaint() { - if (!objs_.empty()) { + if (!fns_.empty() || !objs_.empty()) { auto dl = ImGui::GetWindowDrawList(); - dl->AddCallback(kPrivate::oglDrawCallback, &objs_); + + if (!fns_.empty()) + dl->AddCallback(kPrivate::oglDrawFns, &fns_); + + if (!objs_.empty()) + dl->AddCallback(kPrivate::oglDrawVbos, &objs_); + dl->AddCallback(ImDrawCallback_ResetRenderState, nullptr); // imguiָȾ״̬ } @@ -51,32 +74,51 @@ void KcImOglPaint::pushRenderObject_(KcRenderObject* obj) } +void KcImOglPaint::setGlViewport_(const rect_t& rc) +{ + auto draw_data = ImGui::GetDrawData(); + int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + auto vp(rc); + vp.lower().y() = fb_height - (vp.upper().y() + vp.height()); + vp.setExtent(1, viewport().height()); + glViewport(vp.lower().x(), vp.lower().y(), vp.width(), vp.height()); + + // TODO: glViewportArrayv(); +} + + void KcImOglPaint::drawPoint(const point3& pt) { - super_::drawPoint(pt); - -#if 0 // TODO: - auto progId = KcGlslProgram::currentProgram(); - - KcGlslProgram::useProgram(0); // shaderʹù̶߻ - - glMatrixMode(GL_PROJECTION); - glLoadMatrixd(camera_.projMatrix().data()); - glMatrixMode(GL_MODELVIEW); - glLoadMatrixd(camera_.viewMatrix().data()); - - glPointSize(pointSize_); - glEnable(GL_POINT_SMOOTH); - glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); - //glEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBegin(GL_POINTS); - glColor4f(clr_.r(), clr_.g(), clr_.b(), clr_.a()); - glVertex3f(pt.x(), pt.y(), pt.z()); - glEnd(); - - KcGlslProgram::useProgram(progId); -#endif + auto clr = clr_; + auto ptSize = pointSize_; + auto projMat = camera_.projMatrix(); + auto viewModelMat = camera_.getMvMat(); + auto vp = viewport(); + auto drawFn = [clr, ptSize, pt, projMat, viewModelMat, vp, this]() { + auto progId = KcGlslProgram::currentProgram(); + + KcGlslProgram::useProgram(0); // shaderʹù̶߻ + + glMatrixMode(GL_PROJECTION); + glLoadMatrixd(projMat.data()); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixd(viewModelMat.data()); + setGlViewport_(vp); + + glColor4f(clr.r(), clr.g(), clr.b(), clr.a()); + glPointSize(ptSize); + glEnable(GL_POINT_SMOOTH); + glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); + //glEnable(GL_BLEND); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBegin(GL_POINTS); + glVertex3f(pt.x(), pt.y(), pt.z()); + glEnd(); + + KcGlslProgram::useProgram(progId); + }; + + fns_.push_back(drawFn); } @@ -101,6 +143,43 @@ void KcImOglPaint::drawPoints(point_getter fn, unsigned count) } +void KcImOglPaint::drawLine(const point3& from, const point3& to) +{ + auto clr = clr_; + auto lnWidth = lineWidth_; + auto style = lineStyle_; + auto projMat = camera_.projMatrix(); + auto viewModelMat = camera_.getMvMat(); + auto vp = viewport(); + auto drawFn = [clr, lnWidth, from, to, style, projMat, viewModelMat, vp, this]() { + auto progId = KcGlslProgram::currentProgram(); + + KcGlslProgram::useProgram(0); // shaderʹù̶߻ + + glMatrixMode(GL_PROJECTION); + glLoadMatrixd(projMat.data()); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixd(viewModelMat.data()); + setGlViewport_(vp); + + glLineWidth(lnWidth); + glColor4f(clr.r(), clr.g(), clr.b(), clr.a()); + //glEnable(GL_LINE_SMOOTH); + //glHint(GL_LINE_SMOOTH, GL_NICEST); + //glEnable(GL_BLEND); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBegin(GL_LINES); + glVertex3f(from.x(), from.y(), from.z()); + glVertex3f(to.x(), to.y(), to.z()); + glEnd(); + + KcGlslProgram::useProgram(progId); + }; + + fns_.push_back(drawFn); +} + + void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) { auto obj = new KcLineObject(KcRenderObject::k_line_strip); diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index d8e5ede..7031dbe 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -2,6 +2,7 @@ #include "KcImPaint.h" #include #include +#include #include "opengl/KcRenderObject.h" @@ -22,6 +23,8 @@ public: void drawPoints(point_getter fn, unsigned count) override; + void drawLine(const point3& from, const point3& to) override; + void drawLineStrip(point_getter fn, unsigned count) override; @@ -29,6 +32,9 @@ private: void pushRenderObject_(KcRenderObject* obj); + void setGlViewport_(const rect_t& rc); + private: std::vector> objs_; + std::vector> fns_; }; diff --git a/src/plot/KpContext.h b/src/plot/KpContext.h index 2d3eb69..9080c0d 100644 --- a/src/plot/KpContext.h +++ b/src/plot/KpContext.h @@ -17,7 +17,8 @@ public: k_dash, k_dot, k_dash_dot, - k_dash_dot_dot + k_dash_dot_dot, + k_dash_dot_dash }; int style{ k_solid }; -- Gitee From 5a1c7e803ac8df5c180ced03ca717df52913ca66 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Thu, 15 Dec 2022 16:02:26 +0800 Subject: [PATCH 13/68] =?UTF-8?q?add:=20=E4=BD=BF=E7=94=A8opengl=E5=9B=BA?= =?UTF-8?q?=E5=AE=9A=E7=AE=A1=E7=BA=BF=E7=BB=98=E5=88=B6=E5=8D=95=E4=B8=AA?= =?UTF-8?q?=E7=BA=BF=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 43 ++++++++++++++++++++--------------- src/imapp/KcImOglPaint.h | 2 ++ src/opengl/KcRenderObject.cpp | 2 +- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index ed85484..c78cf3b 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -26,7 +26,7 @@ namespace kPrivate } // colorwidthúã˴Ҫstyle - void oglDrawLine(int style, const KcImOglPaint::point3& from, const KcImOglPaint::point3& to) + void oglLine(int style, const KcImOglPaint::point3& from, const KcImOglPaint::point3& to) { glBegin(GL_LINES); glVertex3f(from.x(), from.y(), from.z()); @@ -66,7 +66,7 @@ void KcImOglPaint::pushRenderObject_(KcRenderObject* obj) obj->setProjMatrix(camera_.getMvpMat()); auto vp = viewport(); // openglviewportԭ½ǣ˴Ҫתyֵ - vp.lower().y() = ImGui::GetWindowViewport()->Size.y - (vp.upper().y() + vp.height()); + vp.lower().y() = ImGui::GetWindowViewport()->Size.y - (vp.lower().y() + vp.height()); vp.setExtent(1, viewport().height()); obj->setViewport(vp); @@ -79,7 +79,7 @@ void KcImOglPaint::setGlViewport_(const rect_t& rc) auto draw_data = ImGui::GetDrawData(); int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); auto vp(rc); - vp.lower().y() = fb_height - (vp.upper().y() + vp.height()); + vp.lower().y() = fb_height - (vp.lower().y() + vp.height()); vp.setExtent(1, viewport().height()); glViewport(vp.lower().x(), vp.lower().y(), vp.width(), vp.height()); @@ -87,22 +87,30 @@ void KcImOglPaint::setGlViewport_(const rect_t& rc) } +KcImOglPaint::point3 KcImOglPaint::toNdc_(const point3& pt) const +{ + auto p = camera_.localToNdc(pt); + + // opengl̶ĬNDCϵpĽϵҪzֵȡ + return { p.x(), p.y(), -p.z() }; +} + void KcImOglPaint::drawPoint(const point3& pt) { auto clr = clr_; auto ptSize = pointSize_; - auto projMat = camera_.projMatrix(); - auto viewModelMat = camera_.getMvMat(); + auto p = toNdc_(pt); + auto vp = viewport(); - auto drawFn = [clr, ptSize, pt, projMat, viewModelMat, vp, this]() { + auto drawFn = [clr, ptSize, p, vp, this]() { auto progId = KcGlslProgram::currentProgram(); KcGlslProgram::useProgram(0); // shaderʹù̶߻ glMatrixMode(GL_PROJECTION); - glLoadMatrixd(projMat.data()); + glLoadIdentity(); glMatrixMode(GL_MODELVIEW); - glLoadMatrixd(viewModelMat.data()); + glLoadIdentity(); setGlViewport_(vp); glColor4f(clr.r(), clr.g(), clr.b(), clr.a()); @@ -112,7 +120,7 @@ void KcImOglPaint::drawPoint(const point3& pt) //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin(GL_POINTS); - glVertex3f(pt.x(), pt.y(), pt.z()); + glVertex3f(p.x(), p.y(), p.z()); glEnd(); KcGlslProgram::useProgram(progId); @@ -148,18 +156,20 @@ void KcImOglPaint::drawLine(const point3& from, const point3& to) auto clr = clr_; auto lnWidth = lineWidth_; auto style = lineStyle_; - auto projMat = camera_.projMatrix(); - auto viewModelMat = camera_.getMvMat(); auto vp = viewport(); - auto drawFn = [clr, lnWidth, from, to, style, projMat, viewModelMat, vp, this]() { + auto pt0 = toNdc_(from); + auto pt1 = toNdc_(to); + + auto drawFn = [clr, lnWidth, pt0, pt1, style, vp, this]() { auto progId = KcGlslProgram::currentProgram(); KcGlslProgram::useProgram(0); // shaderʹù̶߻ + // TODO: ˴Ĺƶһμ glMatrixMode(GL_PROJECTION); - glLoadMatrixd(projMat.data()); + glLoadIdentity(); glMatrixMode(GL_MODELVIEW); - glLoadMatrixd(viewModelMat.data()); + glLoadIdentity(); setGlViewport_(vp); glLineWidth(lnWidth); @@ -168,10 +178,7 @@ void KcImOglPaint::drawLine(const point3& from, const point3& to) //glHint(GL_LINE_SMOOTH, GL_NICEST); //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBegin(GL_LINES); - glVertex3f(from.x(), from.y(), from.z()); - glVertex3f(to.x(), to.y(), to.z()); - glEnd(); + kPrivate::oglLine(style, pt0, pt1); KcGlslProgram::useProgram(progId); }; diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index 7031dbe..35c3a8f 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -34,6 +34,8 @@ private: void setGlViewport_(const rect_t& rc); + point3 toNdc_(const point3& pt) const; + private: std::vector> objs_; std::vector> fns_; diff --git a/src/opengl/KcRenderObject.cpp b/src/opengl/KcRenderObject.cpp index 77095ad..df09bbc 100644 --- a/src/opengl/KcRenderObject.cpp +++ b/src/opengl/KcRenderObject.cpp @@ -26,7 +26,7 @@ void KcRenderObject::draw() const vtxDecl_->declare(); // vboݹ prog_->useProgram(); // shader glUniformMatrix4fv(0, 1, GL_TRUE, projMat_.data()); - glViewport(vp_.lower().x(), vp_.upper().y(), vp_.width(), vp_.height()); + glViewport(vp_.lower().x(), vp_.lower().y(), vp_.width(), vp_.height()); glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vtxDecl_->calcVertexSize()); } -- Gitee From 38a3343d3bc13e77bd369f4c4eb127ca0b49d0be Mon Sep 17 00:00:00 2001 From: koala999 Date: Thu, 15 Dec 2022 21:57:03 +0800 Subject: [PATCH 14/68] =?UTF-8?q?refactor:=20=E6=AF=8F=E4=B8=AAplot?= =?UTF-8?q?=E5=9D=87=E5=9C=A8=E7=BB=9F=E4=B8=80=E7=9A=84viewport=E4=B8=8B?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BB=98=E5=88=B6=EF=BC=8C=E5=87=8F=E5=B0=91?= =?UTF-8?q?=E8=A7=86=E5=9B=BE=E5=88=87=E6=8D=A2=E5=BC=80=E9=94=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 4 ++-- src/opengl/KcRenderObject.cpp | 2 +- src/plot/KcCoord2d.cpp | 4 ++-- src/plot/KvPlot.cpp | 26 ++++++++++++++++++-------- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index c78cf3b..6c155b0 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -91,8 +91,8 @@ KcImOglPaint::point3 KcImOglPaint::toNdc_(const point3& pt) const { auto p = camera_.localToNdc(pt); - // opengl̶ĬNDCϵpĽϵҪzֵȡ - return { p.x(), p.y(), -p.z() }; + // opengl̶ĬNDCϵpĽϵҪzֵȡ??? + return { p.x(), p.y(), p.z() }; } void KcImOglPaint::drawPoint(const point3& pt) diff --git a/src/opengl/KcRenderObject.cpp b/src/opengl/KcRenderObject.cpp index df09bbc..8863bb5 100644 --- a/src/opengl/KcRenderObject.cpp +++ b/src/opengl/KcRenderObject.cpp @@ -26,7 +26,7 @@ void KcRenderObject::draw() const vtxDecl_->declare(); // vboݹ prog_->useProgram(); // shader glUniformMatrix4fv(0, 1, GL_TRUE, projMat_.data()); - glViewport(vp_.lower().x(), vp_.lower().y(), vp_.width(), vp_.height()); + //glViewport(vp_.lower().x(), vp_.lower().y(), vp_.width(), vp_.height()); glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vtxDecl_->calcVertexSize()); } diff --git a/src/plot/KcCoord2d.cpp b/src/plot/KcCoord2d.cpp index 4beeb47..2cc299f 100644 --- a/src/plot/KcCoord2d.cpp +++ b/src/plot/KcCoord2d.cpp @@ -81,9 +81,9 @@ void KcCoord2d::draw(KvPaint* paint) const { if (visible()) { auto oldVp = paint->viewport(); - paint->setViewport(plane_->innerRect()); + //paint->setViewport(plane_->innerRect()); KvCoord::draw(paint); - paint->setViewport(oldVp); // restore the old viewport + //paint->setViewport(oldVp); // restore the old viewport } } diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index b1646eb..1118bfe 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -97,8 +97,6 @@ void KvPlot::update() if (autoFit_ && !plottables_.empty()) fitData(); - //paint_->pushLocal(coord().localMatrix()); // ķתͽautoProject_Ҫõ - auto axisSwapped = coord_->axisSwapped(); if (axisSwapped) paint_->pushLocal(coord_->axisSwapMatrix()); @@ -109,11 +107,23 @@ void KvPlot::update() auto rcCanvas = paint_->viewport(); updateLayout_(rcCanvas); + auto rcPlot = coord().getPlotRect(); + + KvPaint::point2 shift = { rcPlot.lower().x() - rcCanvas.lower().x(), + rcPlot.upper().y() - rcCanvas.upper().y() }; + auto shiftMat = KvPaint::mat4::buildTanslation(paint_->unprojectv(shift)); + + KvPaint::point3 scale = { rcPlot.width() / rcCanvas.width(), + rcPlot.height() / rcCanvas.height(), 1 }; + if (coord_->axisSwapped() == KvCoord::k_axis_swap_xy) + std::swap(scale.x(), scale.y()); + auto scaleMat = KvPaint::mat4::buildScale(scale); + + paint_->pushLocal(shiftMat * scaleMat); coord().draw(paint_.get()); - auto rcPlot = coord().getPlotRect(); - paint_->setViewport(rcPlot); // plottableҪ趨plotͼԱ㰴ִлƲ + //paint_->setViewport(rcPlot); // plottableҪ趨plotͼԱ㰴ִлƲ auto axisInversed = coord_->axisInversed(); if (axisInversed) @@ -127,7 +137,7 @@ void KvPlot::update() if (axisSwapped) paint_->popLocal(); - //paint_->popLocal(); // ƻĻ꣬ٷתͽ꣬任 + paint_->popLocal(); if (realShowLegend_()) legend_->draw(paint_.get()); @@ -135,7 +145,7 @@ void KvPlot::update() if (realShowColorBar_()) colorBar_->draw(paint_.get()); - paint_->setViewport(rcCanvas); // ָԭӿ + //paint_->setViewport(rcCanvas); // ָԭӿ paint_->endPaint(); } @@ -225,7 +235,7 @@ void KvPlot::syncLegendAndColorBar_(KvPlottable* removedPlt, KvPlottable* addedP void KvPlot::drawPlottables_() { - paint_->pushClipRect(paint_->viewport()); // clipRectֹplottablesΧ + //paint_->pushClipRect(paint_->viewport()); // clipRectֹplottablesΧ //paint_->pushLocal(coord().localMatrix()); for (int idx = 0; idx < plottableCount(); idx++) @@ -233,5 +243,5 @@ void KvPlot::drawPlottables_() plottableAt(idx)->draw(paint_.get()); //paint_->popLocal(); - paint_->popClipRect(); + //paint_->popClipRect(); } -- Gitee From 3cba7b5b939aef178d9ffb35826e58415664bcdb Mon Sep 17 00:00:00 2001 From: koala999 Date: Fri, 16 Dec 2022 10:34:17 +0800 Subject: [PATCH 15/68] =?UTF-8?q?refactor:=20=E8=B0=83=E6=95=B4margins?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=88=B0layout=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImPlot2d.cpp | 4 +--- src/plot/KcThemedPlotImpl_.cpp | 15 ++++----------- src/plot/KvPlot2d.h | 6 ------ 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/imapp/KcImPlot2d.cpp b/src/imapp/KcImPlot2d.cpp index 5ac1456..ff79922 100644 --- a/src/imapp/KcImPlot2d.cpp +++ b/src/imapp/KcImPlot2d.cpp @@ -24,9 +24,7 @@ void KcImPlot2d::updateImpl_() // ͼ auto pos = ImGui::GetWindowPos(); auto sz = ImGui::GetWindowSize(); - KvPaint::rect_t vp({ pos.x, pos.y }, { pos.x + sz.x, pos.y + sz.y }); - vp.shrink({ margins_.left(), margins_.bottom() }, { margins_.right(), margins_.top() }); - paint().setViewport(vp); + paint().setViewport({ { pos.x, pos.y }, { pos.x + sz.x, pos.y + sz.y } }); // ͼ KvPlot2d::update(); diff --git a/src/plot/KcThemedPlotImpl_.cpp b/src/plot/KcThemedPlotImpl_.cpp index e311ca2..3701ec3 100644 --- a/src/plot/KcThemedPlotImpl_.cpp +++ b/src/plot/KcThemedPlotImpl_.cpp @@ -63,11 +63,8 @@ void KcThemedPlotImpl_::applyBorder(int level, const KpPen&) KtMargins KcThemedPlotImpl_::margins(int level) const { - if (level == k_plot) { - auto plot2d = dynamic_cast(&plot_); - if (plot2d) - return plot2d->margins(); - } + if (level == k_plot) + return plot_.margins(); return KtMargins(); } @@ -75,12 +72,8 @@ KtMargins KcThemedPlotImpl_::margins(int level) const void KcThemedPlotImpl_::applyMargins(int level, const KtMargins& margins) { - if (level == k_plot) { - auto plot2d = dynamic_cast(&plot_); - if (plot2d) - plot2d->margins() = margins; - } - + if (level == k_plot) + plot_.setMargins(margins); } diff --git a/src/plot/KvPlot2d.h b/src/plot/KvPlot2d.h index d79242d..5ed8d0f 100644 --- a/src/plot/KvPlot2d.h +++ b/src/plot/KvPlot2d.h @@ -19,15 +19,9 @@ public: using KvPlot::KvPlot; - const KtMargins& margins() const { return margins_; } - KtMargins& margins() { return margins_; } - virtual mat4 projMatrix() const = 0; virtual void setProjMatrix(const mat4&) = 0; private: void autoProject_() override; - -protected: - KtMargins margins_{ 15, 15, 15, 15 }; }; -- Gitee From 5ac4b24115833db6a9f3ae12745eaee255868e5f Mon Sep 17 00:00:00 2001 From: koala999 Date: Fri, 16 Dec 2022 10:35:26 +0800 Subject: [PATCH 16/68] =?UTF-8?q?fix:=20=E7=BB=9F=E4=B8=80=E8=A7=86?= =?UTF-8?q?=E5=8F=A3=E5=90=8E=E7=BB=98=E5=9B=BE=E5=8C=BA=E5=9F=9F=E7=9A=84?= =?UTF-8?q?=E7=BC=A9=E6=94=BE=E5=92=8C=E5=81=8F=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KvPlot.cpp | 78 +++++++++++++++++++++++++++++++++------------ src/plot/KvPlot.h | 7 ++++ 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index 1118bfe..257c797 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -105,25 +105,11 @@ void KvPlot::update() paint_->beginPaint(); - auto rcCanvas = paint_->viewport(); - updateLayout_(rcCanvas); - auto rcPlot = coord().getPlotRect(); + updateLayout_(paint_->viewport()); - KvPaint::point2 shift = { rcPlot.lower().x() - rcCanvas.lower().x(), - rcPlot.upper().y() - rcCanvas.upper().y() }; - auto shiftMat = KvPaint::mat4::buildTanslation(paint_->unprojectv(shift)); - - KvPaint::point3 scale = { rcPlot.width() / rcCanvas.width(), - rcPlot.height() / rcCanvas.height(), 1 }; - if (coord_->axisSwapped() == KvCoord::k_axis_swap_xy) - std::swap(scale.x(), scale.y()); - auto scaleMat = KvPaint::mat4::buildScale(scale); + fixPlotView_(); // ˴1localջpop - paint_->pushLocal(shiftMat * scaleMat); - - coord().draw(paint_.get()); - - //paint_->setViewport(rcPlot); // plottableҪ趨plotͼԱ㰴ִлƲ + coord_->draw(paint_.get()); auto axisInversed = coord_->axisInversed(); if (axisInversed) @@ -145,12 +131,44 @@ void KvPlot::update() if (realShowColorBar_()) colorBar_->draw(paint_.get()); - //paint_->setViewport(rcCanvas); // ָԭӿ + // debug drawing + paint_->pushCoord(KvPaint::k_coord_screen); + paint_->setColor({ 1,0,0,1 }); + paint_->drawRect(coord_->getPlotRect()); + if (realShowLegend_()) + paint_->drawRect(legend_->outterRect()); + paint_->popCoord(); paint_->endPaint(); } +void KvPlot::fixPlotView_() +{ + auto rcCanvas = paint_->viewport(); + auto rcPlot = coord_->getPlotRect(); + + // ͼڻͼű + KvPaint::point3 scale = { rcPlot.width() / rcCanvas.width(), + rcPlot.height() / rcCanvas.height(), 1 }; + if (coord_->axisSwapped() == KvCoord::k_axis_swap_xy) + std::swap(scale.x(), scale.y()); + auto scaleMat = KvPaint::mat4::buildScale(scale); + + // ͼڻͼƫƣĻµֵ + KvPaint::point2 shift = { rcPlot.lower().x() - rcCanvas.lower().x(), + rcPlot.upper().y() - rcCanvas.upper().y() }; + auto shift3d = paint_->unprojectv(shift); // ת + + // ⣬ű任ԭеģϵlowerƫƣҪһ + shift3d += (coord_->lower() - coord_->lower() * scale); + + auto shiftMat = KvPaint::mat4::buildTanslation(shift3d); + + paint_->pushLocal(shiftMat * scaleMat); +} + + void KvPlot::fitData() { typename KvRenderable::aabb_t box; @@ -236,12 +254,32 @@ void KvPlot::syncLegendAndColorBar_(KvPlottable* removedPlt, KvPlottable* addedP void KvPlot::drawPlottables_() { //paint_->pushClipRect(paint_->viewport()); // clipRectֹplottablesΧ - //paint_->pushLocal(coord().localMatrix()); for (int idx = 0; idx < plottableCount(); idx++) if (plottableAt(idx)->visible()) plottableAt(idx)->draw(paint_.get()); - //paint_->popLocal(); //paint_->popClipRect(); } + + +void KvPlot::setMargins(const margins_t& m) +{ + rect_t rc; + rc.lower() = { m.left(), m.top() }; // TODO: + rc.upper() = { m.right(), m.bottom() }; + + layout_->setMargins(rc); +} + + +KvPlot::margins_t KvPlot::margins() const +{ + auto rc = layout_->margins(); + margins_t m; + m.left() = rc.lower().x(); + m.right() = rc.upper().x(); + m.top() = rc.lower().y(); + m.bottom() = rc.upper().y(); + return m; +} \ No newline at end of file diff --git a/src/plot/KvPlot.h b/src/plot/KvPlot.h index 5a1e775..26e5004 100644 --- a/src/plot/KvPlot.h +++ b/src/plot/KvPlot.h @@ -4,6 +4,7 @@ #include "KvPlottable.h" #include "KpContext.h" #include "KtAABB.h" +#include "KtMargins.h" class KvPaint; // ִоplot @@ -17,6 +18,7 @@ class KcLayoutGrid; class KvPlot { using rect_t = KtAABB; + using margins_t = KtMargins; public: KvPlot(std::shared_ptr paint, std::shared_ptr coord); @@ -66,6 +68,8 @@ public: void removeAllPlottables(); + void setMargins(const margins_t& m); + margins_t margins() const; private: virtual void autoProject_() = 0; @@ -79,6 +83,9 @@ private: void drawPlottables_(); + // ͼӿڵƫƺţplot2dҪ + void fixPlotView_(); + private: std::shared_ptr paint_; // û std::shared_ptr coord_; // û -- Gitee From 710654f503f6d570d1e9a652c5b884b7633abf41 Mon Sep 17 00:00:00 2001 From: koala999 Date: Fri, 16 Dec 2022 17:45:37 +0800 Subject: [PATCH 17/68] =?UTF-8?q?fix:=20arrange=20layout=E7=9A=84=E7=95=99?= =?UTF-8?q?=E7=99=BD=E4=BA=8C=E6=AC=A1=E8=AE=A1=E7=AE=97=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layout/KcLayout1d.cpp | 4 ++-- src/layout/KcLayoutGrid.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/layout/KcLayout1d.cpp b/src/layout/KcLayout1d.cpp index 73415ef..6c69a9f 100644 --- a/src/layout/KcLayout1d.cpp +++ b/src/layout/KcLayout1d.cpp @@ -75,7 +75,7 @@ void KcLayout1d::arrangeStack_(const rect_t& rc, int dim) __super::arrange_(rc, dim); auto unusedSpace = iRect_.upper()[dim] - iRect_.lower()[dim]; - auto fixedSpace = expectRoom()[dim]; + auto fixedSpace = contentSize()[dim]; // ˴expectRoomҪһΣΪrcѿ۳ auto extraSpace = std::max(0., unusedSpace - fixedSpace); // TODO: 1. ʱʹþȷ; 2. δextraShares == 0ʱextraSpace @@ -88,7 +88,7 @@ void KcLayout1d::arrangeStack_(const rect_t& rc, int dim) continue; // ֧fixd-itemsqueezed-itemĻ - auto itemSpace = i->expectRoom()[dim] + i->extraShares()[dim] * spacePerShare; + auto itemSpace = i->contentSize()[dim] + i->extraShares()[dim] * spacePerShare; rcItem.upper()[dim] = rcItem.lower()[dim] + itemSpace; i->arrange(rcItem); diff --git a/src/layout/KcLayoutGrid.cpp b/src/layout/KcLayoutGrid.cpp index 64f5408..0b0067a 100644 --- a/src/layout/KcLayoutGrid.cpp +++ b/src/layout/KcLayoutGrid.cpp @@ -141,7 +141,7 @@ void KcLayoutGrid::arrangeColStack_(const rect_t& rc) super_::arrange_(rc, 0); // ʼiRect_ auto unusedSpace = iRect_.width(); - auto fixedSpace = expectRoom()[0]; + auto fixedSpace = contentSize()[0]; auto extraSpace = std::max(0., unusedSpace - fixedSpace); auto spacePerShare = extraShares()[0] ? extraSpace / extraShares()[0] : 0; -- Gitee From 4dd5c0b92a784b7a39021c7d852c4d0af504dff7 Mon Sep 17 00:00:00 2001 From: koala999 Date: Fri, 16 Dec 2022 23:00:28 +0800 Subject: [PATCH 18/68] clean code --- src/layout/KcLayout1d.cpp | 8 ++++---- src/layout/KcLayoutGrid.cpp | 11 ++++++----- src/layout/KvLayoutElement.cpp | 6 +++--- src/opengl/KcRenderObject.cpp | 1 - src/opengl/KcRenderObject.h | 6 +----- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/layout/KcLayout1d.cpp b/src/layout/KcLayout1d.cpp index 6c69a9f..44947ef 100644 --- a/src/layout/KcLayout1d.cpp +++ b/src/layout/KcLayout1d.cpp @@ -64,7 +64,7 @@ void KcLayout1d::arrangeOverlay_(const rect_t& rc, int dim) { __super::arrange_(rc, dim); auto rcLay = rc; - rcLay.upper()[!dim] = rcLay.lower()[!dim]; // һά + rcLay.setExtent(!dim, 0); // һά for (auto& i : elements()) if (i) i->arrange(rcLay); } @@ -82,15 +82,15 @@ void KcLayout1d::arrangeStack_(const rect_t& rc, int dim) auto spacePerShare = extraShares()[dim] ? extraSpace / extraShares()[dim] : 0; rect_t rcItem = iRect_; - rcItem.upper()[!dim] = rcItem.lower()[!dim]; // һά + rcItem.setExtent(!dim, 0); // һά for (auto& i : elements()) { if (i == nullptr) continue; // ֧fixd-itemsqueezed-itemĻ - auto itemSpace = i->contentSize()[dim] + i->extraShares()[dim] * spacePerShare; + auto itemSpace = i->expectRoom()[dim] + i->extraShares()[dim] * spacePerShare; - rcItem.upper()[dim] = rcItem.lower()[dim] + itemSpace; + rcItem.setExtent(dim, itemSpace); i->arrange(rcItem); rcItem.lower() = rcItem.upper(); diff --git a/src/layout/KcLayoutGrid.cpp b/src/layout/KcLayoutGrid.cpp index 0b0067a..d08cc1b 100644 --- a/src/layout/KcLayoutGrid.cpp +++ b/src/layout/KcLayoutGrid.cpp @@ -147,15 +147,16 @@ void KcLayoutGrid::arrangeColStack_(const rect_t& rc) auto spacePerShare = extraShares()[0] ? extraSpace / extraShares()[0] : 0; rect_t rcItem = iRect_; - rcItem.upper()[1] = rcItem.lower()[1]; // һά + rcItem.setExtent(1, 0); // һά for (unsigned c = 0; c < cols(); c++) { // ֧fixd-itemsqueezed-itemĻ - auto itemSpace = szCols_[c].first + szCols_[c].second * spacePerShare; - - rcItem.upper()[0] = rcItem.lower()[0] + itemSpace; + rcItem.setExtent(0, szCols_[c].first + szCols_[c].second * spacePerShare); for (unsigned r = 0; r < rows(); r++) { - auto ele = rowAt(r)->getAt(c); + // TODO: ˴ûеrowAt(r)arrangerowAt(r)xάȳߴΪ0 + // rowAt(r)->arrange_(rcItem, 0); + + auto ele = rowAt(r)->getAt(c); if (ele) ele->arrange(rcItem); } diff --git a/src/layout/KvLayoutElement.cpp b/src/layout/KvLayoutElement.cpp index d7d013b..fc535fd 100644 --- a/src/layout/KvLayoutElement.cpp +++ b/src/layout/KvLayoutElement.cpp @@ -12,15 +12,15 @@ void KvLayoutElement::arrange_(const rect_t& rc, int dim) iRect_.upper()[dim] = rc.upper()[dim] - margins_.upper()[dim]; if (iRect_.upper().at(dim) < iRect_.lower().at(dim)) - iRect_.upper().at(dim) = iRect_.lower().at(dim); - else if (contentSize_[dim] > 0 && iRect_.upper().at(dim) - iRect_.lower().at(dim) > contentSize_[dim]) { + iRect_.setExtent(dim, 0); + else if (contentSize_[dim] > 0 && iRect_.extent(dim) > contentSize_[dim]) { // aligniRectе const int left[] = { align_ & KeAlignment::k_left, align_ & KeAlignment::k_top }; const int mid[] = { align_ & KeAlignment::k_hcenter, align_ & KeAlignment::k_vcenter }; const int right[] = { align_ & KeAlignment::k_right, align_ & KeAlignment::k_bottom }; if (left[dim]) { - iRect_.upper()[dim] = iRect_.lower()[dim] + contentSize_[dim]; + iRect_.setExtent(dim, contentSize_[dim]); } else if (right[dim]) { iRect_.lower()[dim] = iRect_.upper()[dim] - contentSize_[dim]; diff --git a/src/opengl/KcRenderObject.cpp b/src/opengl/KcRenderObject.cpp index 8863bb5..cf4e2f5 100644 --- a/src/opengl/KcRenderObject.cpp +++ b/src/opengl/KcRenderObject.cpp @@ -26,7 +26,6 @@ void KcRenderObject::draw() const vtxDecl_->declare(); // vboݹ prog_->useProgram(); // shader glUniformMatrix4fv(0, 1, GL_TRUE, projMat_.data()); - //glViewport(vp_.lower().x(), vp_.lower().y(), vp_.width(), vp_.height()); glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vtxDecl_->calcVertexSize()); } diff --git a/src/opengl/KcRenderObject.h b/src/opengl/KcRenderObject.h index 981e3f8..dab7cb2 100644 --- a/src/opengl/KcRenderObject.h +++ b/src/opengl/KcRenderObject.h @@ -59,10 +59,6 @@ public: projMat_ = projMat; } - void setViewport(const rect_t& vp) { // TODO: Ƶȥͳһ - vp_ = vp; - } - virtual void draw() const; protected: @@ -71,5 +67,5 @@ protected: std::shared_ptr vbo_; std::shared_ptr vtxDecl_; float4x4<> projMat_; - rect_t vp_; // 浥ӿڣֶ֧രڻ + //rect_t vp_; // 浥ӿڣֶ֧രڻ }; -- Gitee From 25593f6f382e802e8146490d4093026681e6a524 Mon Sep 17 00:00:00 2001 From: koala999 Date: Fri, 16 Dec 2022 23:03:17 +0800 Subject: [PATCH 19/68] =?UTF-8?q?fix:=20=E6=8A=93=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E5=A4=A9=E7=9A=84=E8=A7=86=E5=8F=A3=E9=9D=9E=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=E5=81=8F=E7=A7=BBbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base/KtProjector3d.h | 32 ++++++++------- src/imapp/KcImOglPaint.cpp | 44 ++++++++++----------- src/imapp/KcImPaint.h | 2 - src/plot/KcAxis.cpp | 4 +- src/plot/KvPlot.cpp | 79 ++++++++++++++++++++++++++++---------- src/plot/KvPlot.h | 9 ++++- src/plot/KvPlot2d.cpp | 7 ++++ src/plot/KvPlot2d.h | 2 +- 8 files changed, 115 insertions(+), 64 deletions(-) diff --git a/src/base/KtProjector3d.h b/src/base/KtProjector3d.h index 3bcea6d..9dd8847 100644 --- a/src/base/KtProjector3d.h +++ b/src/base/KtProjector3d.h @@ -34,13 +34,13 @@ public: using rect = KtAABB; void pushLocal(const mat4& mat) { - modelMats_.push_back(modelMats_.empty() ? mat : - modelMats_.back() * mat); + localMatStack_.push_back(localMatStack_.empty() ? mat : + localMatStack_.back() * mat); resetModelRelatedMats_(); } void popLocal() { - modelMats_.pop_back(); + localMatStack_.pop_back(); resetModelRelatedMats_(); } @@ -70,14 +70,14 @@ public: // NOTE: viewMat, projMatviewport֮ڵת֮ǰøú void updateProjectMatrixs(); - vec4 localToWorld(const vec4& pt) const { return modelMats_.empty() ? pt : modelMats_.back() * pt; } + vec4 localToWorld(const vec4& pt) const { return localMatStack_.empty() ? pt : localMatStack_.back() * pt; } vec4 localToEye(const vec4& pt) const { return getMvMat() * pt; } vec4 localToClip(const vec4& pt) const { return getMvpMat() * pt; } vec4 localToNdc(const vec4& pt) const { return clipToNdc(localToClip(pt)); } vec4 localToViewport(const vec4& pt) const { return clipToViewport(localToClip(pt)); } vec4 localToScreen(const vec4& pt) const { return clipToScreen(localToClip(pt)); } - vec4 worldToLocal(const vec4& pt) const { return modelMats_.empty() ? pt : getMMatR_() * pt; } + vec4 worldToLocal(const vec4& pt) const { return localMatStack_.empty() ? pt : getMMatR_() * pt; } vec4 worldToEye(const vec4& pt) const { return viewMat_ * pt; } vec4 worldToClip(const vec4& pt) const { return vpMat_ * pt; } vec4 worldToNdc(const vec4& pt) const { return clipToNdc(worldToClip(pt)); } @@ -129,12 +129,12 @@ private: const mat4& getMMatR_() const { if (!mMatR_) - mMatR_ = modelMats_.back().getInverse(); + mMatR_ = localMatStack_.back().getInverse(); return mMatR_.value(); } const mat4& getMvMatR_() const { - if (modelMats_.empty()) + if (localMatStack_.empty()) return getViewMatR_(); if (!mvMatR_) @@ -143,7 +143,7 @@ private: } const mat4& getMvpMatR_() const { - if (modelMats_.empty()) + if (localMatStack_.empty()) return getVpMatR_(); if (!mvpMatR_) @@ -188,7 +188,7 @@ private: rect vp_{ point2(0, 0), point2(1, 1) }; // ģ;ջڴֲ任ȫ - std::vector modelMats_; + std::vector localMatStack_; // view matrix mat4 viewMat_{ mat4::identity() }; @@ -241,22 +241,22 @@ private: template const typename KtProjector::mat4& KtProjector::getMvMat() const { - if (modelMats_.empty()) + if (localMatStack_.empty()) return viewMat_; if (!mvMat_) - mvMat_ = viewMat_ * modelMats_.back(); + mvMat_ = viewMat_ * localMatStack_.back(); return mvMat_.value(); } template const typename KtProjector::mat4& KtProjector::getMvpMat() const { - if (modelMats_.empty()) + if (localMatStack_.empty()) return vpMat_; if (!mvpMat_) - mvpMat_ = vpMat_ * modelMats_.back(); + mvpMat_ = vpMat_ * localMatStack_.back(); return mvpMat_.value(); } @@ -317,8 +317,14 @@ void KtProjector::resetModelRelatedMats_() mvMat_.reset(); mvpMat_.reset(); mMatR_.reset(); + viewMatR_.reset(); + projMatR_.reset(); mvMatR_.reset(); mvpMatR_.reset(); + vpMatR_.reset(); + + vsMatR_.reset(); + nsMatR_.reset(); } diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 6c155b0..774fc67 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -11,6 +11,21 @@ namespace kPrivate { + void oglSetRenderState(const ImDrawList* parent_list, const ImDrawCmd* cmd) + { + KcGlslProgram::useProgram(0); // shaderʹù̶߻ + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + KcImOglPaint* paint = (KcImOglPaint*)cmd->UserCallbackData; + auto rc = paint->viewport(); + auto y0 = ImGui::GetMainViewport()->Size.y - rc.upper().y(); + glViewport(rc.lower().x(), y0, rc.width(), rc.height()); + } + void oglDrawVbos(const ImDrawList* parent_list, const ImDrawCmd* cmd) { auto objs = (std::vector>*)cmd->UserCallbackData; @@ -48,6 +63,8 @@ void KcImOglPaint::endPaint() if (!fns_.empty() || !objs_.empty()) { auto dl = ImGui::GetWindowDrawList(); + dl->AddCallback(kPrivate::oglSetRenderState, this); + if (!fns_.empty()) dl->AddCallback(kPrivate::oglDrawFns, &fns_); @@ -66,9 +83,9 @@ void KcImOglPaint::pushRenderObject_(KcRenderObject* obj) obj->setProjMatrix(camera_.getMvpMat()); auto vp = viewport(); // openglviewportԭ½ǣ˴Ҫתyֵ - vp.lower().y() = ImGui::GetWindowViewport()->Size.y - (vp.lower().y() + vp.height()); - vp.setExtent(1, viewport().height()); - obj->setViewport(vp); + //vp.lower().y() = ImGui::GetWindowViewport()->Size.y - (vp.lower().y() + vp.height()); + //vp.setExtent(1, viewport().height()); + //obj->setViewport(vp); objs_.emplace_back(obj); } @@ -103,15 +120,6 @@ void KcImOglPaint::drawPoint(const point3& pt) auto vp = viewport(); auto drawFn = [clr, ptSize, p, vp, this]() { - auto progId = KcGlslProgram::currentProgram(); - - KcGlslProgram::useProgram(0); // shaderʹù̶߻ - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - setGlViewport_(vp); glColor4f(clr.r(), clr.g(), clr.b(), clr.a()); glPointSize(ptSize); @@ -123,7 +131,6 @@ void KcImOglPaint::drawPoint(const point3& pt) glVertex3f(p.x(), p.y(), p.z()); glEnd(); - KcGlslProgram::useProgram(progId); }; fns_.push_back(drawFn); @@ -161,16 +168,6 @@ void KcImOglPaint::drawLine(const point3& from, const point3& to) auto pt1 = toNdc_(to); auto drawFn = [clr, lnWidth, pt0, pt1, style, vp, this]() { - auto progId = KcGlslProgram::currentProgram(); - - KcGlslProgram::useProgram(0); // shaderʹù̶߻ - - // TODO: ˴Ĺƶһμ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - setGlViewport_(vp); glLineWidth(lnWidth); glColor4f(clr.r(), clr.g(), clr.b(), clr.a()); @@ -180,7 +177,6 @@ void KcImOglPaint::drawLine(const point3& from, const point3& to) //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); kPrivate::oglLine(style, pt0, pt1); - KcGlslProgram::useProgram(progId); }; fns_.push_back(drawFn); diff --git a/src/imapp/KcImPaint.h b/src/imapp/KcImPaint.h index f048aed..e7e36cd 100644 --- a/src/imapp/KcImPaint.h +++ b/src/imapp/KcImPaint.h @@ -92,7 +92,5 @@ protected: int lineStyle_{ 0 }; float_t pointSize_{ 1 }; - KtMatrix4 vp_; // 任 - std::vector coords_; // ϵջ }; diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index d64e0f0..bc6fd23 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -211,7 +211,7 @@ KtMargins KcAxis::calcMargins(KvPaint* paint) const paint->pushCoord(KvPaint::k_coord_screen); // мĻ½ - auto tickOrient = paint->projectv(tickOrient_); + auto tickOrient = paint->projectv(tickOrient_).normalize(); vec3 tickLen(0); // tickijʸ if (showTick()) @@ -254,7 +254,7 @@ KtMargins KcAxis::calcMargins(KvPaint* paint) const if (sameSide) labelAchors += tickOrient * tickCxt_.length; - labelAchors += paint->projectv(labelOrient_) * labelPadding_; + labelAchors += paint->projectv(labelOrient_).normalize() * labelPadding_; auto labelText = i < labels_.size() ? labels_[i] : labels[i]; box.merge(textBox_(paint, labelAchors, labelText)); diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index 257c797..a0d2aa2 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -107,7 +107,7 @@ void KvPlot::update() updateLayout_(paint_->viewport()); - fixPlotView_(); // ˴1localջpop + auto locals = fixPlotView_(); // ˴localsջpop coord_->draw(paint_.get()); @@ -123,7 +123,8 @@ void KvPlot::update() if (axisSwapped) paint_->popLocal(); - paint_->popLocal(); + for (int i = 0; i < locals; i++) + paint_->popLocal(); if (realShowLegend_()) legend_->draw(paint_.get()); @@ -132,40 +133,49 @@ void KvPlot::update() colorBar_->draw(paint_.get()); // debug drawing - paint_->pushCoord(KvPaint::k_coord_screen); - paint_->setColor({ 1,0,0,1 }); - paint_->drawRect(coord_->getPlotRect()); - if (realShowLegend_()) - paint_->drawRect(legend_->outterRect()); - paint_->popCoord(); + drawLayoutRect_(); paint_->endPaint(); } -void KvPlot::fixPlotView_() +int KvPlot::fixPlotView_() { auto rcCanvas = paint_->viewport(); auto rcPlot = coord_->getPlotRect(); - + if (rcPlot == rcCanvas) + return 0; + // ͼڻͼű KvPaint::point3 scale = { rcPlot.width() / rcCanvas.width(), rcPlot.height() / rcCanvas.height(), 1 }; - if (coord_->axisSwapped() == KvCoord::k_axis_swap_xy) - std::swap(scale.x(), scale.y()); + //if (coord_->axisSwapped() == KvCoord::k_axis_swap_xy) + // std::swap(scale.x(), scale.y()); + scale = paint_->localToWorldV(scale); // ȼύ룬˴ʹøͨõı任 auto scaleMat = KvPaint::mat4::buildScale(scale); + paint_->pushLocal(scaleMat); + // ϵlowerƫƵrcPlotµ + auto lower = paint_->unprojectp({ rcPlot.lower().x(), rcPlot.upper().y() }); + auto shiftMat = KvPaint::mat4::buildTanslation(lower - coord_->lower()); + + ///////////////////////////////////////////////////////////////////////// + // ƫƵȼ´ // ͼڻͼƫƣĻµֵ - KvPaint::point2 shift = { rcPlot.lower().x() - rcCanvas.lower().x(), - rcPlot.upper().y() - rcCanvas.upper().y() }; - auto shift3d = paint_->unprojectv(shift); // ת - + //KvPaint::point2 shift = { rcPlot.lower().x() - rcCanvas.lower().x(), + // rcPlot.upper().y() - rcCanvas.upper().y() }; + //auto shift3d = paint_->unprojectv(shift); // ת // ⣬ű任ԭеģϵlowerƫƣҪһ - shift3d += (coord_->lower() - coord_->lower() * scale); + //shift3d += (coord_->lower() - coord_->lower() * scale); + //auto shiftMat = KvPaint::mat4::buildTanslation(shift3d); + ////////////////////////////////////////////////////////////////////////// - auto shiftMat = KvPaint::mat4::buildTanslation(shift3d); + paint_->pushLocal(shiftMat); - paint_->pushLocal(shiftMat * scaleMat); + //assert(std::floor(paint_->projectp(coord_->lower()).x()) == rcPlot.lower().x()); + //assert(std::floor(paint_->projectp(coord_->lower()).y()) == rcPlot.upper().y()); + + return 2; } @@ -273,6 +283,12 @@ void KvPlot::setMargins(const margins_t& m) } +void KvPlot::setMargins(float l, float t, float r, float b) +{ + return setMargins({ l, t, r, b }); +} + + KvPlot::margins_t KvPlot::margins() const { auto rc = layout_->margins(); @@ -282,4 +298,27 @@ KvPlot::margins_t KvPlot::margins() const m.top() = rc.lower().y(); m.bottom() = rc.upper().y(); return m; -} \ No newline at end of file +} + + +#include +void KvPlot::drawLayoutRect_() +{ + std::queue eles; // ƲԪ + eles.push(layout_.get()); + + paint_->pushCoord(KvPaint::k_coord_screen); + paint_->setColor({ 1,0,0,1 }); + + while (!eles.empty()) { + auto e = eles.front(); eles.pop(); + paint_->drawRect(e->outterRect()); + auto c = dynamic_cast(e); + if (c) { + for (auto& i : c->elements()) + if (i) eles.push(i.get()); + } + } + + paint_->popCoord(); +} diff --git a/src/plot/KvPlot.h b/src/plot/KvPlot.h index 26e5004..37aad68 100644 --- a/src/plot/KvPlot.h +++ b/src/plot/KvPlot.h @@ -68,8 +68,9 @@ public: void removeAllPlottables(); - void setMargins(const margins_t& m); margins_t margins() const; + void setMargins(const margins_t& m); + void setMargins(float l, float t, float r, float b); private: virtual void autoProject_() = 0; @@ -84,7 +85,11 @@ private: void drawPlottables_(); // ͼӿڵƫƺţplot2dҪ - void fixPlotView_(); + // ѹlocal任 + int fixPlotView_(); + + // ƸԪص߿debugʹ + void drawLayoutRect_(); private: std::shared_ptr paint_; // û diff --git a/src/plot/KvPlot2d.cpp b/src/plot/KvPlot2d.cpp index 8a56dba..ef8853c 100644 --- a/src/plot/KvPlot2d.cpp +++ b/src/plot/KvPlot2d.cpp @@ -2,6 +2,13 @@ #include "KvCoord.h" +KvPlot2d::KvPlot2d(std::shared_ptr paint, std::shared_ptr coord) + : KvPlot(paint, coord) +{ + setMargins(15, 15, 15, 15); +} + + void KvPlot2d::autoProject_() { auto box = coord().boundingBox(); diff --git a/src/plot/KvPlot2d.h b/src/plot/KvPlot2d.h index 5ed8d0f..e2467ac 100644 --- a/src/plot/KvPlot2d.h +++ b/src/plot/KvPlot2d.h @@ -17,7 +17,7 @@ public: using point2 = point2d; using mat4 = KtMatrix4; - using KvPlot::KvPlot; + KvPlot2d(std::shared_ptr paint, std::shared_ptr coord); virtual mat4 projMatrix() const = 0; virtual void setProjMatrix(const mat4&) = 0; -- Gitee From 31456974f1039cbae8ff59deee6c44663e8788b7 Mon Sep 17 00:00:00 2001 From: koala999 Date: Sun, 18 Dec 2022 18:49:08 +0800 Subject: [PATCH 20/68] =?UTF-8?q?new:=20=E5=AE=9E=E7=8E=B03d=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E7=9A=84=E6=96=87=E6=9C=AC=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 132 +++++++++++++++++++++++++-------- src/imapp/KcImOglPaint.h | 17 +++-- src/imapp/KcImPaint.h | 2 +- src/opengl/KsShaderManager.cpp | 59 +++++++++++++++ src/opengl/KsShaderManager.h | 19 ++++- src/plot/KvPaint.h | 9 +++ 6 files changed, 201 insertions(+), 37 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 774fc67..6b134cb 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -1,5 +1,6 @@ #include "KcImOglPaint.h" #include "imgui.h" +#include "imgui_internal.h" #include "glad.h" #include "opengl/KcGlslProgram.h" #include "opengl/KcGlslShader.h" @@ -7,6 +8,7 @@ #include "opengl/KcVertexDeclaration.h" #include "opengl/KcPointObject.h" #include "opengl/KcLineObject.h" +#include "opengl/KsShaderManager.h" namespace kPrivate @@ -40,6 +42,28 @@ namespace kPrivate i(); } + void oglDrawText(const ImDrawList* parent_list, const ImDrawCmd* cmd) + { + auto vtx = (std::vector*)cmd->UserCallbackData; + + auto obj = KcRenderObject(KcRenderObject::k_quads, KsShaderManager::singleton().programColorUV()); + + auto decl = std::make_shared(); + KcVertexAttribute attrPos(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); + KcVertexAttribute attrUv(1, KcVertexAttribute::k_float2, sizeof(float) * 3, KcVertexAttribute::k_texcoord); + KcVertexAttribute attrClr(2, KcVertexAttribute::k_float4, sizeof(float) * 5, KcVertexAttribute::k_diffuse); + decl->pushAttribute(attrPos); + decl->pushAttribute(attrUv); + decl->pushAttribute(attrClr); + + auto vbo = std::make_shared(); + vbo->setData(vtx->data(), vtx->size() * sizeof(KcImOglPaint::TextVbo), KcGpuBuffer::k_stream_draw); + + obj.setVbo(vbo, decl); + obj.setProjMatrix(float4x4<>::identity()); + obj.draw(); + } + // colorwidthúã˴Ҫstyle void oglLine(int style, const KcImOglPaint::point3& from, const KcImOglPaint::point3& to) { @@ -65,9 +89,15 @@ void KcImOglPaint::endPaint() dl->AddCallback(kPrivate::oglSetRenderState, this); + // ɢ if (!fns_.empty()) dl->AddCallback(kPrivate::oglDrawFns, &fns_); + // text + if (!texts_.empty()) + dl->AddCallback(kPrivate::oglDrawText, &texts_); + + // plottables if (!objs_.empty()) dl->AddCallback(kPrivate::oglDrawVbos, &objs_); @@ -78,32 +108,6 @@ void KcImOglPaint::endPaint() } -void KcImOglPaint::pushRenderObject_(KcRenderObject* obj) -{ - obj->setProjMatrix(camera_.getMvpMat()); - - auto vp = viewport(); // openglviewportԭ½ǣ˴Ҫתyֵ - //vp.lower().y() = ImGui::GetWindowViewport()->Size.y - (vp.lower().y() + vp.height()); - //vp.setExtent(1, viewport().height()); - //obj->setViewport(vp); - - objs_.emplace_back(obj); -} - - -void KcImOglPaint::setGlViewport_(const rect_t& rc) -{ - auto draw_data = ImGui::GetDrawData(); - int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); - auto vp(rc); - vp.lower().y() = fb_height - (vp.lower().y() + vp.height()); - vp.setExtent(1, viewport().height()); - glViewport(vp.lower().x(), vp.lower().y(), vp.width(), vp.height()); - - // TODO: glViewportArrayv(); -} - - KcImOglPaint::point3 KcImOglPaint::toNdc_(const point3& pt) const { auto p = camera_.localToNdc(pt); @@ -154,7 +158,8 @@ void KcImOglPaint::drawPoints(point_getter fn, unsigned count) obj->setVbo(vbo, decl); obj->setColor(clr_); obj->setSize(pointSize_); - pushRenderObject_(obj); + obj->setProjMatrix(camera_.getMvpMat()); + objs_.emplace_back(obj); } @@ -200,5 +205,74 @@ void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) obj->setVbo(vbo, decl); obj->setColor(clr_); obj->setWidth(lineWidth_); - pushRenderObject_(obj); -} \ No newline at end of file + obj->setProjMatrix(camera_.getMvpMat()); + objs_.emplace_back(obj); +} + + +void KcImOglPaint::drawText(const point3& topLeft, const point3& hDir, const point3& vDir, const char* text) +{ + auto font = ImGui::GetFont(); + auto eos = text + strlen(text); + + auto hScale = 1.0 / unprojectv(hDir).length(); + auto vScale = 1.0 / unprojectv(vDir).length(); + auto height = vDir * font->FontSize * vScale; // ÿֵĸ߶. ʱֵֻ֧Ⱦñò + + auto s = text; + auto orig = topLeft; + texts_.reserve(texts_.size() + (eos - text) * 4); + while (s < eos) { + // Decode and advance source + unsigned int c = (unsigned int)*s; + if (c < 0x80) { + s += 1; + } + else { + s += ImTextCharFromUtf8(&c, s, eos); + if (c == 0) // Malformed UTF-8? + break; + } + + if (c < 32) { + if (c == '\n') { + // TODO: + continue; + } + if (c == '\r') + continue; + } + + const ImFontGlyph* glyph = font->FindGlyph((ImWchar)c); + if (glyph == nullptr) + continue; + + if (glyph->Visible) { + + texts_.resize(texts_.size() + 4); // quadԭ + TextVbo* buf = texts_.data() + texts_.size() - 4; + + // ֿ4glyph + buf[0].pos = toNdc_(orig + hScale * glyph->X0 + vScale * glyph->Y0); // top-left + buf[1].pos = toNdc_(orig + hScale * glyph->X1 + vScale * glyph->Y0); // top-right + buf[2].pos = toNdc_(orig + hScale * glyph->X1 + vScale * glyph->Y1); // bottom-right + buf[3].pos = toNdc_(orig + hScale * glyph->X0 + vScale * glyph->Y1); // bottom-left + + // ֿ + float u1 = glyph->U0; + float v1 = glyph->V0; + float u2 = glyph->U1; + float v2 = glyph->V1; + + buf[0].uv = { u1, v1 }; + buf[1].uv = { u2, v1 }; + buf[2].uv = { u2, v2 }; + buf[3].uv = { u1, v2 }; + + for (int i = 0; i < 4; i++) + buf[i].clr = clr_; + } + + orig += hDir * glyph->AdvanceX; + } +} diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index 35c3a8f..a84700a 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -14,6 +14,13 @@ class KcImOglPaint : public KcImPaint public: + struct TextVbo + { + point3f pos; + point2f uv; + color4f clr; + }; + using super_::super_; void beginPaint() override; @@ -27,16 +34,14 @@ public: void drawLineStrip(point_getter fn, unsigned count) override; + void drawText(const point3& topLeft, const point3& hDir, const point3& vDir, const char* text) override; private: - void pushRenderObject_(KcRenderObject* obj); - - void setGlViewport_(const rect_t& rc); - point3 toNdc_(const point3& pt) const; private: - std::vector> objs_; - std::vector> fns_; + std::vector> objs_; // plottables + std::vector> fns_; // + std::vector texts_; // ı }; diff --git a/src/imapp/KcImPaint.h b/src/imapp/KcImPaint.h index e7e36cd..90833ba 100644 --- a/src/imapp/KcImPaint.h +++ b/src/imapp/KcImPaint.h @@ -68,7 +68,7 @@ public: point2 textSize(const char* text) const override; -private: +protected: ImVec2 project_(const point3& pt, bool round = false) const; static ImColor imColor(const color_t& clr) { diff --git a/src/opengl/KsShaderManager.cpp b/src/opengl/KsShaderManager.cpp index 69b68a2..c09aa97 100644 --- a/src/opengl/KsShaderManager.cpp +++ b/src/opengl/KsShaderManager.cpp @@ -38,6 +38,31 @@ KsShaderManager::shader_ptr KsShaderManager::vertexShaderMono() } +KsShaderManager::shader_ptr KsShaderManager::vertexShaderColorUV() +{ + const static char* vertex_shader_color_uv = + "uniform mat4 mvpMat;\n" + "in vec3 position;\n" + "in vec2 uv;\n" + "in vec4 color;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_Position = mvpMat * vec4(position, 1);\n" + " Frag_UV = uv;\n" + " Frag_Color = color;\n" + "}\n"; + + if (vertexShaderColorUV_ == nullptr) { + vertexShaderColorUV_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_color_uv); + assert(vertexShaderColorUV_->compileStatus()); + } + + return vertexShaderColorUV_; +} + + KsShaderManager::shader_ptr KsShaderManager::fragShaderNaive() { const static char* frag_shader_naive = @@ -56,6 +81,26 @@ KsShaderManager::shader_ptr KsShaderManager::fragShaderNaive() } +KsShaderManager::shader_ptr KsShaderManager::fragShaderColorUV() +{ + const static char* frag_shader_color_uv = + "uniform sampler2D Texture;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" + "}\n"; + + if (fragShaderColorUV_ == nullptr) { + fragShaderColorUV_ = std::make_shared(KcGlslShader::k_shader_fragment, frag_shader_color_uv); + assert(fragShaderColorUV_->compileStatus()); + } + + return fragShaderColorUV_; +} + + KsShaderManager::program_ptr KsShaderManager::programMono() { if (progMono_ == nullptr) { @@ -67,4 +112,18 @@ KsShaderManager::program_ptr KsShaderManager::programMono() } return progMono_; +} + + +KsShaderManager::program_ptr KsShaderManager::programColorUV() +{ + if (progColorUV_ == nullptr) { + progColorUV_ = std::make_shared(); + progColorUV_->attachShader(vertexShaderColorUV()); + progColorUV_->attachShader(fragShaderColorUV()); + progColorUV_->link(); + assert(progColorUV_->linked() && progColorUV_->linkStatus()); + } + + return progColorUV_; } \ No newline at end of file diff --git a/src/opengl/KsShaderManager.h b/src/opengl/KsShaderManager.h index f017e38..8b41d0a 100644 --- a/src/opengl/KsShaderManager.h +++ b/src/opengl/KsShaderManager.h @@ -20,12 +20,26 @@ public: using shader_ptr = std::shared_ptr; using program_ptr = std::shared_ptr; + // attr = pos + // uniform = color shader_ptr vertexShaderMono(); + // attr = pos + uv + color + shader_ptr vertexShaderColorUV(); + + // out-color = in-color shader_ptr fragShaderNaive(); + // out-color = in-color * tex(uv) + shader_ptr fragShaderColorUV(); + + // vertexShaderMono_ + fragShaderNaive_ program_ptr programMono(); + // vertexShaderColorUV_ + fragShaderColorUV_ + program_ptr programColorUV(); + + private: KsShaderManager(); ~KsShaderManager(); @@ -37,7 +51,10 @@ private: private: shader_ptr vertexShaderMono_; + shader_ptr vertexShaderColorUV_; shader_ptr fragShaderNaive_; + shader_ptr fragShaderColorUV_; - program_ptr progMono_; + program_ptr progMono_; + program_ptr progColorUV_; }; diff --git a/src/plot/KvPaint.h b/src/plot/KvPaint.h index 254067e..aa6519d 100644 --- a/src/plot/KvPaint.h +++ b/src/plot/KvPaint.h @@ -96,6 +96,15 @@ public: virtual void fillBetween(point_getter line1, point_getter line2, unsigned count) = 0; + // ʵıάƽĻ + // @topLeft: ıϵλ + // @hDir: ֲֵˮƽ + // @vDir: ֲֵĴְֱ˷ϵд + virtual void drawText(const point3& topLeft, const point3& hDir, const point3& vDir, const char* text) = 0; + + // ÷Ĭdir = {1, 0, 0} + // topLeft㽫anchoralignȷ + // @anchor: ıê㡣ıalignʽanchor virtual void drawText(const point3& anchor, const char* text, int align) = 0; virtual void drawGeom(geom_ptr geom) = 0; -- Gitee From 7aa74caa2d44095786c68dccc2c2950ae3a4fe4c Mon Sep 17 00:00:00 2001 From: koala999 Date: Mon, 19 Dec 2022 09:06:00 +0800 Subject: [PATCH 21/68] add: drawing axis-labels with opengl vbo --- src/imapp/KcImOglPaint.cpp | 48 ++++++++++++++++++++++-------- src/opengl/KcVertexDeclaration.cpp | 4 ++- src/opengl/KsShaderManager.cpp | 12 ++++---- src/plot/KcAxis.cpp | 3 +- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 6b134cb..4a7c5e9 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -76,6 +76,7 @@ namespace kPrivate void KcImOglPaint::beginPaint() { + texts_.clear(); fns_.clear(); objs_.clear(); super_::beginPaint(); @@ -94,8 +95,25 @@ void KcImOglPaint::endPaint() dl->AddCallback(kPrivate::oglDrawFns, &fns_); // text - if (!texts_.empty()) - dl->AddCallback(kPrivate::oglDrawText, &texts_); + if (!texts_.empty()) { + auto obj = new KcRenderObject(KcRenderObject::k_quads, KsShaderManager::singleton().programColorUV()); + + auto decl = std::make_shared(); + KcVertexAttribute attrPos(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); + KcVertexAttribute attrUv(1, KcVertexAttribute::k_float2, sizeof(float) * 3, KcVertexAttribute::k_texcoord); + KcVertexAttribute attrClr(2, KcVertexAttribute::k_float4, sizeof(float) * 5, KcVertexAttribute::k_diffuse); + decl->pushAttribute(attrPos); + decl->pushAttribute(attrUv); + decl->pushAttribute(attrClr); + assert(decl->calcVertexSize() == sizeof(texts_[0])); + + auto vbo = std::make_shared(); + vbo->setData(texts_.data(), texts_.size() * sizeof(texts_[0]), KcGpuBuffer::k_stream_draw); + + obj->setVbo(vbo, decl); + obj->setProjMatrix(float4x4<>::identity()); + objs_.emplace_back(obj); + } // plottables if (!objs_.empty()) @@ -116,6 +134,7 @@ KcImOglPaint::point3 KcImOglPaint::toNdc_(const point3& pt) const return { p.x(), p.y(), p.z() }; } + void KcImOglPaint::drawPoint(const point3& pt) { auto clr = clr_; @@ -215,15 +234,14 @@ void KcImOglPaint::drawText(const point3& topLeft, const point3& hDir, const poi auto font = ImGui::GetFont(); auto eos = text + strlen(text); - auto hScale = 1.0 / unprojectv(hDir).length(); - auto vScale = 1.0 / unprojectv(vDir).length(); + auto hScale = 1.0 / projectv(hDir).length(); + auto vScale = 1.0 / projectv(vDir).length(); auto height = vDir * font->FontSize * vScale; // ÿֵĸ߶. ʱֵֻ֧Ⱦñò auto s = text; auto orig = topLeft; texts_.reserve(texts_.size() + (eos - text) * 4); while (s < eos) { - // Decode and advance source unsigned int c = (unsigned int)*s; if (c < 0x80) { s += 1; @@ -249,14 +267,20 @@ void KcImOglPaint::drawText(const point3& topLeft, const point3& hDir, const poi if (glyph->Visible) { - texts_.resize(texts_.size() + 4); // quadԭ - TextVbo* buf = texts_.data() + texts_.size() - 4; + auto curPos = texts_.size(); + texts_.resize(curPos + 4); // quadͼԪ + TextVbo* buf = texts_.data() + curPos; // ֿ4glyph - buf[0].pos = toNdc_(orig + hScale * glyph->X0 + vScale * glyph->Y0); // top-left - buf[1].pos = toNdc_(orig + hScale * glyph->X1 + vScale * glyph->Y0); // top-right - buf[2].pos = toNdc_(orig + hScale * glyph->X1 + vScale * glyph->Y1); // bottom-right - buf[3].pos = toNdc_(orig + hScale * glyph->X0 + vScale * glyph->Y1); // bottom-left + auto dx1 = hDir * (hScale * glyph->X0); + auto dy1 = vDir * (vScale * glyph->Y0); + auto dx2 = hDir * (hScale * glyph->X1); + auto dy2 = vDir * (vScale * glyph->Y1); + + buf[0].pos = toNdc_(orig + dx1 + dy1); // top-left + buf[1].pos = toNdc_(orig + dx2 + dy1); // top-right + buf[2].pos = toNdc_(orig + dx2 + dy2); // bottom-right + buf[3].pos = toNdc_(orig + dx1 + dy2); // bottom-left // ֿ float u1 = glyph->U0; @@ -273,6 +297,6 @@ void KcImOglPaint::drawText(const point3& topLeft, const point3& hDir, const poi buf[i].clr = clr_; } - orig += hDir * glyph->AdvanceX; + orig += hDir * glyph->AdvanceX * hScale; } } diff --git a/src/opengl/KcVertexDeclaration.cpp b/src/opengl/KcVertexDeclaration.cpp index c71f3bc..e244b28 100644 --- a/src/opengl/KcVertexDeclaration.cpp +++ b/src/opengl/KcVertexDeclaration.cpp @@ -61,6 +61,8 @@ unsigned KcVertexDeclaration::texCoordCount() const void KcVertexDeclaration::declare() const { + auto stride = calcVertexSize(); // Ҫһϲŷ֡TODOһŻÿζ + for (unsigned i = 0; i < attributeCount(); i++) { auto& attr = getAttribute(i); glEnableVertexAttribArray(attr.location()); @@ -76,6 +78,6 @@ void KcVertexDeclaration::declare() const } glVertexAttribPointer(attr.location(), attr.componentCount(), type, - attr.normalized() ? GL_TRUE : GL_FALSE, 0, (void*)attr.offset()); // TODO: stride + attr.normalized() ? GL_TRUE : GL_FALSE, stride, (void*)attr.offset()); } } diff --git a/src/opengl/KsShaderManager.cpp b/src/opengl/KsShaderManager.cpp index c09aa97..d4a5ed6 100644 --- a/src/opengl/KsShaderManager.cpp +++ b/src/opengl/KsShaderManager.cpp @@ -42,16 +42,16 @@ KsShaderManager::shader_ptr KsShaderManager::vertexShaderColorUV() { const static char* vertex_shader_color_uv = "uniform mat4 mvpMat;\n" - "in vec3 position;\n" - "in vec2 uv;\n" - "in vec4 color;\n" + "layout (location = 0) in vec3 iPosition;\n" + "layout (location = 1) in vec2 iUV;\n" + "layout (location = 2) in vec4 iColor;\n" "out vec2 Frag_UV;\n" "out vec4 Frag_Color;\n" "void main()\n" "{\n" - " gl_Position = mvpMat * vec4(position, 1);\n" - " Frag_UV = uv;\n" - " Frag_Color = color;\n" + " gl_Position = mvpMat * vec4(iPosition, 1);\n" + " Frag_UV = iUV;\n" + " Frag_Color = iColor;\n" "}\n"; if (vertexShaderColorUV_ == nullptr) { diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index bc6fd23..97802d5 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -115,7 +115,8 @@ void KcAxis::drawTicks_(KvPaint* paint) const // ƣҲĻ KeAlignment align = labelAlignment_(paint, paint->currentCoord() == KvPaint::k_coord_screen); - paint->drawText(labelAchors[i], label.c_str(), align); + //paint->drawText(labelAchors[i], label.c_str(), align); + paint->drawText(labelAchors[i], vec3::unitX(), -vec3::unitY(), label.c_str()); } } -- Gitee From 882e153a4e95d73cccaaf5af1ff9d10779152b23 Mon Sep 17 00:00:00 2001 From: koala999 Date: Mon, 19 Dec 2022 21:38:00 +0800 Subject: [PATCH 22/68] =?UTF-8?q?refactor:=20=E8=B0=83=E6=95=B4=E5=87=A0?= =?UTF-8?q?=E5=A4=84=E6=88=90=E5=91=98=E6=96=B9=E6=B3=95=E7=9A=84=E5=90=8D?= =?UTF-8?q?=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base/KtAABB.h | 30 ++++++++++++++++++++++++------ src/base/KtArray.h | 16 ++++++++++++---- src/plot/KcAxis.cpp | 4 ++-- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/base/KtAABB.h b/src/base/KtAABB.h index 603ee5a..d3b2726 100644 --- a/src/base/KtAABB.h +++ b/src/base/KtAABB.h @@ -84,7 +84,7 @@ public: /** Sets both minimum and maximum extents at once. */ void setExtents(const point_t& lower, const point_t& upper) { - assert(lower.leAll(upper)); + assert(lower.le(upper)); lower_ = lower, upper_ = upper; } @@ -192,26 +192,44 @@ public: return *this; } - KtAABB& shrink(const point_t& lw, const point_t& up) { + KtAABB& deflate(const point_t& lw, const point_t& up) { lower_ += lw, upper_ -= up; return *this; } - KtAABB& shrink(const KtAABB& d) { - shrink(d.lower(), d.upper()); + KtAABB& deflate(const KtAABB& d) { + deflate(d.lower(), d.upper()); return *this; } - KtAABB& expand(const point_t& lw, const point_t& up) { + KtAABB& deflate(float_t dx, float_t dy) { + point_t d(dx, dy); + return deflate(d, d); + } + + KtAABB& deflate(float_t d) { + return deflate(d, d); + } + + KtAABB& inflate(const point_t& lw, const point_t& up) { lower_ -= lw, upper_ += up; return *this; } - KtAABB& expand(const KtAABB& d) { + KtAABB& inflate(const KtAABB& d) { expand(d.lower(), d.upper()); return *this; } + KtAABB& inflate(float_t dx, float_t dy) { + point_t d(dx, dy); + return inflate(d, d); + } + + KtAABB& inflate(float_t d) { + return inflate(d, d); + } + KtAABB& shift(const point_t& d) { lower_ += d, upper_ += d; return *this; diff --git a/src/base/KtArray.h b/src/base/KtArray.h index c20a9d8..2af8a47 100644 --- a/src/base/KtArray.h +++ b/src/base/KtArray.h @@ -49,7 +49,7 @@ public: operator T* () { return data(); } // return ture when this[i] < rhs[i] for all i - bool ltAll(const KtArray& rhs) const { + bool lt(const KtArray& rhs) const { for (unsigned i = 0; i < size(); i++) if (at(i) >= rhs.at(i)) return false; @@ -57,7 +57,7 @@ public: } // return ture when this[i] > rhs[i] for all i - bool gtAll(const KtArray& rhs) const { + bool gt(const KtArray& rhs) const { for (unsigned i = 0; i < size(); i++) if (at(i) <= rhs.at(i)) return false; @@ -65,7 +65,7 @@ public: } // return ture when this[i] <= rhs[i] for all i - bool leAll(const KtArray& rhs) const { + bool le(const KtArray& rhs) const { for (unsigned i = 0; i < size(); i++) if (at(i) > rhs.at(i)) return false; @@ -73,17 +73,23 @@ public: } // return ture when this[i] >= rhs[i] for all i - bool geAll(const KtArray& rhs) const { + bool ge(const KtArray& rhs) const { for (unsigned i = 0; i < size(); i++) if (at(i) < rhs.at(i)) return false; return true; } + bool bewteen(const KtArray& low, const KtArray& high) const { + return ge(low) && le(high); + } + + // ȡthisptάȵĸֵ void makeCeil(const KtArray& pt) { *this = ceil(*this, pt); } + // ȡthisptάȵĵֵ void makeFloor(const KtArray& pt) { *this = floor(*this, pt); } @@ -93,6 +99,7 @@ public: return o; } + // ȡpt1pt2άȵĸֵ static KtArray ceil(const KtArray& pt1, const KtArray& pt2) { KtArray pt; kMath::forEach(pt1.data(), pt2.data(), pt.data(), size(), [](T x, T y) { @@ -101,6 +108,7 @@ public: return pt; } + // ȡpt1pt2άȵĵֵ static KtArray floor(const KtArray& pt1, const KtArray& pt2) { KtArray pt; kMath::forEach(pt1.data(), pt2.data(), pt.data(), size(), [](T x, T y) { diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 97802d5..e73939d 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -278,7 +278,7 @@ KtMargins KcAxis::calcMargins(KvPaint* paint) const margs.right() = u.x(); margs.bottom() = l.y(); // ڼʸϵԲýbottomtop margs.top() = u.y(); - assert(margs.geAll({ 0, 0, 0, 0 })); + assert(margs.ge({ 0, 0, 0, 0 })); paint->popCoord(); @@ -291,7 +291,7 @@ bool KcAxis::tickAndLabelInSameSide_() const KtLine line(point3(0), end() - start()); auto tickSide = line.whichSide(tickOrient_); auto labelSide = line.whichSide(labelOrient_); - return (tickSide * labelSide).geAll(point3(0)); + return (tickSide * labelSide).ge(point3(0)); } -- Gitee From 50aaa511e46fe1dcced9975a3173eec4822cab73 Mon Sep 17 00:00:00 2001 From: koala999 Date: Mon, 19 Dec 2022 21:38:36 +0800 Subject: [PATCH 23/68] =?UTF-8?q?fix:=20=E6=8A=91=E5=88=B6=E5=AF=B9plot3d?= =?UTF-8?q?=E7=9A=84=E8=A7=86=E5=8F=A3=E5=81=8F=E7=A7=BB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcCoord3d.cpp | 1 + src/plot/KvPlot.cpp | 6 +++++- src/plot/KvPlot.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plot/KcCoord3d.cpp b/src/plot/KcCoord3d.cpp index 78f42e8..e631b2c 100644 --- a/src/plot/KcCoord3d.cpp +++ b/src/plot/KcCoord3d.cpp @@ -125,6 +125,7 @@ void KcCoord3d::forPlane(std::function fn) const KcCoord3d::rect_t KcCoord3d::getPlotRect() const { + return outterRect(); // TODO: ʱףoutterRectKvPlot⵽plotRectviewportƫƣʹ3dȾ return innerRect(); } diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index a0d2aa2..780fe33 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -107,6 +107,9 @@ void KvPlot::update() updateLayout_(paint_->viewport()); + paint_->setViewport(layout_->innerRect()); // ˴ѹinnerRectKcCoord3dfixPlotView_plot3dӿƫ + // TODO: źͨõʵ + auto locals = fixPlotView_(); // ˴localsջpop coord_->draw(paint_.get()); @@ -133,7 +136,8 @@ void KvPlot::update() colorBar_->draw(paint_.get()); // debug drawing - drawLayoutRect_(); + if (showLayoutRect_) + drawLayoutRect_(); paint_->endPaint(); } diff --git a/src/plot/KvPlot.h b/src/plot/KvPlot.h index 37aad68..03ea4dc 100644 --- a/src/plot/KvPlot.h +++ b/src/plot/KvPlot.h @@ -103,6 +103,7 @@ private: bool autoFit_{ true }; // trueÿupdaterangeԶϵextents bool showLegend_{ false }; bool showColorBar_{ true }; + bool showLayoutRect_{ false }; // for debug std::unique_ptr layout_; }; -- Gitee From 9d1e1e7041b8f319345617c4c9c392ce3916ffa6 Mon Sep 17 00:00:00 2001 From: koala999 Date: Tue, 20 Dec 2022 07:48:15 +0800 Subject: [PATCH 24/68] =?UTF-8?q?fix:=20=E5=9D=90=E6=A0=87=E8=BD=B4?= =?UTF-8?q?=E5=88=BB=E5=BA=A6label=E5=9C=A83d=E7=A9=BA=E9=97=B4=E7=9A=84?= =?UTF-8?q?=E5=AE=9A=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layout/KuLayoutUtil.h | 4 ++-- src/plot/KcAxis.cpp | 25 +++++++++++++++++++------ src/plot/KcAxis.h | 23 +++++++++++++++++++++++ src/plot/KvPlot.cpp | 1 + 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/layout/KuLayoutUtil.h b/src/layout/KuLayoutUtil.h index 3ef29b6..6e6e3bc 100644 --- a/src/layout/KuLayoutUtil.h +++ b/src/layout/KuLayoutUtil.h @@ -14,14 +14,14 @@ public: // ػêrect // @anchor: ׼ê - // @contentSize: rectijߴ + // @contentSize: rectijߴ // @align: anchorڷrectĶ뷽ʽ // ˴ͳһĻ꣬bottomΪ+ytopΪ-y static rect_t anchorAlignedRect(const point_t& anchor, const size_t& contentSize, int align); // ػڱ߿rect // @base: ׼߿ - // @contentSize: rectijߴ. contentSize[i] == 0rect.extent[i] = base.extent[i] + // @contentSize: rectijߴ. contentSize[i] == 0rect.extent[i] = base.extent[i] // @align: rectbaseĶ뷽ʽ // ˴ͳһĻ꣬bottomΪ+ytopΪ-y static rect_t outterAlignedRect(const rect_t& base, const size_t& contentSize, int align); diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index e73939d..efb0eda 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -109,14 +109,11 @@ void KcAxis::drawTicks_(KvPaint* paint) const // TODO: paint->setFont(); paint->setColor(labelColor()); auto& labels = scale->labels(); + point3 topLeft, hDir, vDir; for (unsigned i = 0; i < ticks.size(); i++) { auto label = i < labels_.size() ? labels_[i] : labels[i]; - - // ƣҲĻ - KeAlignment align = labelAlignment_(paint, paint->currentCoord() == KvPaint::k_coord_screen); - - //paint->drawText(labelAchors[i], label.c_str(), align); - paint->drawText(labelAchors[i], vec3::unitX(), -vec3::unitY(), label.c_str()); + calcLabelPos_(paint, label, labelAchors[i], topLeft, hDir, vDir); + paint->drawText(topLeft, hDir, vDir, label.c_str()); } } @@ -352,3 +349,19 @@ KcAxis::KeType KcAxis::typeReal() const // TODO: ʱֻǶά return KeType(swapType[type_][swapped() ? 1 : 0]); } + + +// TODO: õʵַ +void KcAxis::calcLabelPos_(KvPaint* paint, const std::string_view& label, const point3& anchor, point3& topLeft, point3& hDir, point3& vDir) const +{ + // ƣҲĻ + KeAlignment align = labelAlignment_(paint, paint->currentCoord() == KvPaint::k_coord_screen); + + auto anchorInScreen = paint->projectp(anchor); + auto rc = KuLayoutUtil::anchorAlignedRect({ anchorInScreen.x(), anchorInScreen.y() }, paint->textSize(label.data()), align); + auto topLeftInScreen = point3(rc.lower().x(), rc.lower().y(), anchorInScreen.z()); + + topLeft = paint->unprojectp(topLeftInScreen); + hDir = vec3::unitX(); + vDir = -vec3::unitY(); +} diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index 68c0907..f6e9416 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -196,6 +196,9 @@ private: size_t calcSize_(void* cxt) const final; + // 3dռı3topLeft, hDir, vDir + void calcLabelPos_(KvPaint*, const std::string_view& label, const point3& anchor, point3& topLeft, point3& hDir, point3& vDir) const; + private: KeType type_; std::string title_; @@ -224,4 +227,24 @@ private: int dimSwapped_; bool main_{ true }; // Ƿ bool inv_{ false }; // Ƿת + + // ³Աlabel-boxlayoutpose + + // ʼ״̬£label-boxλڿ̶ṹɵƽ + // + // label-boxIJ̬anchor + // labelλ࣬anchorλlabel-boxright-center + // labelλҲ࣬anchorλlabel-boxleft-center + // lebelλ²࣬anchorλlabel-boxtop-center + // lebelλϲ࣬anchorλlabel-boxbottom-center + // ڲlabelPadding_£labeltickͬ࣬anchor̶ߵĩغϣ̶ȵغ + + // ñȷlabel-boxijʼ״̬ + bool labelVertical_{ false }; // true labelıУı˳+y/-z᷽չ + // falselebelıУı˳+x᷽չ + + // ñȷlabel-boxڳʼֵ̬仯 + point3 pose_{ 0, 0, 0 }; // pose_[0]ʾƫyawlabel-boxƽĴߣanchor㣩תǶ + // pose_[1]ʾpitchƽֱߣanchor㣩תǶ + // pose_[2]ʾrollĴߣanchor㣩תǶ }; diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index 780fe33..4105492 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -110,6 +110,7 @@ void KvPlot::update() paint_->setViewport(layout_->innerRect()); // ˴ѹinnerRectKcCoord3dfixPlotView_plot3dӿƫ // TODO: źͨõʵ + // ӿƫƣҪplot2dϵlowerƵӿڵ½ǣ auto locals = fixPlotView_(); // ˴localsջpop coord_->draw(paint_.get()); -- Gitee From c93ac9d409ac201b8bc90b07cc1ed851a085605c Mon Sep 17 00:00:00 2001 From: koala999 Date: Wed, 21 Dec 2022 22:57:14 +0800 Subject: [PATCH 25/68] =?UTF-8?q?new:=20=E7=BB=98=E5=88=B6=E5=9D=90?= =?UTF-8?q?=E6=A0=87=E8=BD=B4=E7=9A=84=E6=A0=87=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcAxis.cpp | 84 ++++++++++++++++++++++++++++++++++++------ src/plot/KcAxis.h | 10 ++++- src/plot/KcCoord2d.cpp | 5 ++- src/plot/KcCoord3d.cpp | 7 +++- 4 files changed, 89 insertions(+), 17 deletions(-) diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index efb0eda..6a4c554 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -58,9 +58,15 @@ void KcAxis::draw(KvPaint* paint) const paint->drawLine(start(), end()); // } - // draw ticks + // draw ticks & label if (showTick() || showLabel()) drawTicks_(paint); + else + titleAnchor_ = (start() + end()) / 2 + labelOrient_ * titlePadding_ / paint->projectv(labelOrient_).length(); + + // draw title + if (showTitle() && !title().empty()) + drawTitle_(paint); } @@ -85,22 +91,29 @@ void KcAxis::drawTicks_(KvPaint* paint) const paint->apply(tickCxt_); - std::vector labelAchors; + std::vector labelAnchors; bool sameSide = tickAndLabelInSameSide_(); if (showLabel()) - labelAchors.resize(ticks.size()); + labelAnchors.resize(ticks.size()); + + if (showTitle()) { + titleAnchor_ = (start() + end()) / 2 + labelOrient_ * titlePadding_ * labelPaddingPerPixel; + + if (sameSide && showTick()) + titleAnchor_ += tickOrient_ * tickCxt_.length * tickLenPerPixel; + } for (unsigned i = 0; i < ticks.size(); i++) { auto anchor = tickPos(ticks[i]); - if (showTick()) - drawTick_(paint, anchor, tickCxt_.length * tickLenPerPixel); + if (showTick()) + drawTick_(paint, anchor, tickCxt_.length * tickLenPerPixel); if (showLabel()) { - labelAchors[i] = anchor + labelOrient_ * labelPadding_ * labelPaddingPerPixel; + labelAnchors[i] = anchor + labelOrient_ * labelPadding_ * labelPaddingPerPixel; if (sameSide && showTick()) - labelAchors[i] += tickOrient_ * tickCxt_.length * tickLenPerPixel; + labelAnchors[i] += tickOrient_ * tickCxt_.length * tickLenPerPixel; } } @@ -109,11 +122,29 @@ void KcAxis::drawTicks_(KvPaint* paint) const // TODO: paint->setFont(); paint->setColor(labelColor()); auto& labels = scale->labels(); - point3 topLeft, hDir, vDir; + point3 topLeft; + vec3 hDir, vDir; + point2 maxLabelSize(0); for (unsigned i = 0; i < ticks.size(); i++) { auto label = i < labels_.size() ? labels_[i] : labels[i]; - calcLabelPos_(paint, label, labelAchors[i], topLeft, hDir, vDir); + calcLabelPos_(paint, label, labelAnchors[i], topLeft, hDir, vDir); paint->drawText(topLeft, hDir, vDir, label.c_str()); + + if (showTitle()) + maxLabelSize = point2::ceil(maxLabelSize, paint->textSize(label.c_str())); + } + + if (showTitle()) { + + vec3 h = hDir * maxLabelSize.x(); + vec3 v = vDir * maxLabelSize.y(); + + h = h.projectedTo(labelOrient_); + v = v.projectedTo(labelOrient_); + + auto maxSqLen = std::max(h.squaredLength(), v.squaredLength()); + + titleAnchor_ += labelOrient_ * (std::sqrt(maxSqLen) + labelPadding_ ) * labelPaddingPerPixel; } } @@ -259,9 +290,28 @@ KtMargins KcAxis::calcMargins(KvPaint* paint) const } } - if (showTitle()) { - //margins += paint->textSize(title_.c_str()).x(); - //margins += titlePadding_; + if (showTitle() && !title().empty()) { + auto sz = paint->textSize(title_.c_str()); + switch (typeReal()) { + case KcAxis::k_left: + box.lower().x() -= sz.x() + titlePadding_; + break; + + case KcAxis::k_right: + box.upper().x() += sz.x() + titlePadding_; + break; + + case KcAxis::k_bottom: + box.lower().y() -= sz.y() + titlePadding_; + break; + + case KcAxis::k_top: + box.upper().y() += sz.y() + titlePadding_; + break; + + default: + assert(false); + } } aabb_t outter(box.lower(), box.upper()); @@ -347,6 +397,8 @@ KcAxis::KeType KcAxis::typeReal() const }; // TODO: ʱֻǶά + assert(dimReal_ < 2 && dimSwapped_ < 2); + return KeType(swapType[type_][swapped() ? 1 : 0]); } @@ -365,3 +417,11 @@ void KcAxis::calcLabelPos_(KvPaint* paint, const std::string_view& label, const hDir = vec3::unitX(); vDir = -vec3::unitY(); } + + +void KcAxis::drawTitle_(KvPaint* paint) const +{ + point3 topLeft, hDir, vDir; + calcLabelPos_(paint, title_.c_str(), titleAnchor_, topLeft, hDir, vDir); + paint->drawText(topLeft, hDir, vDir, title_.c_str()); +} diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index f6e9416..d7cf990 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -187,6 +187,7 @@ public: KeType typeReal() const; // swapaxisʵλ private: + void drawTitle_(KvPaint*) const; void drawTicks_(KvPaint*) const; // п̶ void drawTick_(KvPaint*, const point3& anchor, double length) const; // Ƶ̶ߣ̶븱̶ @@ -228,7 +229,7 @@ private: bool main_{ true }; // Ƿ bool inv_{ false }; // Ƿת - // ³Աlabel-boxlayoutpose + // ³Աlabel-boxlayoutposeTODO // ʼ״̬£label-boxλڿ̶ṹɵƽ // @@ -247,4 +248,11 @@ private: point3 pose_{ 0, 0, 0 }; // pose_[0]ʾƫyawlabel-boxƽĴߣanchor㣩תǶ // pose_[1]ʾpitchƽֱߣanchor㣩תǶ // pose_[2]ʾrollĴߣanchor㣩תǶ + + + // Ϊߴ㻺ʱ + std::vector labelSize_; + mutable point2 titleSize_; + mutable point3 titleAnchor_; // titleıtop-left + vec3 hDir_, vDir_; // labelıˮƽʹֱչ }; diff --git a/src/plot/KcCoord2d.cpp b/src/plot/KcCoord2d.cpp index 2cc299f..320d9ce 100644 --- a/src/plot/KcCoord2d.cpp +++ b/src/plot/KcCoord2d.cpp @@ -20,7 +20,7 @@ KcCoord2d::KcCoord2d(const point2& lower, const point2& upper) dim[KcAxis::k_left] = dim[KcAxis::k_right] = 1; // ʼ4 - for (unsigned i = 0; i < 4; i++) + for (unsigned i = 0; i < 4; i++) axes_[i].emplace_back(new KcAxis(KcAxis::KeType(i), dim[i], true)); setExtents({ lower.x(), lower.y(), -1 }, { upper.x(), upper.y(), 1 }); @@ -34,8 +34,9 @@ KcCoord2d::KcCoord2d(const point2& lower, const point2& upper) axes_[KcAxis::k_top].front()->tickOrient() = axes_[KcAxis::k_top].front()->labelOrient() = KcAxis::vec3::unitY(); + static const char* title[] = { "X", "Y" }; for (unsigned i = 0; i < 4; i++) - axes_[i].front()->showTick() = true, axes_[i].front()->showLabel() = true; + axes_[i].front()->title() = title[axes_[i].front()->dim()]; axes_[KcAxis::k_right].front()->visible() = false; axes_[KcAxis::k_top].front()->visible() = false; diff --git a/src/plot/KcCoord3d.cpp b/src/plot/KcCoord3d.cpp index e631b2c..140a4a6 100644 --- a/src/plot/KcCoord3d.cpp +++ b/src/plot/KcCoord3d.cpp @@ -57,8 +57,11 @@ KcCoord3d::KcCoord3d(const point3& lower, const point3& upper) axes_[KcAxis::k_ceil_left]->tickOrient() = axes_[KcAxis::k_ceil_left]->labelOrient() = -KcAxis::vec3::unitX(); - for(unsigned i = 0; i < std::size(axes_); i++) - axes_[i]->visible() = false; + static const char* title[] = { "X", "Y", "Z" }; + for (unsigned i = 0; i < std::size(axes_); i++) { + axes_[i]->visible() = false; + axes_[i]->title() = title[axes_[i]->dim()]; + } axes_[KcAxis::k_near_bottom]->visible() = true; axes_[KcAxis::k_near_left]->visible() = true; -- Gitee From d9019df4e45b8a4b6664d0f3efefc1786bd148dd Mon Sep 17 00:00:00 2001 From: koala999 Date: Thu, 22 Dec 2022 14:40:20 +0800 Subject: [PATCH 26/68] =?UTF-8?q?refactor:=20=E6=9B=B4=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E7=9A=84axis=E7=95=99=E7=99=BD=E8=AE=A1=E7=AE=97=EF=BC=88?= =?UTF-8?q?=E5=85=BC=E5=AE=B93d=E5=9D=90=E6=A0=87=E7=B3=BB=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcAxis.cpp | 192 +++++++++++++------------------------------ src/plot/KcAxis.h | 20 +++-- src/plot/KvPaint.cpp | 7 ++ src/plot/KvPaint.h | 2 + 4 files changed, 77 insertions(+), 144 deletions(-) diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 6a4c554..6e08153 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -42,35 +42,34 @@ void KcAxis::setScaler(std::shared_ptr scale) } -KcAxis::aabb_t KcAxis::boundingBox() const -{ - return { start(), end() }; -} - - -void KcAxis::draw(KvPaint* paint) const +void KcAxis::draw_(KvPaint* paint, bool calcBox) const { assert(visible()); + if (calcBox) + box_ = aabb_t(start(), end()); + // draw baseline - if (showBaseline()) { + if (showBaseline() && !calcBox) { paint->apply(baselineCxt_); paint->drawLine(start(), end()); // } + auto realShowTitle = showTitle() && !title().empty(); + // draw ticks & label if (showTick() || showLabel()) - drawTicks_(paint); - else + drawTicks_(paint, calcBox); + else if (realShowTitle) titleAnchor_ = (start() + end()) / 2 + labelOrient_ * titlePadding_ / paint->projectv(labelOrient_).length(); // draw title - if (showTitle() && !title().empty()) - drawTitle_(paint); + if (realShowTitle) + drawLabel_(paint, title_, titleAnchor_, calcBox); } -void KcAxis::drawTicks_(KvPaint* paint) const +void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const { assert(showTick() || showLabel()); @@ -89,7 +88,8 @@ void KcAxis::drawTicks_(KvPaint* paint) const float_t tickLenPerPixel = 1 / tl.length(); float_t labelPaddingPerPixel = 1 / ll.length(); - paint->apply(tickCxt_); + if (!calcBox) + paint->apply(tickCxt_); std::vector labelAnchors; bool sameSide = tickAndLabelInSameSide_(); @@ -107,7 +107,7 @@ void KcAxis::drawTicks_(KvPaint* paint) const auto anchor = tickPos(ticks[i]); if (showTick()) - drawTick_(paint, anchor, tickCxt_.length * tickLenPerPixel); + drawTick_(paint, anchor, tickCxt_.length * tickLenPerPixel, calcBox); if (showLabel()) { labelAnchors[i] = anchor + labelOrient_ * labelPadding_ * labelPaddingPerPixel; @@ -122,25 +122,22 @@ void KcAxis::drawTicks_(KvPaint* paint) const // TODO: paint->setFont(); paint->setColor(labelColor()); auto& labels = scale->labels(); - point3 topLeft; - vec3 hDir, vDir; point2 maxLabelSize(0); for (unsigned i = 0; i < ticks.size(); i++) { auto label = i < labels_.size() ? labels_[i] : labels[i]; - calcLabelPos_(paint, label, labelAnchors[i], topLeft, hDir, vDir); - paint->drawText(topLeft, hDir, vDir, label.c_str()); + drawLabel_(paint, label, labelAnchors[i], calcBox); if (showTitle()) maxLabelSize = point2::ceil(maxLabelSize, paint->textSize(label.c_str())); } - if (showTitle()) { + if (showTitle() || calcBox) { - vec3 h = hDir * maxLabelSize.x(); - vec3 v = vDir * maxLabelSize.y(); + vec3 h = vec3::unitX() * maxLabelSize.x(); // TODO: hDir + vec3 v = vec3::unitY() * maxLabelSize.y(); // TODO: vDir - h = h.projectedTo(labelOrient_); - v = v.projectedTo(labelOrient_); + h = h.projectedTo(ll); + v = v.projectedTo(ll); auto maxSqLen = std::max(h.squaredLength(), v.squaredLength()); @@ -156,15 +153,21 @@ void KcAxis::drawTicks_(KvPaint* paint) const double subtickLen = subtickCxt_.length * tickLenPerPixel; for (unsigned i = 0; i < subticks.size(); i++) - drawTick_(paint, tickPos(subticks[i]), subtickLen); + drawTick_(paint, tickPos(subticks[i]), subtickLen, calcBox); } } -void KcAxis::drawTick_(KvPaint* paint, const point3& anchor, double length) const +void KcAxis::drawTick_(KvPaint* paint, const point3& anchor, double length, bool calcBox) const { auto d = tickOrient() * length; - paint->drawLine(tickBothSide() ? anchor - d : anchor, anchor + d); + if (!calcBox) + paint->drawLine(tickBothSide() ? anchor - d : anchor, anchor + d); + else { + box_.merge(anchor + d); + if (tickBothSide()) + box_.merge(anchor - d); + } } @@ -235,100 +238,23 @@ KcAxis::size_t KcAxis::calcSize_(void* cxt) const // drawϵʵʻƣpaintִлָʱת KtMargins KcAxis::calcMargins(KvPaint* paint) const { - //if (!visible() || length() == 0) - // return { 0, 0, 0, 0 }; - - paint->pushCoord(KvPaint::k_coord_screen); // мĻ½ - - auto tickOrient = paint->projectv(tickOrient_).normalize(); - - vec3 tickLen(0); // tickijʸ - if (showTick()) - tickLen = tickOrient * tickCxt_.length; - - auto scale = scaler(); - scale->generate(lower(), upper(), false, showLabel()); - auto& ticks = scale->ticks(); - - vec3 dir = paint->projectv((end() - start()).normalize()); // ķʸ - point3 lowerPt(0), upperPt(lowerPt + dir * length()); // Ŀǰ֪startendʵֵrangeΪϵ - aabb_t box(lowerPt, upperPt); - - if (showBaseline()) { - auto w = baselineCxt_.width; - if (typeReal() == k_left || typeReal() == k_bottom) - w = -w; - box.merge({ w, w, w }); - } - - if (showTick() && !ticks.empty()) { - // ϲһһtickbox - float_t pos[2]; - pos[0] = kPrivate::remap(ticks.front(), lower(), upper(), 0., length(), inversed()); - pos[1] = kPrivate::remap(ticks.back(), lower(), upper(), 0., length(), inversed()); - for (int i = 0; i < 2; i++) - box.merge(lowerPt + dir * pos[i] + tickLen); - } + if (!visible() || length() == 0) + return { 0, 0, 0, 0 }; - - if (showLabel()) { // ϲlabelbox + draw_(paint, true); - // жlabeltickǷͬ - bool sameSide = tickAndLabelInSameSide_(); - auto& labels = scale->labels(); + aabb_t ibox(paint->projectp(start()), paint->projectp(end())); + aabb_t obox(paint->projectp(box_.lower()), paint->projectp(box_.upper())); + auto l = ibox.lower() - obox.lower(); + auto u = obox.upper() - ibox.upper(); - for (unsigned i = 0; i < ticks.size(); i++) { - auto pos = kPrivate::remap(ticks[i], lower(), upper(), 0., length(), inversed()); - auto labelAchors = lowerPt + dir * pos; - if (sameSide) - labelAchors += tickOrient * tickCxt_.length; - - labelAchors += paint->projectv(labelOrient_).normalize() * labelPadding_; - - auto labelText = i < labels_.size() ? labels_[i] : labels[i]; - box.merge(textBox_(paint, labelAchors, labelText)); - } - } - - if (showTitle() && !title().empty()) { - auto sz = paint->textSize(title_.c_str()); - switch (typeReal()) { - case KcAxis::k_left: - box.lower().x() -= sz.x() + titlePadding_; - break; - - case KcAxis::k_right: - box.upper().x() += sz.x() + titlePadding_; - break; - - case KcAxis::k_bottom: - box.lower().y() -= sz.y() + titlePadding_; - break; - - case KcAxis::k_top: - box.upper().y() += sz.y() + titlePadding_; - break; - - default: - assert(false); - } - } - - aabb_t outter(box.lower(), box.upper()); - aabb_t inner(lowerPt, upperPt); - - auto l = inner.lower() - outter.lower(); - auto u = outter.upper() - inner.upper(); - KtMargins margs; margs.left() = l.x(); margs.right() = u.x(); - margs.bottom() = l.y(); // ڼʸϵԲýbottomtop - margs.top() = u.y(); + margs.bottom() = u.y(); + margs.top() = l.y(); assert(margs.ge({ 0, 0, 0, 0 })); - paint->popCoord(); - return margs; } @@ -342,24 +268,6 @@ bool KcAxis::tickAndLabelInSameSide_() const } -KcAxis::aabb_t KcAxis::textBox_(KvPaint* paint, const point3& anchor, const std::string& text) const -{ - auto r = KuLayoutUtil::anchorAlignedRect({ anchor.x(), anchor.y() }, - paint->textSize(text.c_str()), labelAlignment_(paint, true)); - - return { - { r.lower().x(), r.lower().y(), anchor.z() }, - { r.upper().x(), r.upper().y(), anchor.z() } - }; - - // ˴rΪĻ꣬ҪתΪͼ - //auto yLower = 2 * anchor.y() - r.upper().y(); - //auto yUpper = 2 * anchor.y() - r.lower().y(); - - //return { { r.lower().x(), yLower, anchor.z() }, { r.upper().x(), yUpper, anchor.z() } }; -} - - KcAxis::KeType KcAxis::typeReal() const { // ͽ @@ -411,17 +319,27 @@ void KcAxis::calcLabelPos_(KvPaint* paint, const std::string_view& label, const auto anchorInScreen = paint->projectp(anchor); auto rc = KuLayoutUtil::anchorAlignedRect({ anchorInScreen.x(), anchorInScreen.y() }, paint->textSize(label.data()), align); - auto topLeftInScreen = point3(rc.lower().x(), rc.lower().y(), anchorInScreen.z()); + auto topLeftInScreen = point3(rc.lower().x(), rc.lower().y(), anchorInScreen.z()); // TODO: תӦò topLeft = paint->unprojectp(topLeftInScreen); - hDir = vec3::unitX(); - vDir = -vec3::unitY(); + hDir = paint->unprojectv(vec3::unitX()); + vDir = paint->unprojectv(vec3::unitY()); } -void KcAxis::drawTitle_(KvPaint* paint) const +void KcAxis::drawLabel_(KvPaint* paint, const std::string_view& label, const point3& anchor, bool calcBox) const { point3 topLeft, hDir, vDir; - calcLabelPos_(paint, title_.c_str(), titleAnchor_, topLeft, hDir, vDir); - paint->drawText(topLeft, hDir, vDir, title_.c_str()); + calcLabelPos_(paint, label.data(), anchor, topLeft, hDir, vDir); + if (!calcBox) { + paint->drawText(topLeft, hDir, vDir, label.data()); + } + else { + auto sz = paint->textSize(label.data()); + auto h = paint->projectv(hDir) * sz.x(); + auto v = paint->projectv(vDir) * sz.y(); + h = paint->unprojectv(h); + v = paint->unprojectv(v); + box_.merge({ topLeft, topLeft + h + v }); + } } diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index d7cf990..43683b8 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -163,9 +163,14 @@ public: std::shared_ptr scaler() const; void setScaler(std::shared_ptr scale); - aabb_t boundingBox() const override; + // NB֮󣨼calcSize֮󣩣úܷЧֵ + aabb_t boundingBox() const override { + return box_; + } - void draw(KvPaint*) const override; + void draw(KvPaint* paint) const override { + return draw_(paint, false); + } // tickֵtickϵĵ3ά꣨꣩ point3 tickPos(double val) const; @@ -187,13 +192,13 @@ public: KeType typeReal() const; // swapaxisʵλ private: - void drawTitle_(KvPaint*) const; - void drawTicks_(KvPaint*) const; // п̶ - void drawTick_(KvPaint*, const point3& anchor, double length) const; // Ƶ̶ߣ̶븱̶ - + void draw_(KvPaint*, bool calcBox) const; + void drawTicks_(KvPaint*, bool calcBox) const; // п̶ + void drawTick_(KvPaint*, const point3& anchor, double length, bool calcBox) const; // Ƶ̶ߣ̶븱̶ + void drawLabel_(KvPaint* paint, const std::string_view& label, const point3& anchor, bool calcBox) const; + int labelAlignment_(KvPaint* paint, bool toggleTopBottom) const; // labelorientationжlabelalignment bool tickAndLabelInSameSide_() const; // жticktick-labelǷλͬ - aabb_t textBox_(KvPaint*, const point3& anchor, const std::string& text) const; size_t calcSize_(void* cxt) const final; @@ -255,4 +260,5 @@ private: mutable point2 titleSize_; mutable point3 titleAnchor_; // titleıtop-left vec3 hDir_, vDir_; // labelıˮƽʹֱչ + mutable aabb_t box_; // Ԥaabb }; diff --git a/src/plot/KvPaint.cpp b/src/plot/KvPaint.cpp index 10e3f95..f7b26c5 100644 --- a/src/plot/KvPaint.cpp +++ b/src/plot/KvPaint.cpp @@ -65,6 +65,13 @@ void KvPaint::drawRect(const point3& lower, const point3& upper) } +void KvPaint::drawBox(const point3& lower, const point3& upper) +{ + // TODO: + drawRect(lower, upper); +} + + void KvPaint::fillQuad(point3 pts[4]) { fillTriangle(pts); diff --git a/src/plot/KvPaint.h b/src/plot/KvPaint.h index aa6519d..3433db5 100644 --- a/src/plot/KvPaint.h +++ b/src/plot/KvPaint.h @@ -82,6 +82,8 @@ public: virtual void drawRect(const point3& lower, const point3& upper); + virtual void drawBox(const point3& lower, const point3& upper); + virtual void fillTriangle(point3 pts[3]) = 0; virtual void fillTriangle(point3 pts[3], color_t clrs[3]) = 0; -- Gitee From 0722fc51d3372eb70f040f6f242d235618843a40 Mon Sep 17 00:00:00 2001 From: koala999 Date: Thu, 22 Dec 2022 15:29:25 +0800 Subject: [PATCH 27/68] refactor: rename "scaler" to "ticker" --- DataVis.vcxproj | 8 +++--- DataVis.vcxproj.filters | 8 +++--- src/plot/KcAxis.cpp | 25 ++++++++++--------- src/plot/KcAxis.h | 8 +++--- src/plot/KcCoordPlane.cpp | 18 ++++++------- ...{KcLinearScaler.cpp => KcLinearTicker.cpp} | 12 ++++----- .../{KcLinearScaler.h => KcLinearTicker.h} | 6 ++--- src/plot/{KvScaler.cpp => KvTicker.cpp} | 8 +++--- src/plot/{KvScaler.h => KvTicker.h} | 6 ++--- 9 files changed, 50 insertions(+), 49 deletions(-) rename src/plot/{KcLinearScaler.cpp => KcLinearTicker.cpp} (87%) rename src/plot/{KcLinearScaler.h => KcLinearTicker.h} (86%) rename src/plot/{KvScaler.cpp => KvTicker.cpp} (69%) rename src/plot/{KvScaler.h => KvTicker.h} (96%) diff --git a/DataVis.vcxproj b/DataVis.vcxproj index d740bb1..3036948 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -209,7 +209,7 @@ - + @@ -226,7 +226,7 @@ - + @@ -389,7 +389,7 @@ - + @@ -411,7 +411,7 @@ - + diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index 5eb0cff..262c8a1 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -70,10 +70,10 @@ base - + plot - + plot @@ -552,10 +552,10 @@ base - + plot - + plot diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 6e08153..f2af89b 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -1,6 +1,6 @@ #include "KcAxis.h" #include -#include "KcLinearScaler.h" +#include "KcLinearTicker.h" #include "KvPaint.h" #include "KtuMath.h" #include "KtLine.h" @@ -27,18 +27,18 @@ KcAxis::KcAxis(KeType type, int dim, bool main) //labelFont_, titleFont_; // TODO: - scaler_ = std::make_shared(); + ticker_ = std::make_shared(); } -std::shared_ptr KcAxis::scaler() const +std::shared_ptr KcAxis::ticker() const { - return scaler_; + return ticker_; } -void KcAxis::setScaler(std::shared_ptr scale) +void KcAxis::setTicker(std::shared_ptr tic) { - scaler_ = scale; + ticker_ = tic; } @@ -64,8 +64,10 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const titleAnchor_ = (start() + end()) / 2 + labelOrient_ * titlePadding_ / paint->projectv(labelOrient_).length(); // draw title - if (realShowTitle) + if (realShowTitle) { + paint->setColor(titleColor()); drawLabel_(paint, title_, titleAnchor_, calcBox); + } } @@ -76,9 +78,8 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const if (length() == 0) return; // TODO: draw or not draw ? draw what ?? - auto scale = scaler(); - scale->generate(lower(), upper(), showSubtick(), showLabel()); - const auto& ticks = scale->ticks(); + ticker()->generate(lower(), upper(), showSubtick(), showLabel()); + const auto& ticks = ticker()->ticks(); assert(KtuMath::almostEqual(tickOrient().length(), 1)); @@ -121,7 +122,7 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const // TODO: paint->setFont(); paint->setColor(labelColor()); - auto& labels = scale->labels(); + auto& labels = ticker()->labels(); point2 maxLabelSize(0); for (unsigned i = 0; i < ticks.size(); i++) { auto label = i < labels_.size() ? labels_[i] : labels[i]; @@ -146,7 +147,7 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const } // minor - auto& subticks = scale->subticks(); + auto& subticks = ticker()->subticks(); if (showSubtick() && !subticks.empty()) { paint->apply(subtickCxt_); diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index 43683b8..83ac088 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -3,7 +3,7 @@ #include #include #include "KvRenderable.h" -#include "KvScaler.h" +#include "KvTicker.h" #include "KtColor.h" #include "KtVector3.h" #include "KpContext.h" @@ -160,8 +160,8 @@ public: //QFont titleFont() const { return titleFont_; } //void setTitleFont(QFont font) { titleFont_ = font; } - std::shared_ptr scaler() const; - void setScaler(std::shared_ptr scale); + std::shared_ptr ticker() const; + void setTicker(std::shared_ptr tic); // NB֮󣨼calcSize֮󣩣úܷЧֵ aabb_t boundingBox() const override { @@ -227,7 +227,7 @@ private: vec3 labelOrient_; bool tickBothSide_{ false }; - std::shared_ptr scaler_; + std::shared_ptr ticker_; int dimReal_; // 0ʾxᣬ1ʾyᣬ2ʾzᣬ-1ʾ?ʾcolorbar int dimSwapped_; diff --git a/src/plot/KcCoordPlane.cpp b/src/plot/KcCoordPlane.cpp index b99487e..9804287 100644 --- a/src/plot/KcCoordPlane.cpp +++ b/src/plot/KcCoordPlane.cpp @@ -52,7 +52,7 @@ void KcCoordPlane::draw(KvPaint* paint) const }; for(unsigned i = 0; i < std::size(axes); i++) - axes[i]->scaler()->generate(axes[i]->lower(), axes[i]->upper(), showMajor, showMinor); + axes[i]->ticker()->generate(axes[i]->lower(), axes[i]->upper(), showMajor, showMinor); if (showMajor) { paint->apply(majorLineCxt_); @@ -70,13 +70,13 @@ void KcCoordPlane::draw(KvPaint* paint) const void KcCoordPlane::drawMajors_(KvPaint* paint, axis_ptr axis0, axis_ptr axis1) { - auto scale0 = axis0->scaler(); - auto scale1 = axis1->scaler(); + auto t0 = axis0->ticker(); + auto t1 = axis1->ticker(); - assert(scale0->tickCount() == scale1->tickCount()); // TODO: + assert(t0->tickCount() == t1->tickCount()); // TODO: auto vlen = axis1->start() - axis0->start(); - auto& ticks = scale0->ticks(); // TODO: ٶticks + auto& ticks = t0->ticks(); // TODO: ٶticks for (auto t : ticks) { auto pos = axis0->tickPos(t); paint->drawLine(pos, pos + vlen); @@ -86,13 +86,13 @@ void KcCoordPlane::drawMajors_(KvPaint* paint, axis_ptr axis0, axis_ptr axis1) void KcCoordPlane::drawMinors_(KvPaint* paint, axis_ptr axis0, axis_ptr axis1) { - auto scale0 = axis0->scaler(); - auto scale1 = axis1->scaler(); + auto t0 = axis0->ticker(); + auto t1 = axis1->ticker(); - assert(scale0->subtickCount() == scale1->subtickCount()); // TODO: + assert(t0->subtickCount() == t1->subtickCount()); // TODO: auto vlen = axis1->start() - axis0->start(); - auto& subticks = scale0->subticks(); + auto& subticks = t0->subticks(); for (auto t : subticks) { auto pos = axis0->tickPos(t); paint->drawLine(pos, pos + vlen); diff --git a/src/plot/KcLinearScaler.cpp b/src/plot/KcLinearTicker.cpp similarity index 87% rename from src/plot/KcLinearScaler.cpp rename to src/plot/KcLinearTicker.cpp index 0fe39ec..356de29 100644 --- a/src/plot/KcLinearScaler.cpp +++ b/src/plot/KcLinearTicker.cpp @@ -1,17 +1,17 @@ -#include "KcLinearScaler.h" +#include "KcLinearTicker.h" #include #include #include "KtuMath.h" -KcLinearScaler::KcLinearScaler() +KcLinearTicker::KcLinearTicker() { mantissi_ = //{ 1, 2, 2.5, 5, 10 }; { 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0 }; } -void KcLinearScaler::generate(double lower, double upper, bool genSubticks, bool genLabels) +void KcLinearTicker::generate(double lower, double upper, bool genSubticks, bool genLabels) { if (lower >= upper) return; @@ -51,7 +51,7 @@ void KcLinearScaler::generate(double lower, double upper, bool genSubticks, bool } -unsigned KcLinearScaler::autoRange_(double& lower, double& upper) +unsigned KcLinearTicker::autoRange_(double& lower, double& upper) { assert(upper > lower); @@ -68,7 +68,7 @@ unsigned KcLinearScaler::autoRange_(double& lower, double& upper) } -double KcLinearScaler::getTickStep_(double lower, double upper) const +double KcLinearTicker::getTickStep_(double lower, double upper) const { if (tickCount() <= 1) return upper - lower; @@ -83,7 +83,7 @@ double KcLinearScaler::getTickStep_(double lower, double upper) const } -void KcLinearScaler::trimTicks_(double lower, double upper, std::vector& ticks) +void KcLinearTicker::trimTicks_(double lower, double upper, std::vector& ticks) { // TODO: Ż while (!ticks.empty() && ticks.front() < lower) diff --git a/src/plot/KcLinearScaler.h b/src/plot/KcLinearTicker.h similarity index 86% rename from src/plot/KcLinearScaler.h rename to src/plot/KcLinearTicker.h index 924672d..b46c4de 100644 --- a/src/plot/KcLinearScaler.h +++ b/src/plot/KcLinearTicker.h @@ -1,11 +1,11 @@ #pragma once -#include "KvScaler.h" +#include "KvTicker.h" -class KcLinearScaler : public KvScaler +class KcLinearTicker : public KvTicker { public: - KcLinearScaler(); + KcLinearTicker(); void generate(double lower, double upper, bool genSubticks, bool genLabels) override; diff --git a/src/plot/KvScaler.cpp b/src/plot/KvTicker.cpp similarity index 69% rename from src/plot/KvScaler.cpp rename to src/plot/KvTicker.cpp index 99a7fb7..575c795 100644 --- a/src/plot/KvScaler.cpp +++ b/src/plot/KvTicker.cpp @@ -1,8 +1,8 @@ -#include "KvScaler.h" +#include "KvTicker.h" #include -KvScaler::KvScaler() +KvTicker::KvTicker() { tickCount_ = 5; subtickCount_ = 4; @@ -10,13 +10,13 @@ KvScaler::KvScaler() } -KvScaler::~KvScaler() +KvTicker::~KvTicker() { } -std::string KvScaler::genLabel_(double val) const +std::string KvTicker::genLabel_(double val) const { char buf[64]; sprintf_s(buf, format_.c_str(), val); diff --git a/src/plot/KvScaler.h b/src/plot/KvTicker.h similarity index 96% rename from src/plot/KvScaler.h rename to src/plot/KvTicker.h index 328dadf..109bab9 100644 --- a/src/plot/KvScaler.h +++ b/src/plot/KvTicker.h @@ -5,11 +5,11 @@ // ̶ȲԵijࣺĿ̶λúͿ̶label -class KvScaler +class KvTicker { public: - KvScaler(); - virtual ~KvScaler(); + KvTicker(); + virtual ~KvTicker(); unsigned tickCount() const { return tickCount_; } void setTickCount(unsigned count) { tickCount_ = count; } -- Gitee From 03e4af5895ef08709473f3385aed9b907985a93d Mon Sep 17 00:00:00 2001 From: koala999 Date: Thu, 22 Dec 2022 15:37:35 +0800 Subject: [PATCH 28/68] =?UTF-8?q?fix:=20box=E5=B8=83=E5=B1=80=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E7=9A=84=E5=9D=90=E6=A0=87=E8=BD=B4=E6=A0=87=E9=A2=98?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/layouts.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/themes/layouts.json b/themes/layouts.json index 67ee5f3..5c58f96 100644 --- a/themes/layouts.json +++ b/themes/layouts.json @@ -80,55 +80,55 @@ "right": { "visible": true, "baseline": true, - "label": null, + "text": null, "tick": null }, "top": { "visible": true, "baseline": true, - "label": null, + "text": null, "tick": null }, "far-left": { "visible": true, "baseline": true, - "label": null, + "text": null, "tick": null }, "far-right": { "visible": true, "baseline": true, - "label": null, + "text": null, "tick": null }, "far-bottom": { "visible": true, "baseline": true, - "label": null, + "text": null, "tick": null }, "far-top": { "visible": true, "baseline": true, - "label": null, + "text": null, "tick": null }, "floor-left": { "visible": true, "baseline": true, - "label": null, + "text": null, "tick": null }, "ceil-left": { "visible": true, "baseline": true, - "label": null, + "text": null, "tick": null }, "ceil-right": { "visible": true, "baseline": true, - "label": null, + "text": null, "tick": null } }, -- Gitee From 8cc8d8bb8b2ff40bd3e78747c91a5c0eb14dcba1 Mon Sep 17 00:00:00 2001 From: koala999 Date: Thu, 22 Dec 2022 15:45:07 +0800 Subject: [PATCH 29/68] =?UTF-8?q?fix:=20=E5=9D=90=E6=A0=87=E8=BD=B4?= =?UTF-8?q?=E5=8F=AA=E6=98=BE=E7=A4=BAbaseline=E6=97=B6=E7=9A=84=E7=95=99?= =?UTF-8?q?=E7=99=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcAxis.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index f2af89b..4a334be 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -216,16 +216,16 @@ KcAxis::size_t KcAxis::calcSize_(void* cxt) const switch (typeReal()) { case KcAxis::k_left: - return { calcMargins(paint).left(), 0 }; + return { std::max(calcMargins(paint).left(), baselineCxt_.width), 0 }; case KcAxis::k_right: - return { calcMargins(paint).right(), 0 }; + return { std::max(calcMargins(paint).right(), baselineCxt_.width), 0 }; case KcAxis::k_bottom: - return { 0, calcMargins(paint).bottom() }; + return { 0, std::max(calcMargins(paint).bottom(), baselineCxt_.width) }; case KcAxis::k_top: - return { 0, calcMargins(paint).top() }; + return { 0, std::max(calcMargins(paint).top(), baselineCxt_.width) }; default: break; -- Gitee From b249e7e79bb7554bcb151a9030d62560f7e7bc6c Mon Sep 17 00:00:00 2001 From: koala999 Date: Fri, 23 Dec 2022 19:26:18 +0800 Subject: [PATCH 30/68] =?UTF-8?q?add:=20=E6=B8=B2=E6=9F=93=E7=8A=B6?= =?UTF-8?q?=E6=80=81+=E6=B8=B2=E6=9F=93=E9=98=9F=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 272 ++++++++++++++++++++++++++++++------- src/imapp/KcImOglPaint.h | 56 +++++++- src/imapp/KcImPaint.h | 3 +- src/plot/KcCoord3d.cpp | 1 - src/plot/KvPaint.h | 4 + src/plot/KvPlot.cpp | 18 ++- src/plot/KvPlot.h | 10 +- src/plot/KvPlot2d.cpp | 2 +- src/plot/KvPlot3d.cpp | 2 +- 9 files changed, 306 insertions(+), 62 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 4a7c5e9..f1bd3ad 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -23,7 +23,7 @@ namespace kPrivate glLoadIdentity(); KcImOglPaint* paint = (KcImOglPaint*)cmd->UserCallbackData; - auto rc = paint->viewport(); + auto rc = paint->viewport(); // NB: ȷһڣviewportֲ auto y0 = ImGui::GetMainViewport()->Size.y - rc.upper().y(); glViewport(rc.lower().x(), y0, rc.width(), rc.height()); } @@ -64,7 +64,7 @@ namespace kPrivate obj.draw(); } - // colorwidthúã˴Ҫstyle + // colorwidthúã˴Ҫstyle(TODO) void oglLine(int style, const KcImOglPaint::point3& from, const KcImOglPaint::point3& to) { glBegin(GL_LINES); @@ -72,53 +72,50 @@ namespace kPrivate glVertex3f(to.x(), to.y(), to.z()); glEnd(); } + + void oglDrawRenderList(const ImDrawList*, const ImDrawCmd* cmd) + { + auto paint = (KcImOglPaint*)cmd->UserCallbackData; + paint->drawRenderList_(); + } +} + + +KcImOglPaint::KcImOglPaint(camera_type& cam) + : super_(cam) +{ + curViewport_ = -1; + curClipBox_ = -1; } + void KcImOglPaint::beginPaint() { - texts_.clear(); - fns_.clear(); - objs_.clear(); + renderList_.clear(); + + viewportHistList_.clear(); + clipRectHistList_.clear(); + + viewportHistList_.push_back(viewport()); + curViewport_ = 0; + + auto crmin = ImGui::GetWindowDrawList()->GetClipRectMin(); + auto crmax = ImGui::GetWindowDrawList()->GetClipRectMax(); + clipRectHistList_.emplace_back(point2(crmin.x, crmin.y), point2(crmax.x, crmax.y)); + clipRectStack_.push_back(0); + + clipBoxHistList_.clear(); + curClipBox_ = -1; + super_::beginPaint(); } void KcImOglPaint::endPaint() { - if (!fns_.empty() || !objs_.empty()) { + if (!renderList_.empty()) { auto dl = ImGui::GetWindowDrawList(); - - dl->AddCallback(kPrivate::oglSetRenderState, this); - - // ɢ - if (!fns_.empty()) - dl->AddCallback(kPrivate::oglDrawFns, &fns_); - - // text - if (!texts_.empty()) { - auto obj = new KcRenderObject(KcRenderObject::k_quads, KsShaderManager::singleton().programColorUV()); - - auto decl = std::make_shared(); - KcVertexAttribute attrPos(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); - KcVertexAttribute attrUv(1, KcVertexAttribute::k_float2, sizeof(float) * 3, KcVertexAttribute::k_texcoord); - KcVertexAttribute attrClr(2, KcVertexAttribute::k_float4, sizeof(float) * 5, KcVertexAttribute::k_diffuse); - decl->pushAttribute(attrPos); - decl->pushAttribute(attrUv); - decl->pushAttribute(attrClr); - assert(decl->calcVertexSize() == sizeof(texts_[0])); - - auto vbo = std::make_shared(); - vbo->setData(texts_.data(), texts_.size() * sizeof(texts_[0]), KcGpuBuffer::k_stream_draw); - - obj->setVbo(vbo, decl); - obj->setProjMatrix(float4x4<>::identity()); - objs_.emplace_back(obj); - } - - // plottables - if (!objs_.empty()) - dl->AddCallback(kPrivate::oglDrawVbos, &objs_); - + dl->AddCallback(kPrivate::oglDrawRenderList, this); dl->AddCallback(ImDrawCallback_ResetRenderState, nullptr); // imguiָȾ״̬ } @@ -156,7 +153,7 @@ void KcImOglPaint::drawPoint(const point3& pt) }; - fns_.push_back(drawFn); + currentRenderList().fns.push_back(drawFn); } @@ -178,7 +175,8 @@ void KcImOglPaint::drawPoints(point_getter fn, unsigned count) obj->setColor(clr_); obj->setSize(pointSize_); obj->setProjMatrix(camera_.getMvpMat()); - objs_.emplace_back(obj); + + currentRenderList().objs.emplace_back(obj); } @@ -203,7 +201,7 @@ void KcImOglPaint::drawLine(const point3& from, const point3& to) }; - fns_.push_back(drawFn); + currentRenderList().fns.push_back(drawFn); } @@ -225,7 +223,7 @@ void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) obj->setColor(clr_); obj->setWidth(lineWidth_); obj->setProjMatrix(camera_.getMvpMat()); - objs_.emplace_back(obj); + currentRenderList().objs.emplace_back(obj); } @@ -240,7 +238,8 @@ void KcImOglPaint::drawText(const point3& topLeft, const point3& hDir, const poi auto s = text; auto orig = topLeft; - texts_.reserve(texts_.size() + (eos - text) * 4); + auto& texts = currentRenderList().texts; + texts.reserve(texts.size() + (eos - text) * 4); while (s < eos) { unsigned int c = (unsigned int)*s; if (c < 0x80) { @@ -267,9 +266,9 @@ void KcImOglPaint::drawText(const point3& topLeft, const point3& hDir, const poi if (glyph->Visible) { - auto curPos = texts_.size(); - texts_.resize(curPos + 4); // quadͼԪ - TextVbo* buf = texts_.data() + curPos; + auto curPos = texts.size(); + texts.resize(curPos + 4); // quadͼԪ + TextVbo* buf = texts.data() + curPos; // ֿ4glyph auto dx1 = hDir * (hScale * glyph->X0); @@ -300,3 +299,184 @@ void KcImOglPaint::drawText(const point3& topLeft, const point3& hDir, const poi orig += hDir * glyph->AdvanceX * hScale; } } + + +void KcImOglPaint::pushTextVbo_(KpRenderList_& rl) +{ + if (!rl.texts.empty()) { + auto obj = new KcRenderObject(KcRenderObject::k_quads, + KsShaderManager::singleton().programColorUV()); + + auto decl = std::make_shared(); + KcVertexAttribute attrPos(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); + KcVertexAttribute attrUv(1, KcVertexAttribute::k_float2, sizeof(float) * 3, KcVertexAttribute::k_texcoord); + KcVertexAttribute attrClr(2, KcVertexAttribute::k_float4, sizeof(float) * 5, KcVertexAttribute::k_diffuse); + decl->pushAttribute(attrPos); + decl->pushAttribute(attrUv); + decl->pushAttribute(attrClr); + assert(decl->calcVertexSize() == sizeof(rl.texts[0])); + + auto vbo = std::make_shared(); + vbo->setData(rl.texts.data(), rl.texts.size() * sizeof(rl.texts[0]), KcGpuBuffer::k_stream_draw); + + obj->setVbo(vbo, decl); + obj->setProjMatrix(float4x4<>::identity()); + rl.objs.emplace_back(obj); + } +} + + +void KcImOglPaint::setViewport(const rect_t& vp) +{ + auto pos = std::find(viewportHistList_.cbegin(), viewportHistList_.cend(), vp); + if (pos == viewportHistList_.cend()) { + curViewport_ = viewportHistList_.size(); + viewportHistList_.push_back(vp); + } + else { + curViewport_ = std::distance(viewportHistList_.cbegin(), pos); + } + + super_::setViewport(vp); +} + + +void KcImOglPaint::pushClipRect(const rect_t& cr) +{ + auto pos = std::find(clipRectHistList_.cbegin(), clipRectHistList_.cend(), cr); + if (pos == clipRectHistList_.cend()) { + clipRectStack_.push_back(clipRectHistList_.size()); + clipRectHistList_.push_back(cr); + } + else { + clipRectStack_.push_back(std::distance(clipRectHistList_.cbegin(), pos)); + } + + super_::pushClipRect(cr); // TODO: õúȥĶImGuiȾ״̬ +} + + +void KcImOglPaint::popClipRect() +{ + clipRectStack_.pop_back(); + + super_::popClipRect(); +} + + +void KcImOglPaint::enableClipBox(point3 lower, point3 upper) +{ + auto pos = std::find(clipBoxHistList_.cbegin(), clipBoxHistList_.cend(), aabb_t(lower, upper)); + if (pos == clipBoxHistList_.cend()) { + curClipBox_ = clipBoxHistList_.size(); + clipBoxHistList_.emplace_back(lower, upper); + } + else { + curClipBox_ = std::distance(clipBoxHistList_.cbegin(), pos); + } +} + + +void KcImOglPaint::disableClipBox() +{ + curClipBox_ = -1; +} + + +KcImOglPaint::KpRenderList_& KcImOglPaint::currentRenderList() +{ + auto curClipRect = clipRectStack_.empty() ? -1 : clipRectStack_.back(); + return renderList_[kRenderState_(curViewport_, curClipRect, curClipBox_)]; +} + + +void KcImOglPaint::drawRenderList_() +{ + unsigned viewport(-1), clipRect(-1), clipBox(-1); + for (auto& rd : renderList_) { + auto& state = rd.first; + if (std::get<0>(state) != viewport) { + viewport = std::get<0>(state); + glViewport_(viewport); + } + if (std::get<1>(state) != clipRect) { + clipRect = std::get<1>(state); + glScissor_(clipRect); + } + if (std::get<2>(state) != clipBox) { + clipBox = std::get<2>(state); + glClipPlane_(clipBox); + } + + auto& rl = rd.second; + + KcGlslProgram::useProgram(0); // shaderʹù̶߻ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + for (auto& i : rl.fns) + i(); + + pushTextVbo_(rl); + for (auto& i : rl.objs) + i->draw(); + } +} + + +void KcImOglPaint::glViewport_(unsigned id) +{ + if (id != -1) { + assert(id < viewportHistList_.size()); + auto& rc = viewportHistList_[id]; + auto y0 = ImGui::GetMainViewport()->Size.y - rc.upper().y(); + glViewport(rc.lower().x(), y0, rc.width(), rc.height()); + } +} + + +void KcImOglPaint::glScissor_(unsigned id) +{ + if (id != -1) { + assert(id < clipRectHistList_.size()); + auto& rc = clipRectHistList_[id]; + auto y0 = ImGui::GetMainViewport()->Size.y - rc.upper().y(); + glScissor(rc.lower().x(), y0, rc.width(), rc.height()); + } +} + + +void KcImOglPaint::glClipPlane_(unsigned id) +{ + static constexpr unsigned planes[] = { + GL_CLIP_PLANE0, + GL_CLIP_PLANE1, + GL_CLIP_PLANE2, + GL_CLIP_PLANE3, + GL_CLIP_PLANE4, + GL_CLIP_PLANE5 + }; + + if (id != -1) { + assert(id < clipBoxHistList_.size()); + auto& aabb = clipBoxHistList_[id]; + GLdouble clipPlane[4]{ 0 }; + for (int i = 0; i < 3; i++) { + clipPlane[i] = 1; clipPlane[3] = aabb.lower()[i]; + glClipPlane(planes[2 * i], clipPlane); + glEnable(planes[2 * i]); + + clipPlane[i] = -1; clipPlane[3] = aabb.upper()[i]; + glClipPlane(planes[2 * i + 1], clipPlane); + glEnable(planes[2 * i + 1]); + + clipPlane[i] = 0; + } + } + else { + for(unsigned i = 0; i < std::size(planes); i++) + glDisable(planes[i]); + } +} diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index a84700a..c6361f5 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include "opengl/KcRenderObject.h" @@ -11,6 +13,7 @@ class KcImOglPaint : public KcImPaint { using super_ = KcImPaint; + using aabb_t = KtAABB; public: @@ -21,7 +24,15 @@ public: color4f clr; }; - using super_::super_; + KcImOglPaint(camera_type& cam); + + void setViewport(const rect_t& vp) override; + + void pushClipRect(const rect_t& cr) override; + void popClipRect() override; + + void enableClipBox(point3 lower, point3 upper) override; + void disableClipBox() override; void beginPaint() override; void endPaint() override; @@ -36,12 +47,49 @@ public: void drawText(const point3& topLeft, const point3& hDir, const point3& vDir, const char* text) override; + // ڲImGuiصԻrenderList_Ⱦ + void drawRenderList_(); + private: point3 toNdc_(const point3& pt) const; + +private: + + // render states stacks + + std::vector viewportHistList_; + std::vector clipRectHistList_; + std::vector clipBoxHistList_; + + std::vector clipRectStack_; + unsigned curViewport_; // -1ʾδ + unsigned curClipBox_; + + // ʹtuple3ջ + using kRenderState_ = std::tuple; + + struct KpRenderList_ + { + std::vector> objs; // plottables + std::vector> fns; // + std::vector texts; // ı + }; + + // Ⱦ״̬ĴȾб + std::map renderList_; + + //std::vector glLists_; // clipBoxʾбid + //unsigned clipBox_{ 0 }; // 浱ǰclipBox״̬ӦglLists_ + // ͨglCallList(glLists_[clipBox_])ӦclipBox0ʾ + private: - std::vector> objs_; // plottables - std::vector> fns_; // - std::vector texts_; // ı + KpRenderList_& currentRenderList(); + + void glViewport_(unsigned id); + void glScissor_(unsigned id); + void glClipPlane_(unsigned id); + + void pushTextVbo_(KpRenderList_& rl); // ɻıvbo }; diff --git a/src/imapp/KcImPaint.h b/src/imapp/KcImPaint.h index 90833ba..86b1fac 100644 --- a/src/imapp/KcImPaint.h +++ b/src/imapp/KcImPaint.h @@ -6,9 +6,8 @@ class KcImPaint : public KvPaint { - using camera_type = KtProjector; - public: + using camera_type = KtProjector; KcImPaint(camera_type& cam); diff --git a/src/plot/KcCoord3d.cpp b/src/plot/KcCoord3d.cpp index 140a4a6..11aebde 100644 --- a/src/plot/KcCoord3d.cpp +++ b/src/plot/KcCoord3d.cpp @@ -128,7 +128,6 @@ void KcCoord3d::forPlane(std::function fn) const KcCoord3d::rect_t KcCoord3d::getPlotRect() const { - return outterRect(); // TODO: ʱףoutterRectKvPlot⵽plotRectviewportƫƣʹ3dȾ return innerRect(); } diff --git a/src/plot/KvPaint.h b/src/plot/KvPaint.h index 3433db5..17302a6 100644 --- a/src/plot/KvPaint.h +++ b/src/plot/KvPaint.h @@ -48,6 +48,10 @@ public: virtual void popCoord() = 0; virtual KeCoordType currentCoord() const = 0; + // 3άϵ6ƽ湹ɵclipPlane + virtual void enableClipBox(point3 lower, point3 upper) = 0; + virtual void disableClipBox() = 0; + // project local point/vector to screen point/vector virtual point4 project(const point4& pt) const = 0; diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index 4105492..2a4a4a6 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -7,9 +7,10 @@ #include "layout/KuLayoutHelper.h" -KvPlot::KvPlot(std::shared_ptr paint, std::shared_ptr coord) +KvPlot::KvPlot(std::shared_ptr paint, std::shared_ptr coord, char dim) : paint_(paint) , coord_(coord) + , dim_(dim) { legend_ = new KcLegend; colorBar_ = nullptr; @@ -99,7 +100,7 @@ void KvPlot::update() auto axisSwapped = coord_->axisSwapped(); if (axisSwapped) - paint_->pushLocal(coord_->axisSwapMatrix()); + paint_->pushLocal(coord_->axisSwapMatrix()); // ѹύautoProject_Ҫ autoProject_(); @@ -119,8 +120,14 @@ void KvPlot::update() if (axisInversed) paint_->pushLocal(coord_->axisInverseMatrix()); + if (dim() == 3) + paint_->enableClipBox(coord_->lower(), coord_->upper()); + drawPlottables_(); + if (dim() == 3) + paint_->disableClipBox(); + if (axisInversed) paint_->popLocal(); @@ -146,6 +153,9 @@ void KvPlot::update() int KvPlot::fixPlotView_() { + if (dim() != 2) + return 0; // ֻplot2d + auto rcCanvas = paint_->viewport(); auto rcPlot = coord_->getPlotRect(); if (rcPlot == rcCanvas) @@ -268,13 +278,13 @@ void KvPlot::syncLegendAndColorBar_(KvPlottable* removedPlt, KvPlottable* addedP void KvPlot::drawPlottables_() { - //paint_->pushClipRect(paint_->viewport()); // clipRectֹplottablesΧ + paint_->pushClipRect(coord_->getPlotRect()); // clipRectֹplottablesΧ for (int idx = 0; idx < plottableCount(); idx++) if (plottableAt(idx)->visible()) plottableAt(idx)->draw(paint_.get()); - //paint_->popClipRect(); + paint_->popClipRect(); } diff --git a/src/plot/KvPlot.h b/src/plot/KvPlot.h index 03ea4dc..b47a382 100644 --- a/src/plot/KvPlot.h +++ b/src/plot/KvPlot.h @@ -21,7 +21,7 @@ class KvPlot using margins_t = KtMargins; public: - KvPlot(std::shared_ptr paint, std::shared_ptr coord); + KvPlot(std::shared_ptr paint, std::shared_ptr coord, char dim); ~KvPlot(); virtual void setVisible(bool b) = 0; @@ -72,6 +72,8 @@ public: void setMargins(const margins_t& m); void setMargins(float l, float t, float r, float b); + char dim() const { return dim_; } + private: virtual void autoProject_() = 0; @@ -100,10 +102,12 @@ private: KpBrush bkgnd_; + std::unique_ptr layout_; + + char dim_{ 3 }; // ȡֵ23thisplot2dplot3d + bool autoFit_{ true }; // trueÿupdaterangeԶϵextents bool showLegend_{ false }; bool showColorBar_{ true }; bool showLayoutRect_{ false }; // for debug - - std::unique_ptr layout_; }; diff --git a/src/plot/KvPlot2d.cpp b/src/plot/KvPlot2d.cpp index ef8853c..be6baf0 100644 --- a/src/plot/KvPlot2d.cpp +++ b/src/plot/KvPlot2d.cpp @@ -3,7 +3,7 @@ KvPlot2d::KvPlot2d(std::shared_ptr paint, std::shared_ptr coord) - : KvPlot(paint, coord) + : KvPlot(paint, coord, 2) { setMargins(15, 15, 15, 15); } diff --git a/src/plot/KvPlot3d.cpp b/src/plot/KvPlot3d.cpp index 2b35987..17702f3 100644 --- a/src/plot/KvPlot3d.cpp +++ b/src/plot/KvPlot3d.cpp @@ -4,7 +4,7 @@ KvPlot3d::KvPlot3d(std::shared_ptr paint, std::shared_ptr coord) - : KvPlot(paint, coord) + : KvPlot(paint, coord, 3) { mat3d<> rot; rot.fromEulerAngleXYZ(0.316, -0.595, 0); -- Gitee From 447276a0d8c1e5bbbc6c8a7f9e762f4b4b1f0e0b Mon Sep 17 00:00:00 2001 From: koala999 Date: Fri, 23 Dec 2022 19:39:28 +0800 Subject: [PATCH 31/68] =?UTF-8?q?add:=20pushAttribute=E7=9A=84=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E5=BF=AB=E6=8D=B7=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 66 +++--------------------------- src/opengl/KcVertexDeclaration.cpp | 7 ++++ src/opengl/KcVertexDeclaration.h | 2 + 3 files changed, 14 insertions(+), 61 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index f1bd3ad..05e6841 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -13,57 +13,6 @@ namespace kPrivate { - void oglSetRenderState(const ImDrawList* parent_list, const ImDrawCmd* cmd) - { - KcGlslProgram::useProgram(0); // shaderʹù̶߻ - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - KcImOglPaint* paint = (KcImOglPaint*)cmd->UserCallbackData; - auto rc = paint->viewport(); // NB: ȷһڣviewportֲ - auto y0 = ImGui::GetMainViewport()->Size.y - rc.upper().y(); - glViewport(rc.lower().x(), y0, rc.width(), rc.height()); - } - - void oglDrawVbos(const ImDrawList* parent_list, const ImDrawCmd* cmd) - { - auto objs = (std::vector>*)cmd->UserCallbackData; - for (auto& i : *objs) - i->draw(); - } - - void oglDrawFns(const ImDrawList* parent_list, const ImDrawCmd* cmd) - { - auto fns = (std::vector>*)cmd->UserCallbackData; - for (auto& i : *fns) - i(); - } - - void oglDrawText(const ImDrawList* parent_list, const ImDrawCmd* cmd) - { - auto vtx = (std::vector*)cmd->UserCallbackData; - - auto obj = KcRenderObject(KcRenderObject::k_quads, KsShaderManager::singleton().programColorUV()); - - auto decl = std::make_shared(); - KcVertexAttribute attrPos(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); - KcVertexAttribute attrUv(1, KcVertexAttribute::k_float2, sizeof(float) * 3, KcVertexAttribute::k_texcoord); - KcVertexAttribute attrClr(2, KcVertexAttribute::k_float4, sizeof(float) * 5, KcVertexAttribute::k_diffuse); - decl->pushAttribute(attrPos); - decl->pushAttribute(attrUv); - decl->pushAttribute(attrClr); - - auto vbo = std::make_shared(); - vbo->setData(vtx->data(), vtx->size() * sizeof(KcImOglPaint::TextVbo), KcGpuBuffer::k_stream_draw); - - obj.setVbo(vbo, decl); - obj.setProjMatrix(float4x4<>::identity()); - obj.draw(); - } - // colorwidthúã˴Ҫstyle(TODO) void oglLine(int style, const KcImOglPaint::point3& from, const KcImOglPaint::point3& to) { @@ -162,8 +111,7 @@ void KcImOglPaint::drawPoints(point_getter fn, unsigned count) auto obj = new KcPointObject; auto decl = std::make_shared(); - KcVertexAttribute attr(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); - decl->pushAttribute(attr); + decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); auto vbo = std::make_shared(); std::vector vtx; @@ -210,8 +158,7 @@ void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) auto obj = new KcLineObject(KcRenderObject::k_line_strip); auto decl = std::make_shared(); - KcVertexAttribute attr(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); - decl->pushAttribute(attr); + decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); auto vbo = std::make_shared(); std::vector vtx; @@ -308,12 +255,9 @@ void KcImOglPaint::pushTextVbo_(KpRenderList_& rl) KsShaderManager::singleton().programColorUV()); auto decl = std::make_shared(); - KcVertexAttribute attrPos(0, KcVertexAttribute::k_float3, 0, KcVertexAttribute::k_position); - KcVertexAttribute attrUv(1, KcVertexAttribute::k_float2, sizeof(float) * 3, KcVertexAttribute::k_texcoord); - KcVertexAttribute attrClr(2, KcVertexAttribute::k_float4, sizeof(float) * 5, KcVertexAttribute::k_diffuse); - decl->pushAttribute(attrPos); - decl->pushAttribute(attrUv); - decl->pushAttribute(attrClr); + decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); + decl->pushAttribute(KcVertexAttribute::k_float2, KcVertexAttribute::k_texcoord); + decl->pushAttribute(KcVertexAttribute::k_float4, KcVertexAttribute::k_diffuse); assert(decl->calcVertexSize() == sizeof(rl.texts[0])); auto vbo = std::make_shared(); diff --git a/src/opengl/KcVertexDeclaration.cpp b/src/opengl/KcVertexDeclaration.cpp index e244b28..e1e7db7 100644 --- a/src/opengl/KcVertexDeclaration.cpp +++ b/src/opengl/KcVertexDeclaration.cpp @@ -3,6 +3,13 @@ #include +void KcVertexDeclaration::pushAttribute(KcVertexAttribute::KeFormat fmt, KcVertexAttribute::KeSemantic semantic, unsigned semanticIndex) +{ + pushAttribute(KcVertexAttribute(attributeCount(), fmt, calcVertexSize(), + semantic, semanticIndex)); // TODO: semanticIndexҲ +} + + const KcVertexAttribute* KcVertexDeclaration::findAttribute(KcVertexAttribute::KeSemantic semantic, unsigned semanticIdx) const { for(unsigned i = 0; i < attributeCount(); i++) { diff --git a/src/opengl/KcVertexDeclaration.h b/src/opengl/KcVertexDeclaration.h index 6b885f5..9155c7c 100644 --- a/src/opengl/KcVertexDeclaration.h +++ b/src/opengl/KcVertexDeclaration.h @@ -13,6 +13,8 @@ public: attrs_.push_back(attr); } + void pushAttribute(KcVertexAttribute::KeFormat fmt, KcVertexAttribute::KeSemantic semantic, unsigned semanticIndex = 0); + KcVertexAttribute& getAttribute(unsigned idx) { return attrs_[idx]; } const KcVertexAttribute& getAttribute(unsigned idx) const { return attrs_[idx]; } -- Gitee From f7500490fc2df646e9bdebf7cbcfdd714bc84322 Mon Sep 17 00:00:00 2001 From: koala999 Date: Sat, 24 Dec 2022 12:26:26 +0800 Subject: [PATCH 32/68] =?UTF-8?q?add:=20plot3d=E7=9A=84=E4=B8=89=E7=BB=B4?= =?UTF-8?q?=E8=A3=81=E5=89=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 9 +++++++-- src/opengl/KcLineObject.cpp | 3 ++- src/opengl/KcPointObject.cpp | 3 ++- src/opengl/KcRenderObject.cpp | 11 +++++++++++ src/opengl/KcRenderObject.h | 10 +++++++--- src/opengl/KsShaderManager.cpp | 21 ++++++++++++++++++--- 6 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 05e6841..3b14550 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -170,6 +170,11 @@ void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) obj->setColor(clr_); obj->setWidth(lineWidth_); obj->setProjMatrix(camera_.getMvpMat()); + if (curClipBox_ != -1) { + auto& box = clipBoxHistList_[curClipBox_]; + obj->setClipBox({ box.lower(), box.upper() }); + } + currentRenderList().objs.emplace_back(obj); } @@ -406,9 +411,9 @@ void KcImOglPaint::glClipPlane_(unsigned id) if (id != -1) { assert(id < clipBoxHistList_.size()); auto& aabb = clipBoxHistList_[id]; - GLdouble clipPlane[4]{ 0 }; + GLdouble clipPlane[4] = { 0 }; for (int i = 0; i < 3; i++) { - clipPlane[i] = 1; clipPlane[3] = aabb.lower()[i]; + clipPlane[i] = 1; clipPlane[3] = -aabb.lower()[i]; glClipPlane(planes[2 * i], clipPlane); glEnable(planes[2 * i]); diff --git a/src/opengl/KcLineObject.cpp b/src/opengl/KcLineObject.cpp index 76a1c67..16de941 100644 --- a/src/opengl/KcLineObject.cpp +++ b/src/opengl/KcLineObject.cpp @@ -15,7 +15,8 @@ void KcLineObject::draw() const { glLineWidth(lineWidth_); prog_->useProgram(); - glUniform4f(1, lineColor_[0], lineColor_[1], lineColor_[2], lineColor_[3]); + auto loc = prog_->getUniformLocation("vColor"); + glUniform4f(loc, lineColor_[0], lineColor_[1], lineColor_[2], lineColor_[3]); super_::draw(); } diff --git a/src/opengl/KcPointObject.cpp b/src/opengl/KcPointObject.cpp index 1ea7d3e..6e5ae75 100644 --- a/src/opengl/KcPointObject.cpp +++ b/src/opengl/KcPointObject.cpp @@ -19,6 +19,7 @@ void KcPointObject::draw() const //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); prog_->useProgram(); - glUniform4f(1, pointColor_[0], pointColor_[1], pointColor_[2], pointColor_[3]); + auto loc = prog_->getUniformLocation("vColor"); + glUniform4f(loc, pointColor_[0], pointColor_[1], pointColor_[2], pointColor_[3]); super_::draw(); } diff --git a/src/opengl/KcRenderObject.cpp b/src/opengl/KcRenderObject.cpp index cf4e2f5..e7cb938 100644 --- a/src/opengl/KcRenderObject.cpp +++ b/src/opengl/KcRenderObject.cpp @@ -27,5 +27,16 @@ void KcRenderObject::draw() const prog_->useProgram(); // shader glUniformMatrix4fv(0, 1, GL_TRUE, projMat_.data()); + GLint enableClip = !clipBox_.isNull(); + auto loc = prog_->getUniformLocation("iEnableClip"); + glUniform1i(loc, enableClip); + if (enableClip) { + loc = prog_->getUniformLocation("vClipLower"); + glUniform3f(loc, clipBox_.lower().x(), clipBox_.lower().y(), clipBox_.lower().z()); + loc = prog_->getUniformLocation("vClipUpper"); + glUniform3f(loc, clipBox_.upper().x(), clipBox_.upper().y(), clipBox_.upper().z()); + } + + glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vtxDecl_->calcVertexSize()); } diff --git a/src/opengl/KcRenderObject.h b/src/opengl/KcRenderObject.h index dab7cb2..46a78fa 100644 --- a/src/opengl/KcRenderObject.h +++ b/src/opengl/KcRenderObject.h @@ -12,10 +12,10 @@ class KcVertexDeclaration; class KcRenderObject { - using rect_t = KtAABB; - public: + using aabb_t = KtAABB; + enum KeType { k_points, // Draws a point at each of the n vertices @@ -59,6 +59,10 @@ public: projMat_ = projMat; } + void setClipBox(const aabb_t& clipBox) { + clipBox_ = clipBox; + } + virtual void draw() const; protected: @@ -67,5 +71,5 @@ protected: std::shared_ptr vbo_; std::shared_ptr vtxDecl_; float4x4<> projMat_; - //rect_t vp_; // 浥ӿڣֶ֧രڻ + aabb_t clipBox_; }; diff --git a/src/opengl/KsShaderManager.cpp b/src/opengl/KsShaderManager.cpp index d4a5ed6..89289bb 100644 --- a/src/opengl/KsShaderManager.cpp +++ b/src/opengl/KsShaderManager.cpp @@ -20,18 +20,33 @@ KsShaderManager::shader_ptr KsShaderManager::vertexShaderMono() { const static char* vertex_shader_mono = "uniform mat4 mvpMat;\n" + "uniform int iEnableClip;\n" + "uniform vec3 vClipLower;\n" + "uniform vec3 vClipUpper;\n" "uniform vec4 vColor;\n" - "in vec3 position;\n" + "in vec3 iPosition;\n" "out vec4 Frag_Color;\n" "void main()\n" "{\n" - " gl_Position = mvpMat * vec4(position, 1);\n" + " gl_Position = mvpMat * vec4(iPosition, 1);\n" " Frag_Color = vColor;\n" + " if (iEnableClip != 0)\n" + " {\n" + " gl_ClipDistance[0] = iPosition.x - vClipLower.x;\n" + " gl_ClipDistance[1] = iPosition.y - vClipLower.y;\n" + " gl_ClipDistance[2] = iPosition.z - vClipLower.z;\n" + " gl_ClipDistance[3] = vClipUpper.x - iPosition.x;\n" + " gl_ClipDistance[4] = vClipUpper.y - iPosition.y;\n" + " gl_ClipDistance[5] = vClipUpper.z - iPosition.z;\n" + " }\n" "}\n"; if (vertexShaderMono_ == nullptr) { vertexShaderMono_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_mono); - assert(vertexShaderMono_->compileStatus()); + if (!vertexShaderMono_->compileStatus()) { + auto info = vertexShaderMono_->infoLog(); + assert(false && info.c_str()); + } } return vertexShaderMono_; -- Gitee From 07152ea7e8a28f2b1c63f11b4ed8a7371276bc1f Mon Sep 17 00:00:00 2001 From: koala999 Date: Sat, 24 Dec 2022 14:14:08 +0800 Subject: [PATCH 33/68] =?UTF-8?q?fix:=20=E4=B8=89=E7=BB=B4=E8=A3=81?= =?UTF-8?q?=E5=89=AA=E5=88=9D=E5=A7=8B=E7=8A=B6=E6=80=81=E4=B8=8D=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E5=AF=BC=E8=87=B4=E7=9A=84=E5=9D=90=E6=A0=87=E8=BD=B4?= =?UTF-8?q?=E6=B6=88=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 46 +++++++++++++++++++---------------- src/opengl/KcRenderObject.cpp | 7 +++--- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 3b14550..7d5c196 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -87,8 +87,7 @@ void KcImOglPaint::drawPoint(const point3& pt) auto ptSize = pointSize_; auto p = toNdc_(pt); - auto vp = viewport(); - auto drawFn = [clr, ptSize, p, vp, this]() { + auto drawFn = [clr, ptSize, p]() { glColor4f(clr.r(), clr.g(), clr.b(), clr.a()); glPointSize(ptSize); @@ -123,6 +122,10 @@ void KcImOglPaint::drawPoints(point_getter fn, unsigned count) obj->setColor(clr_); obj->setSize(pointSize_); obj->setProjMatrix(camera_.getMvpMat()); + if (curClipBox_ != -1) { + auto& box = clipBoxHistList_[curClipBox_]; + obj->setClipBox({ box.lower(), box.upper() }); + } currentRenderList().objs.emplace_back(obj); } @@ -133,11 +136,10 @@ void KcImOglPaint::drawLine(const point3& from, const point3& to) auto clr = clr_; auto lnWidth = lineWidth_; auto style = lineStyle_; - auto vp = viewport(); auto pt0 = toNdc_(from); auto pt1 = toNdc_(to); - auto drawFn = [clr, lnWidth, pt0, pt1, style, vp, this]() { + auto drawFn = [clr, lnWidth, pt0, pt1, style]() { glLineWidth(lnWidth); glColor4f(clr.r(), clr.g(), clr.b(), clr.a()); @@ -286,6 +288,7 @@ void KcImOglPaint::setViewport(const rect_t& vp) curViewport_ = std::distance(viewportHistList_.cbegin(), pos); } + assert(viewportHistList_[curViewport_] == vp); super_::setViewport(vp); } @@ -341,7 +344,12 @@ KcImOglPaint::KpRenderList_& KcImOglPaint::currentRenderList() void KcImOglPaint::drawRenderList_() { - unsigned viewport(-1), clipRect(-1), clipBox(-1); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + unsigned viewport(-1), clipRect(-1), clipBox(-2); for (auto& rd : renderList_) { auto& state = rd.first; if (std::get<0>(state) != viewport) { @@ -360,10 +368,6 @@ void KcImOglPaint::drawRenderList_() auto& rl = rd.second; KcGlslProgram::useProgram(0); // shaderʹù̶߻ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); for (auto& i : rl.fns) i(); @@ -377,23 +381,23 @@ void KcImOglPaint::drawRenderList_() void KcImOglPaint::glViewport_(unsigned id) { - if (id != -1) { - assert(id < viewportHistList_.size()); - auto& rc = viewportHistList_[id]; - auto y0 = ImGui::GetMainViewport()->Size.y - rc.upper().y(); - glViewport(rc.lower().x(), y0, rc.width(), rc.height()); - } + assert(id != -1); + + assert(id < viewportHistList_.size()); + auto& rc = viewportHistList_[id]; + auto y0 = ImGui::GetMainViewport()->Size.y - rc.upper().y(); + glViewport(rc.lower().x(), y0, rc.width(), rc.height()); } void KcImOglPaint::glScissor_(unsigned id) { - if (id != -1) { - assert(id < clipRectHistList_.size()); - auto& rc = clipRectHistList_[id]; - auto y0 = ImGui::GetMainViewport()->Size.y - rc.upper().y(); - glScissor(rc.lower().x(), y0, rc.width(), rc.height()); - } + assert(id != -1); + + assert(id < clipRectHistList_.size()); + auto& rc = clipRectHistList_[id]; + auto y0 = ImGui::GetMainViewport()->Size.y - rc.upper().y(); + glScissor(rc.lower().x(), y0, rc.width(), rc.height()); } diff --git a/src/opengl/KcRenderObject.cpp b/src/opengl/KcRenderObject.cpp index e7cb938..3368bd8 100644 --- a/src/opengl/KcRenderObject.cpp +++ b/src/opengl/KcRenderObject.cpp @@ -25,10 +25,12 @@ void KcRenderObject::draw() const vbo_->bind(); // vbo vtxDecl_->declare(); // vboݹ prog_->useProgram(); // shader - glUniformMatrix4fv(0, 1, GL_TRUE, projMat_.data()); + // shaderuniformֵ + auto loc = prog_->getUniformLocation("mvpMat"); + glUniformMatrix4fv(loc, 1, GL_TRUE, projMat_.data()); GLint enableClip = !clipBox_.isNull(); - auto loc = prog_->getUniformLocation("iEnableClip"); + loc = prog_->getUniformLocation("iEnableClip"); glUniform1i(loc, enableClip); if (enableClip) { loc = prog_->getUniformLocation("vClipLower"); @@ -37,6 +39,5 @@ void KcRenderObject::draw() const glUniform3f(loc, clipBox_.upper().x(), clipBox_.upper().y(), clipBox_.upper().z()); } - glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vtxDecl_->calcVertexSize()); } -- Gitee From 87c067a2b5549828fc622159152776872cb9bbc4 Mon Sep 17 00:00:00 2001 From: koala999 Date: Sun, 25 Dec 2022 21:25:42 +0800 Subject: [PATCH 34/68] =?UTF-8?q?try:=20=E8=BF=9B=E4=B8=80=E6=AD=A5?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1geometry=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataVis.vcxproj | 2 +- DataVis.vcxproj.filters | 2 +- src/opengl/KsShaderManager.cpp | 5 +- src/plot/KtGeometry.h | 31 +++----- src/plot/KuGeometryFactory.h | 97 ----------------------- src/plot/KuPrimitiveFactory.h | 139 +++++++++++++++++++++++++++++++++ 6 files changed, 155 insertions(+), 121 deletions(-) delete mode 100644 src/plot/KuGeometryFactory.h create mode 100644 src/plot/KuPrimitiveFactory.h diff --git a/DataVis.vcxproj b/DataVis.vcxproj index 3036948..ecdcf62 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -402,7 +402,7 @@ - + diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index 262c8a1..2839f8f 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -873,7 +873,7 @@ op - + plot diff --git a/src/opengl/KsShaderManager.cpp b/src/opengl/KsShaderManager.cpp index 89289bb..da8f006 100644 --- a/src/opengl/KsShaderManager.cpp +++ b/src/opengl/KsShaderManager.cpp @@ -43,10 +43,7 @@ KsShaderManager::shader_ptr KsShaderManager::vertexShaderMono() if (vertexShaderMono_ == nullptr) { vertexShaderMono_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_mono); - if (!vertexShaderMono_->compileStatus()) { - auto info = vertexShaderMono_->infoLog(); - assert(false && info.c_str()); - } + assert(vertexShaderMono_->compileStatus()); } return vertexShaderMono_; diff --git a/src/plot/KtGeometry.h b/src/plot/KtGeometry.h index d140731..d98cd75 100644 --- a/src/plot/KtGeometry.h +++ b/src/plot/KtGeometry.h @@ -1,32 +1,21 @@ #pragma once #include -#include "KtPoint.h" -template +template class KtGeometry { public: - using vertex_element_t = VTX_ELEMENT_TYPE; - using vertex_t = KtPoint; + using vertex_t = VTX_TYPE; using index_t = IDX_TYPE; - void reserve(unsigned vxtCount, unsigned idxCount) { vtx_.reserve(vxtCount), idx_.reserve(idxCount); } - void shrink_to_fit() { - vtx_.shrink_to_fit(), idx_.shrink_to_fit(); - } - - // ѹ붥㣬ض - void pushVertex(const vertex_t& pt) { - vtx_.push_back(pt); - } - - void pushVertex(vertex_element_t x, vertex_element_t y, vertex_element_t z) { - vtx_.emplace_back(x, y, z); + vertex_t* newVertex(unsigned extra) { + vtx_.resize(vtx_.size() + extra); + return vtx_.data() + vtx_.size() - extra; } unsigned vertexCount() const { @@ -46,8 +35,13 @@ public: } - void pushIndex(index_t idx) { - idx_.push_back(idx); + bool hasIndex() const { + return !idx.empty(); + } + + index_t* newIndex(unsigned extra) { + idx_.resize(idx_.size() + extra); + return idx_.data() + idx_.size() - extra; } unsigned indexCount() const { @@ -66,6 +60,7 @@ public: return idx_.data(); } + private: std::vector vtx_; std::vector idx_; diff --git a/src/plot/KuGeometryFactory.h b/src/plot/KuGeometryFactory.h deleted file mode 100644 index 23a6af7..0000000 --- a/src/plot/KuGeometryFactory.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once -#include -#include "KtGeometry.h" -#include "KtAABB.h" - - -class KuGeometryFactory -{ -public: - template - using geom_ptr = std::shared_ptr>; - - template - using point3 = KtPoint; - - - template - static geom_ptr makeBox(const KtAABB& aabb); - - template - static geom_ptr makeBox(const point3& lower, const point3& upper) { - return makeBox(KtAABB(lower, upper)); - } - - template - static geom_ptr makeBox() { - return makeBox({ 0, 0, 0 }, { 1, 1, 1 }); - } - -private: - KuGeometryFactory() = delete; -}; - - -template KuGeometryFactory::geom_ptr - KuGeometryFactory::makeBox(const KtAABB& aabb) -{ - auto corns = aabb.allCorners(); - - auto geom = std::make_shared>(); - geom->reserve(8, 36); - - - /* - 1-----2 - /| /| - / | / | - 5-----4 | - | 0--|--3 - | / | / - |/ |/ - 6-----7 - */ - - for(auto& i : corns) geom->pushVertex(i); - - if constexpr (CCW) { - geom->pushIndex(3); geom->pushIndex(0); geom->pushIndex(1); - geom->pushIndex(1); geom->pushIndex(2); geom->pushIndex(3); - - geom->pushIndex(7); geom->pushIndex(6); geom->pushIndex(0); - geom->pushIndex(0); geom->pushIndex(3); geom->pushIndex(7); - - geom->pushIndex(4); geom->pushIndex(5); geom->pushIndex(6); - geom->pushIndex(6); geom->pushIndex(7); geom->pushIndex(4); - - geom->pushIndex(2); geom->pushIndex(1); geom->pushIndex(5); - geom->pushIndex(5); geom->pushIndex(4); geom->pushIndex(2); - - geom->pushIndex(7); geom->pushIndex(3); geom->pushIndex(2); - geom->pushIndex(2); geom->pushIndex(4); geom->pushIndex(7); - - geom->pushIndex(0); geom->pushIndex(6); geom->pushIndex(5); - geom->pushIndex(5); geom->pushIndex(1); geom->pushIndex(0); - } - else { - geom->pushIndex(1); geom->pushIndex(0); geom->pushIndex(3); - geom->pushIndex(3); geom->pushIndex(2); geom->pushIndex(1); - - geom->pushIndex(0); geom->pushIndex(6); geom->pushIndex(7); - geom->pushIndex(7); geom->pushIndex(3); geom->pushIndex(0); - - geom->pushIndex(6); geom->pushIndex(5); geom->pushIndex(4); - geom->pushIndex(4); geom->pushIndex(7); geom->pushIndex(6); - - geom->pushIndex(5); geom->pushIndex(1); geom->pushIndex(2); - geom->pushIndex(2); geom->pushIndex(4); geom->pushIndex(5); - - geom->pushIndex(2); geom->pushIndex(3); geom->pushIndex(7); - geom->pushIndex(7); geom->pushIndex(4); geom->pushIndex(2); - - geom->pushIndex(5); geom->pushIndex(6); geom->pushIndex(0); - geom->pushIndex(0); geom->pushIndex(1); geom->pushIndex(5); - } - - return geom; -} diff --git a/src/plot/KuPrimitiveFactory.h b/src/plot/KuPrimitiveFactory.h new file mode 100644 index 0000000..dbd4ed6 --- /dev/null +++ b/src/plot/KuPrimitiveFactory.h @@ -0,0 +1,139 @@ +#pragma once +#include +#include "KtAABB.h" + + +// ɻ3d + +class KuPrimitiveFactory +{ +public: + using point3 = std::array; + + enum KeType + { + k_position, + k_normal, + k_texcoord, + + k_edge_index, + k_mesh_index + }; + + + template + static int makeBox(const point3& lower, const point3& upper, void* obuf, unsigned stride = 0); + + +private: + KuPrimitiveFactory() = delete; +}; + + +template +int KuPrimitiveFactory::makeBox(const point3& lower, const point3& upper, void* obuf, unsigned stride) +{ + /* + 1-----2 + /| /| + / | / | + 5-----4 | + | 0--|--3 + | / | / + |/ |/ + 6-----7 + */ + + if constexpr (CCW) { + static constexpr T MESH_IDX[] = { + 3, 0, 1, 1, 2, 3, + 7, 6, 0, 0, 3, 7, + 4, 5, 6, 6, 7, 4, + 2, 1, 5, 5, 4, 2, + 7, 3, 2, 2, 4, 7, + 0, 6, 5, 5, 1, 0 + }; + } + else { + static constexpr T MESH_IDX[] = { + 1, 0, 3, 3, 2, 1, + 0, 6, 7, 7, 3, 0, + 6, 5, 4, 4, 7, 6, + 5, 1, 2, 2, 4, 5, + 2, 3, 7, 7, 4, 2, + 5, 6, 0, 0, 1, 5 + }; + } + + static constexpr T EDGE_IDX[] = { + 0, 1, 1, 2, 2, 3, 3, 0, + 4, 5, 5, 6, 6, 7, 7, 4, + 1, 5, 2, 4, 0, 6, 3, 7 + }; + + if constexpr (TYPE == k_mesh_index) { + assert(stride == 0 || stride == sizeof(T)); + + if (obuf) + std::copy(std::cbegin(MESH_IDX), std::cend(MESH_IDX), (T*)obuf); + + return std::size(MESH_IDX); + } + else if constexpr (TYPE == k_edge_index) { + assert(stride == 0 || stride == sizeof(T)); + + if (obuf) + std::copy(std::cbegin(EDGE_IDX), std::cend(EDGE_IDX), (T*)obuf); + + return std::size(EDGE_IDX); + } + else { + if (obuf == nullptr) + return corns.size(); + + char* buf = (char*)obuf; + + if constexpr (type == k_position) { + auto aabb = KtAABB(lower, upper); + auto corns = aabb.allCorners(); + constexpr int point_size = sizeof(T) * 3; + assert(sizeof(corns[0]) == point_size); + + if (stride == 0) + stride = point_size; + + for (unsigned i = 0; i < corns.size(); i++) { + auto pt = (std::array*)buf; + *pt = corns[i]; + buf += stride; + } + } + else if constexpr (TYPE == k_normal) { + auto aabb = KtAABB(lower, upper); + auto corns = aabb.allCorners(); + constexpr int point_size = sizeof(T) * 3; + assert(sizeof(corns[0]) == point_size); + + if (stride == 0) + stride = point_size; + + static constexpr char diag[] = { + 4, 7, 6, 5, 0, 3, 2, 1 + }; + + for (unsigned i = 0; i < corns.size(); i++) { + auto pt = (std::array*)buf; + *pt = corns[i] - corns[diag[i]]; + buf += stride; + } + } + else if consteval (TYPE == k_texcoord) { + static_assert(false, "TODO"); + } + else { + static_assert(false, "unknown type"); + } + + return corns.size(); + } +} -- Gitee From 33f40c1b113fd1383c43ca92d0cd2cbbd62b40f2 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Mon, 26 Dec 2022 09:22:08 +0800 Subject: [PATCH 35/68] clean code --- DataVis.vcxproj | 35 +++---- DataVis.vcxproj.filters | 96 +++++++++++-------- src/3d/KePrimitiveType.h | 49 ++++++++++ src/{base => 3d}/KtAABB.h | 0 .../KtGeometry.h => 3d/KtGeometryImpl.h} | 18 +++- src/{base => 3d}/KtLine.h | 0 src/{base => 3d}/KtLineS2d.h | 0 src/{base => 3d}/KtMatrix3.h | 0 src/{base => 3d}/KtMatrix4.h | 0 src/{base => 3d}/KtPlane.h | 0 src/{base => 3d}/KtPoint.h | 0 src/{base => 3d}/KtProjector3d.h | 0 src/{base => 3d}/KtQuaternion.h | 0 src/{base => 3d}/KtTrackballController.h | 0 src/{base => 3d}/KtVector3.h | 0 src/{base => 3d}/KtVector4.h | 0 src/{plot => 3d}/KuPrimitiveFactory.h | 0 src/3d/KvGeometry.h | 19 ++++ src/imapp/KcImOglPaint.cpp | 2 +- src/opengl/KcLineObject.h | 2 +- src/opengl/KcRenderObject.h | 34 +------ src/opengl/KvVertexBuffer.h | 11 +++ src/plot/KcBars3d.cpp | 11 ++- 23 files changed, 180 insertions(+), 97 deletions(-) create mode 100644 src/3d/KePrimitiveType.h rename src/{base => 3d}/KtAABB.h (100%) rename src/{plot/KtGeometry.h => 3d/KtGeometryImpl.h} (69%) rename src/{base => 3d}/KtLine.h (100%) rename src/{base => 3d}/KtLineS2d.h (100%) rename src/{base => 3d}/KtMatrix3.h (100%) rename src/{base => 3d}/KtMatrix4.h (100%) rename src/{base => 3d}/KtPlane.h (100%) rename src/{base => 3d}/KtPoint.h (100%) rename src/{base => 3d}/KtProjector3d.h (100%) rename src/{base => 3d}/KtQuaternion.h (100%) rename src/{base => 3d}/KtTrackballController.h (100%) rename src/{base => 3d}/KtVector3.h (100%) rename src/{base => 3d}/KtVector4.h (100%) rename src/{plot => 3d}/KuPrimitiveFactory.h (100%) create mode 100644 src/3d/KvGeometry.h create mode 100644 src/opengl/KvVertexBuffer.h diff --git a/DataVis.vcxproj b/DataVis.vcxproj index ecdcf62..6e26cab 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -52,7 +52,7 @@ /Zc:__cplusplus %(AdditionalOptions) stdcpp17 - $(SolutionDir)3rdparty/stb;$(SolutionDir)3rdparty/imgui;$(SolutionDir)3rdparty/glfw;$(SolutionDir)3rdparty/ImGuizmo;$(SolutionDir)3rdparty/glad;$(SolutionDir)3rdparty;$(SolutionDir)src;$(SolutionDir)src/base;$(SolutionDir)src/dsp;$(SolutionDir)src/audio;$(SolutionDir)src/imapp;%(AdditionalIncludeDirectories) + $(SolutionDir)3rdparty/stb;$(SolutionDir)3rdparty/imgui;$(SolutionDir)3rdparty/glfw;$(SolutionDir)3rdparty/ImGuizmo;$(SolutionDir)3rdparty/glad;$(SolutionDir)3rdparty;$(SolutionDir)src;$(SolutionDir)src/base;$(SolutionDir)src/dsp;$(SolutionDir)src/audio;$(SolutionDir)src/imapp;$(SolutionDir)src/3d;%(AdditionalIncludeDirectories) 4819;4828 %(PreprocessorDefinitions) @@ -67,7 +67,7 @@ /Zc:__cplusplus %(AdditionalOptions) stdcpp17 - $(SolutionDir)3rdparty/stb;$(SolutionDir)3rdparty/imgui;$(SolutionDir)3rdparty/glfw;$(SolutionDir)3rdparty/ImGuizmo;$(SolutionDir)3rdparty/glad;$(SolutionDir)3rdparty;$(SolutionDir)src;$(SolutionDir)src/base;$(SolutionDir)src/dsp;$(SolutionDir)src/audio;$(SolutionDir)src/imapp;%(AdditionalIncludeDirectories) + $(SolutionDir)3rdparty/stb;$(SolutionDir)3rdparty/imgui;$(SolutionDir)3rdparty/glfw;$(SolutionDir)3rdparty/ImGuizmo;$(SolutionDir)3rdparty/glad;$(SolutionDir)3rdparty;$(SolutionDir)src;$(SolutionDir)src/base;$(SolutionDir)src/dsp;$(SolutionDir)src/audio;$(SolutionDir)src/imapp;$(SolutionDir)src/3d;%(AdditionalIncludeDirectories) 4819;4828 %(PreprocessorDefinitions) @@ -256,29 +256,33 @@ + + + + + + + + + + + + + + + + - - - - - - - - - - - - @@ -370,6 +374,7 @@ + @@ -395,14 +400,12 @@ - - diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index 2839f8f..654043f 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -43,6 +43,9 @@ {6c8e049e-5599-45c4-9e5a-62bc4d398592} + + {666b7f16-b2fc-4731-b7b5-a079c519e0b6} + @@ -546,12 +549,6 @@ plot - - base - - - base - plot @@ -564,18 +561,9 @@ dsp - - base - - - base - plot - - base - 3rdparty\imgui @@ -684,30 +672,15 @@ prov - - base - - - base - base - - base - - - base - imapp plot - - base - imapp @@ -762,9 +735,6 @@ plot - - base - plot @@ -864,21 +834,12 @@ op - - base - dsp op - - plot - - - plot - dsp @@ -1029,5 +990,56 @@ opengl + + opengl + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + + + 3d + \ No newline at end of file diff --git a/src/3d/KePrimitiveType.h b/src/3d/KePrimitiveType.h new file mode 100644 index 0000000..6de48c4 --- /dev/null +++ b/src/3d/KePrimitiveType.h @@ -0,0 +1,49 @@ +#pragma once + + +enum KePrimitiveType +{ + // Draws a point at each of the n vertices + k_points, + + // Draws a series of unconnected line segments. Segments are drawn between v0 and v1, + // between v2 and v3, and so on.If n is odd, the last segment is drawn between vnC3and vnC2, and vnC1 is ignored. + k_lines, + + // Draws a line segment from v0 to v1, then from v1 to v2, and so on, finally drawing the segment + // from vnC2 to vnC1.Thus, a total of nC1 line segments are drawn.Nothing is drawn unless n + // is larger than 1. There are no restrictions on the vertices describing a line strip(or a line loop); the lines can intersect arbitrarily. + k_line_strip, + + // Same as k_line_strip, except that a final line segment is drawn from vnC1 to v0, completing a loop. + k_line_loop, + + // Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v3, v4, v5, and so on. + // If n isnt a multiple of 3, the final one or two vertices are ignored + k_triangles, + + // Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v2, v1, v3(note the order), then v2, v3, v4, and so on. + // The ordering is to ensure that the triangles are all drawn with the same orientation so that + // the strip can correctly form part of a surface. + // Preserving the orientation is important for some operations, such as culling. + // n must be at least 3 for anything to be drawn. + k_triangle_strip, + + // Same as k_triangle_strip, except that the vertices are v0, v1, v2, then v0, v2, v3, then v0, v3, v4, and so on + k_triangle_fan, + + // Draws a series of quadrilaterals (four-sided polygons) using vertices v0, v1, v2, v3, + // then v4, v5, v6, v7, and so on.If n isnt a multiple of 4, the final one, two, or three vertices are ignored. + k_quads, + + // Draws a series of quadrilaterals (four-sided polygons) beginning with v0, v1, v3, v2, + // then v2, v3, v5, v4, then v4, v5, v7, v6, and so on + // n must be at least 4 before anything is drawn.If n is odd, the final vertex is ignored. + k_quad_strip, + + // Draws a polygon using the points v0, ... , vnC1 as vertices. + // n must be at least 3, or nothing is drawn.In addition, the polygon specified must + // not intersect itselfand must be convex. If the vertices dont satisfy these conditions, the + // results are unpredictable. + k_polygon +}; \ No newline at end of file diff --git a/src/base/KtAABB.h b/src/3d/KtAABB.h similarity index 100% rename from src/base/KtAABB.h rename to src/3d/KtAABB.h diff --git a/src/plot/KtGeometry.h b/src/3d/KtGeometryImpl.h similarity index 69% rename from src/plot/KtGeometry.h rename to src/3d/KtGeometryImpl.h index d98cd75..cdddf47 100644 --- a/src/plot/KtGeometry.h +++ b/src/3d/KtGeometryImpl.h @@ -1,14 +1,17 @@ #pragma once #include +#include "KvGeometry.h" template -class KtGeometry +class KtGeometryImpl : public KvGeometry { public: using vertex_t = VTX_TYPE; using index_t = IDX_TYPE; + KtGeometryImpl(KePrimitiveType type) : type_(type) {} + void reserve(unsigned vxtCount, unsigned idxCount) { vtx_.reserve(vxtCount), idx_.reserve(idxCount); } @@ -18,7 +21,7 @@ public: return vtx_.data() + vtx_.size() - extra; } - unsigned vertexCount() const { + unsigned vertexCount() const override { return vtx_.size(); } @@ -26,7 +29,7 @@ public: return vtx_.at(idx); } - const vertex_t* vertexBuffer() const { + void* vertexBuffer() const override { return vtx_.data(); } @@ -44,7 +47,7 @@ public: return idx_.data() + idx_.size() - extra; } - unsigned indexCount() const { + unsigned indexCount() const override { return idx_.size(); } @@ -52,7 +55,7 @@ public: return idx_.at(idx); } - index_t* indexBuffer() const { + void* indexBuffer() const override { return idx_.data(); } @@ -61,7 +64,12 @@ public: } + KePrimitiveType type() const override { returnt type_; } + + unsigned indexSize() const override { return sizeof(index_t); } + private: + KePrimitiveType type_; std::vector vtx_; std::vector idx_; }; diff --git a/src/base/KtLine.h b/src/3d/KtLine.h similarity index 100% rename from src/base/KtLine.h rename to src/3d/KtLine.h diff --git a/src/base/KtLineS2d.h b/src/3d/KtLineS2d.h similarity index 100% rename from src/base/KtLineS2d.h rename to src/3d/KtLineS2d.h diff --git a/src/base/KtMatrix3.h b/src/3d/KtMatrix3.h similarity index 100% rename from src/base/KtMatrix3.h rename to src/3d/KtMatrix3.h diff --git a/src/base/KtMatrix4.h b/src/3d/KtMatrix4.h similarity index 100% rename from src/base/KtMatrix4.h rename to src/3d/KtMatrix4.h diff --git a/src/base/KtPlane.h b/src/3d/KtPlane.h similarity index 100% rename from src/base/KtPlane.h rename to src/3d/KtPlane.h diff --git a/src/base/KtPoint.h b/src/3d/KtPoint.h similarity index 100% rename from src/base/KtPoint.h rename to src/3d/KtPoint.h diff --git a/src/base/KtProjector3d.h b/src/3d/KtProjector3d.h similarity index 100% rename from src/base/KtProjector3d.h rename to src/3d/KtProjector3d.h diff --git a/src/base/KtQuaternion.h b/src/3d/KtQuaternion.h similarity index 100% rename from src/base/KtQuaternion.h rename to src/3d/KtQuaternion.h diff --git a/src/base/KtTrackballController.h b/src/3d/KtTrackballController.h similarity index 100% rename from src/base/KtTrackballController.h rename to src/3d/KtTrackballController.h diff --git a/src/base/KtVector3.h b/src/3d/KtVector3.h similarity index 100% rename from src/base/KtVector3.h rename to src/3d/KtVector3.h diff --git a/src/base/KtVector4.h b/src/3d/KtVector4.h similarity index 100% rename from src/base/KtVector4.h rename to src/3d/KtVector4.h diff --git a/src/plot/KuPrimitiveFactory.h b/src/3d/KuPrimitiveFactory.h similarity index 100% rename from src/plot/KuPrimitiveFactory.h rename to src/3d/KuPrimitiveFactory.h diff --git a/src/3d/KvGeometry.h b/src/3d/KvGeometry.h new file mode 100644 index 0000000..9146812 --- /dev/null +++ b/src/3d/KvGeometry.h @@ -0,0 +1,19 @@ +#pragma once +#include "KePrimitiveType.h" + + +class KvGeometry +{ +public: + + virtual KePrimitiveType type() const = 0; + + virtual unsigned vertexCount() const = 0; + virtual void* vertexBuffer() const = 0; + + virtual unsigned indexCount() const = 0; + virtual void* indexBuffer() const = 0; + + // ÿֵֽڳߴ + virtual unsigned indexSize() const = 0; +}; diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 7d5c196..cfd98a7 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -258,7 +258,7 @@ void KcImOglPaint::drawText(const point3& topLeft, const point3& hDir, const poi void KcImOglPaint::pushTextVbo_(KpRenderList_& rl) { if (!rl.texts.empty()) { - auto obj = new KcRenderObject(KcRenderObject::k_quads, + auto obj = new KcRenderObject(k_quads, KsShaderManager::singleton().programColorUV()); auto decl = std::make_shared(); diff --git a/src/opengl/KcLineObject.h b/src/opengl/KcLineObject.h index df63a7f..beccb1d 100644 --- a/src/opengl/KcLineObject.h +++ b/src/opengl/KcLineObject.h @@ -10,7 +10,7 @@ class KcLineObject : public KcRenderObject public: - KcLineObject(KeType type = k_line_strip); + KcLineObject(KePrimitiveType type = k_line_strip); void setColor(const float4& clr) { lineColor_ = clr; diff --git a/src/opengl/KcRenderObject.h b/src/opengl/KcRenderObject.h index 46a78fa..04f2672 100644 --- a/src/opengl/KcRenderObject.h +++ b/src/opengl/KcRenderObject.h @@ -2,6 +2,7 @@ #include #include "KtMatrix4.h" #include "KtAABB.h" +#include "3d/KePrimitiveType.h" class KcGpuBuffer; class KcGlslProgram; @@ -16,36 +17,7 @@ public: using aabb_t = KtAABB; - enum KeType - { - k_points, // Draws a point at each of the n vertices - k_lines, // Draws a series of unconnected line segments. Segments are drawn between v0 and v1, - // between v2 and v3, and so on.If n is odd, the last segment is drawn between vnC3and vnC2, and vnC1 is ignored. - k_line_strip, // Draws a line segment from v0 to v1, then from v1 to v2, and so on, finally drawing the segment - // from vnC2 to vnC1.Thus, a total of nC1 line segments are drawn.Nothing is drawn unless n - // is larger than 1. There are no restrictions on the vertices describing a line strip(or a line loop); the lines can intersect arbitrarily. - k_line_loop, // Same as k_line_strip, except that a final line segment is drawn from vnC1 to v0, completing a loop. - k_triangles, // Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v3, v4, v5, and so on. - // If n isnt a multiple of 3, the final one or two vertices are ignored - k_triangle_strip, // Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v2, v1, v3(note the order), then v2, v3, v4, and so on. - // The ordering is to ensure that the triangles are all drawn with the same orientation so that - // the strip can correctly form part of a surface. - // Preserving the orientation is important for some operations, such as culling. - // n must be at least 3 for anything to be drawn. - k_triangle_fan, // Same as k_triangle_strip, except that the vertices are v0, v1, v2, then v0, v2, v3, then v0, v3, v4, and so on - k_quads, // Draws a series of quadrilaterals (four-sided polygons) using vertices v0, v1, v2, v3, - // then v4, v5, v6, v7, and so on.If n isnt a multiple of 4, the final one, two, or three vertices are ignored. - k_quad_strip, // Draws a series of quadrilaterals (four-sided polygons) beginning with v0, v1, v3, v2, - // then v2, v3, v5, v4, then v4, v5, v7, v6, and so on - // n must be at least 4 before anything is drawn.If n is odd, the final vertex is ignored. - k_polygon // Draws a polygon using the points v0, ... , vnC1 as vertices. - // n must be at least 3, or nothing is drawn.In addition, the polygon specified must - // not intersect itselfand must be convex. If the vertices dont satisfy these conditions, the - // results are unpredictable. - }; - - - KcRenderObject(KeType type, std::shared_ptr prog) + KcRenderObject(KePrimitiveType type, std::shared_ptr prog) : type_(type), prog_(prog) {} KcRenderObject(const KcRenderObject& rhs) @@ -66,7 +38,7 @@ public: virtual void draw() const; protected: - KeType type_; + KePrimitiveType type_; std::shared_ptr prog_; std::shared_ptr vbo_; std::shared_ptr vtxDecl_; diff --git a/src/opengl/KvVertexBuffer.h b/src/opengl/KvVertexBuffer.h new file mode 100644 index 0000000..7df539c --- /dev/null +++ b/src/opengl/KvVertexBuffer.h @@ -0,0 +1,11 @@ +#pragma once + + +// VBOij + +class KvVertexBuffer +{ +public: + + virtual void bind() const = 0; +}; diff --git a/src/plot/KcBars3d.cpp b/src/plot/KcBars3d.cpp index 6b3b46b..5480d52 100644 --- a/src/plot/KcBars3d.cpp +++ b/src/plot/KcBars3d.cpp @@ -1,5 +1,6 @@ #include "KcBars3d.h" -#include "KuGeometryFactory.h" +#include "KuPrimitiveFactory.h" +#include "KtGeometryImpl.h" #include "KvData.h" @@ -22,6 +23,14 @@ void KcBars3d::drawImpl_(KvPaint* paint, point_getter getter, unsigned count, un bool drawFill = fill_.style != KpBrush::k_none && majorColor(0).a() != 0; bool drawBorder = border_.style != KpPen::k_none && minorColor().a() != 0 && minorColor() != majorColor(0); + struct KpVtxBuffer_ + { + point3f pos; + point3f normal; + }; + + auto gemo = std::make_shared>(k_triangles); + for (unsigned i = 0; i < count; i++) { auto pt0 = getter(i); point3 pt1; -- Gitee From ab405cec80c7e962fb9ec7a8ea3a70df5c85f426 Mon Sep 17 00:00:00 2001 From: koala999 Date: Mon, 26 Dec 2022 20:37:59 +0800 Subject: [PATCH 36/68] =?UTF-8?q?add:=20=E4=BD=BF=E7=94=A8ogl=E7=BB=98?= =?UTF-8?q?=E5=88=B6mesh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DataVis.vcxproj | 10 ++- DataVis.vcxproj.filters | 30 +++++--- src/{opengl => 3d}/KcVertexAttribute.cpp | 0 src/{opengl => 3d}/KcVertexAttribute.h | 0 src/{opengl => 3d}/KcVertexDeclaration.cpp | 19 ++++- src/{opengl => 3d}/KcVertexDeclaration.h | 4 +- src/3d/KtGeometryImpl.h | 16 ++-- src/3d/KuPrimitiveFactory.h | 29 ++++--- src/3d/KvGeometry.h | 8 +- src/imapp/KcImOglPaint.cpp | 51 +++++++++++-- src/imapp/KcImOglPaint.h | 3 + src/imapp/KcImPaint.cpp | 6 +- src/imapp/KcImPaint.h | 2 +- src/opengl/KcGlslShader.cpp | 2 +- src/opengl/KcGpuBuffer.cpp | 88 +++++++++++++++------- src/opengl/KcGpuBuffer.h | 18 ++++- src/opengl/KcLightenObject.cpp | 25 ++++++ src/opengl/KcLightenObject.h | 24 ++++++ src/opengl/KcLineObject.cpp | 10 +-- src/opengl/KcLineObject.h | 5 -- src/opengl/KcPointObject.cpp | 9 +-- src/opengl/KcPointObject.h | 5 -- src/opengl/KcRenderObject.cpp | 31 ++++++-- src/opengl/KcRenderObject.h | 24 ++++-- src/opengl/KsShaderManager.cpp | 68 +++++++++++++++-- src/opengl/KsShaderManager.h | 11 ++- src/plot/KcBars3d.cpp | 37 ++++++--- src/plot/KvPaint.h | 8 +- 28 files changed, 400 insertions(+), 143 deletions(-) rename src/{opengl => 3d}/KcVertexAttribute.cpp (100%) rename src/{opengl => 3d}/KcVertexAttribute.h (100%) rename src/{opengl => 3d}/KcVertexDeclaration.cpp (79%) rename src/{opengl => 3d}/KcVertexDeclaration.h (91%) create mode 100644 src/opengl/KcLightenObject.cpp create mode 100644 src/opengl/KcLightenObject.h diff --git a/DataVis.vcxproj b/DataVis.vcxproj index 6e26cab..e22c9f1 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -114,6 +114,8 @@ + + @@ -181,11 +183,10 @@ + - - @@ -256,6 +257,8 @@ + + @@ -368,11 +371,10 @@ + - - diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index 654043f..0a63ffa 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -439,12 +439,6 @@ opengl - - opengl - - - opengl - opengl @@ -457,6 +451,15 @@ opengl + + 3d + + + 3d + + + opengl + @@ -972,12 +975,6 @@ opengl - - opengl - - - opengl - opengl @@ -1041,5 +1038,14 @@ 3d + + 3d + + + 3d + + + opengl + \ No newline at end of file diff --git a/src/opengl/KcVertexAttribute.cpp b/src/3d/KcVertexAttribute.cpp similarity index 100% rename from src/opengl/KcVertexAttribute.cpp rename to src/3d/KcVertexAttribute.cpp diff --git a/src/opengl/KcVertexAttribute.h b/src/3d/KcVertexAttribute.h similarity index 100% rename from src/opengl/KcVertexAttribute.h rename to src/3d/KcVertexAttribute.h diff --git a/src/opengl/KcVertexDeclaration.cpp b/src/3d/KcVertexDeclaration.cpp similarity index 79% rename from src/opengl/KcVertexDeclaration.cpp rename to src/3d/KcVertexDeclaration.cpp index e1e7db7..65d6b74 100644 --- a/src/opengl/KcVertexDeclaration.cpp +++ b/src/3d/KcVertexDeclaration.cpp @@ -5,7 +5,7 @@ void KcVertexDeclaration::pushAttribute(KcVertexAttribute::KeFormat fmt, KcVertexAttribute::KeSemantic semantic, unsigned semanticIndex) { - pushAttribute(KcVertexAttribute(attributeCount(), fmt, calcVertexSize(), + pushAttribute(KcVertexAttribute(attributeCount(), fmt, vertexSize(), semantic, semanticIndex)); // TODO: semanticIndexҲ } @@ -22,7 +22,7 @@ const KcVertexAttribute* KcVertexDeclaration::findAttribute(KcVertexAttribute::K } -unsigned KcVertexDeclaration::calcVertexSize() const +unsigned KcVertexDeclaration::vertexSize() const { unsigned s(0); for (unsigned i = 0; i < attributeCount(); i++) @@ -54,6 +54,17 @@ bool KcVertexDeclaration::hasColor() const } +bool KcVertexDeclaration::hasNormal() const +{ + for (unsigned i = 0; i < attributeCount(); i++) { + if (getAttribute(i).semantic() == KcVertexAttribute::k_normal) + return true; + } + + return false; +} + + unsigned KcVertexDeclaration::texCoordCount() const { unsigned c(0); @@ -68,7 +79,7 @@ unsigned KcVertexDeclaration::texCoordCount() const void KcVertexDeclaration::declare() const { - auto stride = calcVertexSize(); // Ҫһϲŷ֡TODOһŻÿζ + auto stride = vertexSize(); // Ҫһϲŷ֡TODOһŻÿζ for (unsigned i = 0; i < attributeCount(); i++) { auto& attr = getAttribute(i); @@ -85,6 +96,6 @@ void KcVertexDeclaration::declare() const } glVertexAttribPointer(attr.location(), attr.componentCount(), type, - attr.normalized() ? GL_TRUE : GL_FALSE, stride, (void*)attr.offset()); + attr.normalized() ? GL_TRUE : GL_FALSE, stride, ((char*)0) + attr.offset()); } } diff --git a/src/opengl/KcVertexDeclaration.h b/src/3d/KcVertexDeclaration.h similarity index 91% rename from src/opengl/KcVertexDeclaration.h rename to src/3d/KcVertexDeclaration.h index 9155c7c..22c1efe 100644 --- a/src/opengl/KcVertexDeclaration.h +++ b/src/3d/KcVertexDeclaration.h @@ -22,13 +22,15 @@ public: unsigned attributeCount() const { return attrs_.size(); } - unsigned calcVertexSize() const; // 벼ռֽڵĴС + unsigned vertexSize() const; // 벼ռֽڵĴС bool hasSemantic(KcVertexAttribute::KeSemantic semantic) const; // ԪǷɫֵ bool hasColor() const; + bool hasNormal() const; + // ԪԪصĿ unsigned texCoordCount() const; diff --git a/src/3d/KtGeometryImpl.h b/src/3d/KtGeometryImpl.h index cdddf47..93ad02a 100644 --- a/src/3d/KtGeometryImpl.h +++ b/src/3d/KtGeometryImpl.h @@ -29,11 +29,11 @@ public: return vtx_.at(idx); } - void* vertexBuffer() const override { - return vtx_.data(); + void* vertexData() const override { + return const_cast(vtx_.data()); } - vertex_t* vertexBuffer() { + vertex_t* vertexData() { return vtx_.data(); } @@ -55,16 +55,18 @@ public: return idx_.at(idx); } - void* indexBuffer() const override { - return idx_.data(); + void* indexData() const override { + return const_cast(idx_.data()); } - index_t* indexBuffer() { + index_t* indexData() { return idx_.data(); } - KePrimitiveType type() const override { returnt type_; } + KePrimitiveType type() const override { return type_; } + + unsigned vertexSize() const override { return sizeof(vertex_t); } unsigned indexSize() const override { return sizeof(index_t); } diff --git a/src/3d/KuPrimitiveFactory.h b/src/3d/KuPrimitiveFactory.h index dbd4ed6..9e0f624 100644 --- a/src/3d/KuPrimitiveFactory.h +++ b/src/3d/KuPrimitiveFactory.h @@ -8,6 +8,7 @@ class KuPrimitiveFactory { public: + using point3 = std::array; enum KeType @@ -21,7 +22,7 @@ public: }; - template + template static int makeBox(const point3& lower, const point3& upper, void* obuf, unsigned stride = 0); @@ -44,8 +45,10 @@ int KuPrimitiveFactory::makeBox(const point3& lower, const point3& upper, void* 6-----7 */ + const T* MESH_IDX; + if constexpr (CCW) { - static constexpr T MESH_IDX[] = { + static constexpr T MESH_IDX_[] = { 3, 0, 1, 1, 2, 3, 7, 6, 0, 0, 3, 7, 4, 5, 6, 6, 7, 4, @@ -53,9 +56,10 @@ int KuPrimitiveFactory::makeBox(const point3& lower, const point3& upper, void* 7, 3, 2, 2, 4, 7, 0, 6, 5, 5, 1, 0 }; + MESH_IDX = MESH_IDX_; } else { - static constexpr T MESH_IDX[] = { + static constexpr T MESH_IDX_[] = { 1, 0, 3, 3, 2, 1, 0, 6, 7, 7, 3, 0, 6, 5, 4, 4, 7, 6, @@ -63,6 +67,7 @@ int KuPrimitiveFactory::makeBox(const point3& lower, const point3& upper, void* 2, 3, 7, 7, 4, 2, 5, 6, 0, 0, 1, 5 }; + MESH_IDX = MESH_IDX_; } static constexpr T EDGE_IDX[] = { @@ -75,9 +80,9 @@ int KuPrimitiveFactory::makeBox(const point3& lower, const point3& upper, void* assert(stride == 0 || stride == sizeof(T)); if (obuf) - std::copy(std::cbegin(MESH_IDX), std::cend(MESH_IDX), (T*)obuf); + std::copy(MESH_IDX, MESH_IDX + 36, (T*)obuf); - return std::size(MESH_IDX); + return 36; } else if constexpr (TYPE == k_edge_index) { assert(stride == 0 || stride == sizeof(T)); @@ -89,12 +94,13 @@ int KuPrimitiveFactory::makeBox(const point3& lower, const point3& upper, void* } else { if (obuf == nullptr) - return corns.size(); + return 8; char* buf = (char*)obuf; - if constexpr (type == k_position) { - auto aabb = KtAABB(lower, upper); + if constexpr (TYPE == k_position) { + auto aabb = KtAABB(KtPoint(lower[0], lower[1], lower[2]), + KtPoint(upper[0], upper[1], upper[2])); auto corns = aabb.allCorners(); constexpr int point_size = sizeof(T) * 3; assert(sizeof(corns[0]) == point_size); @@ -109,7 +115,8 @@ int KuPrimitiveFactory::makeBox(const point3& lower, const point3& upper, void* } } else if constexpr (TYPE == k_normal) { - auto aabb = KtAABB(lower, upper); + auto aabb = KtAABB(KtPoint(lower[0], lower[1], lower[2]), + KtPoint(upper[0], upper[1], upper[2])); auto corns = aabb.allCorners(); constexpr int point_size = sizeof(T) * 3; assert(sizeof(corns[0]) == point_size); @@ -127,13 +134,13 @@ int KuPrimitiveFactory::makeBox(const point3& lower, const point3& upper, void* buf += stride; } } - else if consteval (TYPE == k_texcoord) { + else if constexpr (TYPE == k_texcoord) { static_assert(false, "TODO"); } else { static_assert(false, "unknown type"); } - return corns.size(); + return 8; } } diff --git a/src/3d/KvGeometry.h b/src/3d/KvGeometry.h index 9146812..d090e38 100644 --- a/src/3d/KvGeometry.h +++ b/src/3d/KvGeometry.h @@ -9,10 +9,14 @@ public: virtual KePrimitiveType type() const = 0; virtual unsigned vertexCount() const = 0; - virtual void* vertexBuffer() const = 0; + virtual void* vertexData() const = 0; + + // ÿݵֽڳߴ + virtual unsigned vertexSize() const = 0; + virtual unsigned indexCount() const = 0; - virtual void* indexBuffer() const = 0; + virtual void* indexData() const = 0; // ÿֵֽڳߴ virtual unsigned indexSize() const = 0; diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index cfd98a7..8173fd8 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -2,12 +2,13 @@ #include "imgui.h" #include "imgui_internal.h" #include "glad.h" +#include "KcVertexDeclaration.h" #include "opengl/KcGlslProgram.h" #include "opengl/KcGlslShader.h" #include "opengl/KcGpuBuffer.h" -#include "opengl/KcVertexDeclaration.h" #include "opengl/KcPointObject.h" #include "opengl/KcLineObject.h" +#include "opengl/KcLightenObject.h" #include "opengl/KsShaderManager.h" @@ -118,7 +119,7 @@ void KcImOglPaint::drawPoints(point_getter fn, unsigned count) vtx.push_back(fn(i)); vbo->setData(vtx.data(), vtx.size() * sizeof(point3f), KcGpuBuffer::k_stream_draw); - obj->setVbo(vbo, decl); + obj->setVBO(vbo, decl); obj->setColor(clr_); obj->setSize(pointSize_); obj->setProjMatrix(camera_.getMvpMat()); @@ -157,7 +158,7 @@ void KcImOglPaint::drawLine(const point3& from, const point3& to) void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) { - auto obj = new KcLineObject(KcRenderObject::k_line_strip); + auto obj = new KcLineObject(k_line_strip); auto decl = std::make_shared(); decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); @@ -168,7 +169,7 @@ void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) vtx.push_back(fn(i)); vbo->setData(vtx.data(), vtx.size() * sizeof(point3f), KcGpuBuffer::k_stream_draw); - obj->setVbo(vbo, decl); + obj->setVBO(vbo, decl); obj->setColor(clr_); obj->setWidth(lineWidth_); obj->setProjMatrix(camera_.getMvpMat()); @@ -258,25 +259,59 @@ void KcImOglPaint::drawText(const point3& topLeft, const point3& hDir, const poi void KcImOglPaint::pushTextVbo_(KpRenderList_& rl) { if (!rl.texts.empty()) { - auto obj = new KcRenderObject(k_quads, - KsShaderManager::singleton().programColorUV()); + auto obj = new KcRenderObject(k_quads); + obj->setShader(KsShaderManager::singleton().programColorUV()); auto decl = std::make_shared(); decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); decl->pushAttribute(KcVertexAttribute::k_float2, KcVertexAttribute::k_texcoord); decl->pushAttribute(KcVertexAttribute::k_float4, KcVertexAttribute::k_diffuse); - assert(decl->calcVertexSize() == sizeof(rl.texts[0])); + assert(decl->vertexSize() == sizeof(rl.texts[0])); auto vbo = std::make_shared(); vbo->setData(rl.texts.data(), rl.texts.size() * sizeof(rl.texts[0]), KcGpuBuffer::k_stream_draw); - obj->setVbo(vbo, decl); + obj->setVBO(vbo, decl); obj->setProjMatrix(float4x4<>::identity()); rl.objs.emplace_back(obj); } } +void KcImOglPaint::drawGeom(vtx_decl_ptr decl, geom_ptr geom) +{ + assert(geom->vertexSize() == decl->vertexSize()); + + bool hasNormal = decl->hasNormal(); + + KcRenderObject* obj = hasNormal ? new KcLightenObject(geom->type()) : new KcRenderObject(geom->type()); + + if (hasNormal) { + //((KcLightenObject*)obj)->setNormalMatrix(camera_.getNormalMatrix()); + ((KcLightenObject*)obj)->setNormalMatrix(mat4::identity()); + } + + auto vbo = std::make_shared(); + vbo->setData(geom->vertexData(), geom->vertexCount() * geom->vertexSize(), KcGpuBuffer::k_stream_draw); + + obj->setVBO(vbo, decl); + if (geom->indexCount() > 0) { + auto ibo = std::make_shared(KcGpuBuffer::k_index_buffer); + ibo->setData(geom->indexData(), geom->indexCount() * geom->indexSize(), KcGpuBuffer::k_stream_draw); + obj->setIBO(ibo, geom->indexCount()); + } + + obj->setColor(clr_); + obj->setProjMatrix(camera_.getMvpMat()); + if (curClipBox_ != -1) { + auto& box = clipBoxHistList_[curClipBox_]; + obj->setClipBox({ box.lower(), box.upper() }); + } + + currentRenderList().objs.emplace_back(obj); +} + + void KcImOglPaint::setViewport(const rect_t& vp) { auto pos = std::find(viewportHistList_.cbegin(), viewportHistList_.cend(), vp); diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index c6361f5..aaf9afe 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -47,6 +47,9 @@ public: void drawText(const point3& topLeft, const point3& hDir, const point3& vDir, const char* text) override; + void drawGeom(vtx_decl_ptr decl, geom_ptr geom) override; + + // ڲImGuiصԻrenderList_Ⱦ void drawRenderList_(); diff --git a/src/imapp/KcImPaint.cpp b/src/imapp/KcImPaint.cpp index 1ef58ea..235d8c4 100644 --- a/src/imapp/KcImPaint.cpp +++ b/src/imapp/KcImPaint.cpp @@ -323,8 +323,8 @@ void KcImPaint::fillBetween(point_getter fn1, point_getter fn2, unsigned count) drawList->PrimUnreserve(0, noninters); } - -void KcImPaint::drawGeom(geom_ptr geom) +#if 0 +void KcImPaint::drawGeom(vtx_decl_ptr decl, geom_ptr geom) { auto drawList = ImGui::GetWindowDrawList(); drawList->PrimReserve(geom->indexCount(), geom->vertexCount()); @@ -341,7 +341,7 @@ void KcImPaint::drawGeom(geom_ptr geom) for (unsigned i = 0; i < geom->indexCount(); i++) drawList->PrimWriteIdx(geom->indexAt(i) + vtxIdx0); } - +#endif void KcImPaint::drawText(const point3& anchor, const char* text, int align) { diff --git a/src/imapp/KcImPaint.h b/src/imapp/KcImPaint.h index 86b1fac..849a655 100644 --- a/src/imapp/KcImPaint.h +++ b/src/imapp/KcImPaint.h @@ -63,7 +63,7 @@ public: void drawText(const point3& anchor, const char* text, int align) override; - void drawGeom(geom_ptr geom) override; + //void drawGeom(vtx_decl_ptr decl, geom_ptr geom) override; point2 textSize(const char* text) const override; diff --git a/src/opengl/KcGlslShader.cpp b/src/opengl/KcGlslShader.cpp index c421da4..c681b19 100644 --- a/src/opengl/KcGlslShader.cpp +++ b/src/opengl/KcGlslShader.cpp @@ -7,7 +7,7 @@ KcGlslShader::KcGlslShader(KeType type, const std::string_view& path_or_source) : type_(type) { - if (KuPathUtil::exist(path_or_source)) { + if (KuPathUtil::isLegalFileName(path_or_source.data()) && KuPathUtil::exist(path_or_source)) { path_ = path_or_source; source_ = KuFileUtil::readAsString(path_); } diff --git a/src/opengl/KcGpuBuffer.cpp b/src/opengl/KcGpuBuffer.cpp index 2761e34..c5fa4fe 100644 --- a/src/opengl/KcGpuBuffer.cpp +++ b/src/opengl/KcGpuBuffer.cpp @@ -3,6 +3,20 @@ #include "glad.h" +namespace kPrivate +{ + GLenum oglBufferType(KcGpuBuffer::KeType type) + { + constexpr static GLenum oglType[] = { + GL_ARRAY_BUFFER, + GL_ELEMENT_ARRAY_BUFFER + }; + + return oglType[type]; + } +} + + void KcGpuBuffer::create_() { if (handle() == 0) { @@ -25,13 +39,13 @@ void KcGpuBuffer::destroy() void KcGpuBuffer::bind() const { - glBindBuffer(GL_ARRAY_BUFFER, handle()); + bind_(handle()); } void KcGpuBuffer::setData(const void* data, unsigned bytes, KeUsage usage) { - const static GLenum glUsages[] = { + constexpr static GLenum glUsages[] = { GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, @@ -45,15 +59,14 @@ void KcGpuBuffer::setData(const void* data, unsigned bytes, KeUsage usage) create_(); - // we use the GL_ARRAY_BUFFER slot to send the data for no special reason - GLuint last_array_buffer; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); + auto lastBinding = binding_(); - glBindBuffer(GL_ARRAY_BUFFER, handle()); - glBufferData(GL_ARRAY_BUFFER, bytes, data, glUsages[usage]); + bind(); - if (last_array_buffer != handle()) - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); // TODO: Ƿָֻģʽ + glBufferData(kPrivate::oglBufferType(type_), bytes, data, glUsages[usage]); + + if (lastBinding != handle()) + bind_(lastBinding); // TODO: Ƿָֻģʽ bytes_ = bytes; usage_ = usage; @@ -65,20 +78,20 @@ void KcGpuBuffer::setSubData(const void* data, unsigned bytes, int offset) assert(handle() && data); assert(bytes + offset <= bytesCount()); - GLuint last_array_buffer; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); + auto lastBinding = binding_(); + + bind(); - glBindBuffer(GL_ARRAY_BUFFER, handle()); - glBufferSubData(GL_ARRAY_BUFFER, offset, bytes, data); + glBufferSubData(kPrivate::oglBufferType(type_), offset, bytes, data); - if (last_array_buffer != handle()) - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + if (lastBinding != handle()) + bind_(lastBinding); } void* KcGpuBuffer::map(KeAccess access) { - const static GLenum glAccess[] = { + constexpr static GLenum glAccess[] = { GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE @@ -86,14 +99,14 @@ void* KcGpuBuffer::map(KeAccess access) create_(); - GLuint last_array_buffer; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); + auto lastBinding = binding_(); + + bind(); - glBindBuffer(GL_ARRAY_BUFFER, handle()); - void* ptr = glMapBuffer(GL_ARRAY_BUFFER, glAccess[access]); + void* ptr = glMapBuffer(kPrivate::oglBufferType(type_), glAccess[access]); - if (last_array_buffer != handle()) - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + if (lastBinding != handle()) + bind_(lastBinding); return ptr; } @@ -103,15 +116,34 @@ bool KcGpuBuffer::unmap() { assert(handle()); - GLuint last_array_buffer; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); + auto lastBinding = binding_(); - glBindBuffer(GL_ARRAY_BUFFER, handle()); + bind(); - bool ok = glUnmapBuffer(GL_ARRAY_BUFFER) == GL_TRUE; + bool ok = glUnmapBuffer(kPrivate::oglBufferType(type_)) == GL_TRUE; - if (last_array_buffer != handle()) - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + if (lastBinding != handle()) + bind_(lastBinding); return true; } + + +unsigned int KcGpuBuffer::binding_() const +{ + constexpr static GLenum bindingFlag[] = { + GL_ARRAY_BUFFER_BINDING, + GL_ELEMENT_ARRAY_BUFFER_BINDING + }; + + GLuint last_binding; + glGetIntegerv(bindingFlag[type_], (GLint*)&last_binding); + + return last_binding; +} + + +void KcGpuBuffer::bind_(unsigned int id) const +{ + glBindBuffer(kPrivate::oglBufferType(type_), id); +} diff --git a/src/opengl/KcGpuBuffer.h b/src/opengl/KcGpuBuffer.h index 1b59fd0..cd908a2 100644 --- a/src/opengl/KcGpuBuffer.h +++ b/src/opengl/KcGpuBuffer.h @@ -7,9 +7,15 @@ class KcGpuBuffer { public: - ~KcGpuBuffer() { - destroy(); - } + enum KeType + { + k_vertex_buffer, // vbo + k_index_buffer // ibo + }; + + KcGpuBuffer(KeType type = k_vertex_buffer) : type_(type) {} + + ~KcGpuBuffer() { destroy(); } unsigned int handle() const { return handle_; } @@ -71,8 +77,12 @@ private: void create_(); -private: + unsigned int binding_() const; + + void bind_(unsigned int id) const; +private: + KeType type_; unsigned int handle_{ 0 }; unsigned bytes_{ 0 }; KeUsage usage_{ k_static_draw }; diff --git a/src/opengl/KcLightenObject.cpp b/src/opengl/KcLightenObject.cpp new file mode 100644 index 0000000..c34720c --- /dev/null +++ b/src/opengl/KcLightenObject.cpp @@ -0,0 +1,25 @@ +#include "KcLightenObject.h" +#include "KsShaderManager.h" +#include "KcGlslProgram.h" +#include "glad.h" +#include + + +KcLightenObject::KcLightenObject(KePrimitiveType type) + : super_(type) +{ + prog_ = KsShaderManager::singleton().programMonoLight(); +} + + +void KcLightenObject::draw() const +{ + auto loc = prog_->getUniformLocation("matNormal"); + assert(loc != -1); + + prog_->useProgram(); + glUniformMatrix4fv(loc, 1, GL_TRUE, normalMat_.data()); + //glProgramUniformMatrix4fv(prog_->handle(), loc, 1, GL_TRUE, normalMat_.data()); + + super_::draw(); +} diff --git a/src/opengl/KcLightenObject.h b/src/opengl/KcLightenObject.h new file mode 100644 index 0000000..0b9e494 --- /dev/null +++ b/src/opengl/KcLightenObject.h @@ -0,0 +1,24 @@ +#pragma once +#include "KcRenderObject.h" + + +// ȫֹգƹⷽ+ZȾ + +class KcLightenObject : public KcRenderObject +{ + using super_ = KcRenderObject; + +public: + + KcLightenObject(KePrimitiveType type); + + void setNormalMatrix(float4x4<> m) { + normalMat_ = m; + } + + void draw() const override; + +private: + float4x4<> normalMat_; +}; + diff --git a/src/opengl/KcLineObject.cpp b/src/opengl/KcLineObject.cpp index 16de941..7d0d909 100644 --- a/src/opengl/KcLineObject.cpp +++ b/src/opengl/KcLineObject.cpp @@ -1,22 +1,18 @@ #include "KcLineObject.h" #include "glad.h" #include "KsShaderManager.h" -#include "opengl/KcGlslProgram.h" -KcLineObject::KcLineObject(KeType type) - : super_(type, KsShaderManager::singleton().programMono()) +KcLineObject::KcLineObject(KePrimitiveType type) + : super_(type) { - + prog_ = KsShaderManager::singleton().programMono(); } void KcLineObject::draw() const { glLineWidth(lineWidth_); - prog_->useProgram(); - auto loc = prog_->getUniformLocation("vColor"); - glUniform4f(loc, lineColor_[0], lineColor_[1], lineColor_[2], lineColor_[3]); super_::draw(); } diff --git a/src/opengl/KcLineObject.h b/src/opengl/KcLineObject.h index beccb1d..8ece3e5 100644 --- a/src/opengl/KcLineObject.h +++ b/src/opengl/KcLineObject.h @@ -12,10 +12,6 @@ public: KcLineObject(KePrimitiveType type = k_line_strip); - void setColor(const float4& clr) { - lineColor_ = clr; - } - void setWidth(float w) { lineWidth_ = w; } @@ -23,6 +19,5 @@ public: void draw() const override; private: - float4 lineColor_{1, 0, 0, 1}; float lineWidth_{ 1 }; }; \ No newline at end of file diff --git a/src/opengl/KcPointObject.cpp b/src/opengl/KcPointObject.cpp index 6e5ae75..90568e5 100644 --- a/src/opengl/KcPointObject.cpp +++ b/src/opengl/KcPointObject.cpp @@ -1,13 +1,12 @@ #include "KcPointObject.h" #include "glad.h" #include "KsShaderManager.h" -#include "opengl/KcGlslProgram.h" KcPointObject::KcPointObject() - : super_(k_points, KsShaderManager::singleton().programMono()) + : super_(k_points) { - + prog_ = KsShaderManager::singleton().programMono(); } @@ -18,8 +17,6 @@ void KcPointObject::draw() const glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - prog_->useProgram(); - auto loc = prog_->getUniformLocation("vColor"); - glUniform4f(loc, pointColor_[0], pointColor_[1], pointColor_[2], pointColor_[3]); + super_::draw(); } diff --git a/src/opengl/KcPointObject.h b/src/opengl/KcPointObject.h index 080e69b..0ff2593 100644 --- a/src/opengl/KcPointObject.h +++ b/src/opengl/KcPointObject.h @@ -12,10 +12,6 @@ public: KcPointObject(); - void setColor(const float4& clr) { - pointColor_ = clr; - } - void setSize(float s) { pointSize_ = s; } @@ -23,7 +19,6 @@ public: void draw() const override; private: - float4 pointColor_{ 1, 0, 0, 1 }; float pointSize_{ 2 }; }; diff --git a/src/opengl/KcRenderObject.cpp b/src/opengl/KcRenderObject.cpp index 3368bd8..79b8f25 100644 --- a/src/opengl/KcRenderObject.cpp +++ b/src/opengl/KcRenderObject.cpp @@ -27,17 +27,32 @@ void KcRenderObject::draw() const prog_->useProgram(); // shader // shaderuniformֵ - auto loc = prog_->getUniformLocation("mvpMat"); + auto loc = prog_->getUniformLocation("matMvp"); glUniformMatrix4fv(loc, 1, GL_TRUE, projMat_.data()); + GLint enableClip = !clipBox_.isNull(); loc = prog_->getUniformLocation("iEnableClip"); - glUniform1i(loc, enableClip); - if (enableClip) { - loc = prog_->getUniformLocation("vClipLower"); - glUniform3f(loc, clipBox_.lower().x(), clipBox_.lower().y(), clipBox_.lower().z()); - loc = prog_->getUniformLocation("vClipUpper"); - glUniform3f(loc, clipBox_.upper().x(), clipBox_.upper().y(), clipBox_.upper().z()); + if (loc != -1) { + glUniform1i(loc, enableClip); + if (enableClip) { + loc = prog_->getUniformLocation("vClipLower"); + glUniform3f(loc, clipBox_.lower().x(), clipBox_.lower().y(), clipBox_.lower().z()); + loc = prog_->getUniformLocation("vClipUpper"); + glUniform3f(loc, clipBox_.upper().x(), clipBox_.upper().y(), clipBox_.upper().z()); + } } - glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vtxDecl_->calcVertexSize()); + loc = prog_->getUniformLocation("vColor"); + if (loc != -1) + glUniform4f(loc, color_[0], color_[1], color_[2], color_[3]); + + if (ibo_ && indexCount_ > 0) { + ibo_->bind(); + auto idxSize = ibo_->bytesCount() / indexCount_; + GLenum type = (idxSize == 4) ? GL_UNSIGNED_INT : (idxSize == 2) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE; + glDrawElements(glModes[type_], indexCount_, type, 0); + } + else { + glDrawArrays(glModes[type_], 0, vbo_->bytesCount() / vtxDecl_->vertexSize()); + } } diff --git a/src/opengl/KcRenderObject.h b/src/opengl/KcRenderObject.h index 04f2672..9824ac0 100644 --- a/src/opengl/KcRenderObject.h +++ b/src/opengl/KcRenderObject.h @@ -17,16 +17,24 @@ public: using aabb_t = KtAABB; - KcRenderObject(KePrimitiveType type, std::shared_ptr prog) - : type_(type), prog_(prog) {} + KcRenderObject(KePrimitiveType type) : type_(type) {} KcRenderObject(const KcRenderObject& rhs) - : type_(rhs.type_), prog_(rhs.prog_), vbo_(rhs.vbo_), vtxDecl_(rhs.vtxDecl_) {} + : type_(rhs.type_), prog_(rhs.prog_), vbo_(rhs.vbo_), ibo_(rhs.ibo_), + vtxDecl_(rhs.vtxDecl_), indexCount_(rhs.indexCount_) {} - void setVbo(std::shared_ptr vbo, std::shared_ptr vtxDecl) { + void setShader(std::shared_ptr prog) { + prog_ = prog; + } + + void setVBO(std::shared_ptr vbo, std::shared_ptr vtxDecl) { vbo_ = vbo, vtxDecl_ = vtxDecl; } + void setIBO(std::shared_ptr ibo, unsigned idxCount) { + ibo_ = ibo, indexCount_ = idxCount; + } + void setProjMatrix(const float4x4<>& projMat) { projMat_ = projMat; } @@ -35,13 +43,19 @@ public: clipBox_ = clipBox; } + void setColor(const float4& clr) { + color_ = clr; + } + virtual void draw() const; protected: KePrimitiveType type_; std::shared_ptr prog_; - std::shared_ptr vbo_; + std::shared_ptr vbo_, ibo_; std::shared_ptr vtxDecl_; + unsigned indexCount_{ 0 }; float4x4<> projMat_; aabb_t clipBox_; + float4 color_{ 1, 0, 0, 1 }; }; diff --git a/src/opengl/KsShaderManager.cpp b/src/opengl/KsShaderManager.cpp index da8f006..3bda577 100644 --- a/src/opengl/KsShaderManager.cpp +++ b/src/opengl/KsShaderManager.cpp @@ -19,16 +19,16 @@ KsShaderManager::~KsShaderManager() KsShaderManager::shader_ptr KsShaderManager::vertexShaderMono() { const static char* vertex_shader_mono = - "uniform mat4 mvpMat;\n" + "uniform mat4 matMvp;\n" + "uniform vec4 vColor;\n" "uniform int iEnableClip;\n" "uniform vec3 vClipLower;\n" - "uniform vec3 vClipUpper;\n" - "uniform vec4 vColor;\n" + "uniform vec3 vClipUpper;\n" "in vec3 iPosition;\n" "out vec4 Frag_Color;\n" "void main()\n" "{\n" - " gl_Position = mvpMat * vec4(iPosition, 1);\n" + " gl_Position = matMvp * vec4(iPosition, 1);\n" " Frag_Color = vColor;\n" " if (iEnableClip != 0)\n" " {\n" @@ -53,7 +53,7 @@ KsShaderManager::shader_ptr KsShaderManager::vertexShaderMono() KsShaderManager::shader_ptr KsShaderManager::vertexShaderColorUV() { const static char* vertex_shader_color_uv = - "uniform mat4 mvpMat;\n" + "uniform mat4 matMvp;\n" "layout (location = 0) in vec3 iPosition;\n" "layout (location = 1) in vec2 iUV;\n" "layout (location = 2) in vec4 iColor;\n" @@ -61,7 +61,7 @@ KsShaderManager::shader_ptr KsShaderManager::vertexShaderColorUV() "out vec4 Frag_Color;\n" "void main()\n" "{\n" - " gl_Position = mvpMat * vec4(iPosition, 1);\n" + " gl_Position = matMvp * vec4(iPosition, 1);\n" " Frag_UV = iUV;\n" " Frag_Color = iColor;\n" "}\n"; @@ -75,6 +75,47 @@ KsShaderManager::shader_ptr KsShaderManager::vertexShaderColorUV() } +KsShaderManager::shader_ptr KsShaderManager::vertexShaderMonoLight() +{ + const static char* vertex_shader_mono_light = + "uniform mat4 matMvp;\n" + "uniform mat4 matNormal;\n" + "uniform vec4 vColor;\n" + "uniform int iEnableClip;\n" + "uniform vec3 vClipLower;\n" + "uniform vec3 vClipUpper;\n" + "in vec3 iPosition;\n" + "in vec3 iNormal;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_Position = matMvp * vec4(iPosition, 1);\n" + " vec3 vNorm = normalize(matNormal * vec4(iNormal, 0)).xyz;\n" + " vec3 vLightDir = vec3(1.0, 1.0, 1.0);\n" + " float fDot = max(0.0, dot(vNorm, vLightDir));\n" + " Frag_Color.rgb = vColor.rgb * fDot;\n" + " Frag_Color.a = vColor.a;\n" + " if (iEnableClip != 0)\n" + " {\n" + " gl_ClipDistance[0] = iPosition.x - vClipLower.x;\n" + " gl_ClipDistance[1] = iPosition.y - vClipLower.y;\n" + " gl_ClipDistance[2] = iPosition.z - vClipLower.z;\n" + " gl_ClipDistance[3] = vClipUpper.x - iPosition.x;\n" + " gl_ClipDistance[4] = vClipUpper.y - iPosition.y;\n" + " gl_ClipDistance[5] = vClipUpper.z - iPosition.z;\n" + " }\n" + "}\n"; + + if (vertexShaderMonoLight_ == nullptr) { + vertexShaderMonoLight_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_mono_light); + auto log = vertexShaderMonoLight_->infoLog(); + assert(vertexShaderMonoLight_->compileStatus()); + } + + return vertexShaderMonoLight_; +} + + KsShaderManager::shader_ptr KsShaderManager::fragShaderNaive() { const static char* frag_shader_naive = @@ -138,4 +179,19 @@ KsShaderManager::program_ptr KsShaderManager::programColorUV() } return progColorUV_; +} + + +KsShaderManager::program_ptr KsShaderManager::programMonoLight() +{ + if (progMonoLight_ == nullptr) { + progMonoLight_ = std::make_shared(); + progMonoLight_->attachShader(vertexShaderMonoLight()); + progMonoLight_->attachShader(fragShaderNaive()); + progMonoLight_->link(); + auto info = progMonoLight_->infoLog(); + assert(progMonoLight_->linked() && progMonoLight_->linkStatus()); + } + + return progMonoLight_; } \ No newline at end of file diff --git a/src/opengl/KsShaderManager.h b/src/opengl/KsShaderManager.h index 8b41d0a..a716bce 100644 --- a/src/opengl/KsShaderManager.h +++ b/src/opengl/KsShaderManager.h @@ -21,12 +21,17 @@ public: using program_ptr = std::shared_ptr; // attr = pos - // uniform = color + // uniform = matMvp + vColor shader_ptr vertexShaderMono(); // attr = pos + uv + color + // uniform = matMvp shader_ptr vertexShaderColorUV(); + // attr = pos + normal + // uniform = matMvp + matNormal + vColor + shader_ptr vertexShaderMonoLight(); + // out-color = in-color shader_ptr fragShaderNaive(); @@ -39,6 +44,8 @@ public: // vertexShaderColorUV_ + fragShaderColorUV_ program_ptr programColorUV(); + // vertexShaderMonoLight_ + fragShaderNaive_ + program_ptr programMonoLight(); private: KsShaderManager(); @@ -52,9 +59,11 @@ private: shader_ptr vertexShaderMono_; shader_ptr vertexShaderColorUV_; + shader_ptr vertexShaderMonoLight_; shader_ptr fragShaderNaive_; shader_ptr fragShaderColorUV_; program_ptr progMono_; program_ptr progColorUV_; + program_ptr progMonoLight_; }; diff --git a/src/plot/KcBars3d.cpp b/src/plot/KcBars3d.cpp index 5480d52..df33d16 100644 --- a/src/plot/KcBars3d.cpp +++ b/src/plot/KcBars3d.cpp @@ -1,6 +1,7 @@ #include "KcBars3d.h" #include "KuPrimitiveFactory.h" #include "KtGeometryImpl.h" +#include "KcVertexDeclaration.h" #include "KvData.h" @@ -29,7 +30,10 @@ void KcBars3d::drawImpl_(KvPaint* paint, point_getter getter, unsigned count, un point3f normal; }; - auto gemo = std::make_shared>(k_triangles); + auto geom = std::make_shared>(k_triangles); + auto vtxPerBox = 8; + auto idxPerBox = 36; + geom->reserve(vtxPerBox * count, idxPerBox * count); for (unsigned i = 0; i < count; i++) { auto pt0 = getter(i); @@ -44,17 +48,28 @@ void KcBars3d::drawImpl_(KvPaint* paint, point_getter getter, unsigned count, un pt1 = { pt0.x() - xw, pt0.y() - yw, baseLine_ }; } - auto box = KuGeometryFactory::makeBox(pt1, pt0); + unsigned idxBase = geom->vertexCount(); + char* vtxBuf = (char*)geom->newVertex(vtxPerBox); + KuPrimitiveFactory::makeBox(pt1, pt0, vtxBuf, sizeof(KpVtxBuffer_)); + KuPrimitiveFactory::makeBox(pt1, pt0, vtxBuf + sizeof(point3f), sizeof(KpVtxBuffer_)); - if (drawFill) { - paint->apply(fill_); - paint->drawGeom(box); - } + auto* idxBuf = geom->newIndex(idxPerBox); + KuPrimitiveFactory::makeBox(pt1, pt0, idxBuf); + for (unsigned i = 0; i < idxPerBox; i++) + idxBuf[i] += idxBase; + } - // TODO: - //if (drawBorder) { - // paint->apply(border_); - // paint->drawRect(pt0, pt1); - //} + if (drawFill) { + paint->apply(fill_); + auto decl = std::make_shared(); + decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); + decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_normal); + paint->drawGeom(decl, geom); } + + // TODO: + //if (drawBorder) { + // paint->apply(border_); + // paint->drawRect(pt0, pt1); + //} } \ No newline at end of file diff --git a/src/plot/KvPaint.h b/src/plot/KvPaint.h index 17302a6..5e2a50c 100644 --- a/src/plot/KvPaint.h +++ b/src/plot/KvPaint.h @@ -3,7 +3,8 @@ #include #include "KvRenderable.h" #include "KpContext.h" -#include "KtGeometry.h" +#include "KvGeometry.h" +#include "KcVertexDeclaration.h" #include "KtMatrix4.h" #include "KtQuaternion.h" @@ -21,7 +22,8 @@ public: using point4 = KtPoint; using mat4 = KtMatrix4; using point_getter = std::function; - using geom_ptr = std::shared_ptr>; + using geom_ptr = std::shared_ptr; + using vtx_decl_ptr = std::shared_ptr; virtual void beginPaint() = 0; virtual void endPaint() = 0; @@ -113,7 +115,7 @@ public: // @anchor: ıê㡣ıalignʽanchor virtual void drawText(const point3& anchor, const char* text, int align) = 0; - virtual void drawGeom(geom_ptr geom) = 0; + virtual void drawGeom(vtx_decl_ptr decl, geom_ptr geom) = 0; // һЩߴ㺯 -- Gitee From 0c7faa56046a37eb7a5367bba638d16bde128cfd Mon Sep 17 00:00:00 2001 From: koala999 Date: Tue, 27 Dec 2022 08:04:17 +0800 Subject: [PATCH 37/68] try: depth test --- src/imapp/KcImOglPaint.cpp | 19 ++++++++++++++-- src/imapp/KcImOglPaint.h | 25 ++++++++++++--------- src/plot/KcBars2d.cpp | 2 +- src/plot/KcBars3d.cpp | 46 +++++++++++++++++++++++++++----------- src/plot/KvPaint.h | 2 ++ 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 8173fd8..df31618 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -36,6 +36,7 @@ KcImOglPaint::KcImOglPaint(camera_type& cam) { curViewport_ = -1; curClipBox_ = -1; + depthTest_ = false; } @@ -57,6 +58,8 @@ void KcImOglPaint::beginPaint() clipBoxHistList_.clear(); curClipBox_ = -1; + glClear(GL_DEPTH_BUFFER_BIT); + super_::beginPaint(); } @@ -290,6 +293,9 @@ void KcImOglPaint::drawGeom(vtx_decl_ptr decl, geom_ptr geom) //((KcLightenObject*)obj)->setNormalMatrix(camera_.getNormalMatrix()); ((KcLightenObject*)obj)->setNormalMatrix(mat4::identity()); } + else { + obj->setShader(KsShaderManager::singleton().programMono()); // ȱʡshader + } auto vbo = std::make_shared(); vbo->setData(geom->vertexData(), geom->vertexCount() * geom->vertexSize(), KcGpuBuffer::k_stream_draw); @@ -373,7 +379,7 @@ void KcImOglPaint::disableClipBox() KcImOglPaint::KpRenderList_& KcImOglPaint::currentRenderList() { auto curClipRect = clipRectStack_.empty() ? -1 : clipRectStack_.back(); - return renderList_[kRenderState_(curViewport_, curClipRect, curClipBox_)]; + return renderList_[kRenderState_(curViewport_, curClipRect, curClipBox_, depthTest_)]; } @@ -383,8 +389,9 @@ void KcImOglPaint::drawRenderList_() glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + glDisable(GL_DEPTH_TEST); - unsigned viewport(-1), clipRect(-1), clipBox(-2); + unsigned viewport(-1), clipRect(-1), clipBox(-2), depthTest(false); for (auto& rd : renderList_) { auto& state = rd.first; if (std::get<0>(state) != viewport) { @@ -399,6 +406,14 @@ void KcImOglPaint::drawRenderList_() clipBox = std::get<2>(state); glClipPlane_(clipBox); } + if (std::get<3>(state) != depthTest) { + depthTest = std::get<3>(state); + if (depthTest) { + glEnable(GL_DEPTH_TEST); + } + else + glDisable(GL_DEPTH_TEST); + } auto& rl = rd.second; diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index aaf9afe..c95e978 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -34,6 +34,10 @@ public: void enableClipBox(point3 lower, point3 upper) override; void disableClipBox() override; + void enableDepthTest(bool b) override { + depthTest_ = b; + } + void beginPaint() override; void endPaint() override; @@ -61,16 +65,20 @@ private: // render states stacks - std::vector viewportHistList_; - std::vector clipRectHistList_; - std::vector clipBoxHistList_; + std::vector viewportHistList_; // ӿб + std::vector clipRectHistList_; // ürectб + std::vector clipBoxHistList_; // άռüboxб std::vector clipRectStack_; unsigned curViewport_; // -1ʾδ - unsigned curClipBox_; + unsigned curClipBox_; + bool depthTest_; // Ȳԣ - // ʹtuple3ջ - using kRenderState_ = std::tuple; + // [0]: viewport idx + // [1]: clipRect idx + // [2]: clipBox idx + // [3]: depth test + using kRenderState_ = std::tuple; struct KpRenderList_ { @@ -82,11 +90,6 @@ private: // Ⱦ״̬ĴȾб std::map renderList_; - //std::vector glLists_; // clipBoxʾбid - //unsigned clipBox_{ 0 }; // 浱ǰclipBox״̬ӦglLists_ - // ͨglCallList(glLists_[clipBox_])ӦclipBox0ʾ - - private: KpRenderList_& currentRenderList(); diff --git a/src/plot/KcBars2d.cpp b/src/plot/KcBars2d.cpp index 89f03cd..d701b84 100644 --- a/src/plot/KcBars2d.cpp +++ b/src/plot/KcBars2d.cpp @@ -7,7 +7,7 @@ KcBars2d::KcBars2d(const std::string_view& name) : super_(name) { - border_.color = color4f(0); // default no border + border_.color = color4f(0, 0, 0, 1); // default no border } diff --git a/src/plot/KcBars3d.cpp b/src/plot/KcBars3d.cpp index df33d16..9352f82 100644 --- a/src/plot/KcBars3d.cpp +++ b/src/plot/KcBars3d.cpp @@ -30,10 +30,15 @@ void KcBars3d::drawImpl_(KvPaint* paint, point_getter getter, unsigned count, un point3f normal; }; - auto geom = std::make_shared>(k_triangles); + auto mesh = std::make_shared>(k_triangles); auto vtxPerBox = 8; - auto idxPerBox = 36; - geom->reserve(vtxPerBox * count, idxPerBox * count); + auto idxPerBoxMesh = 36; + mesh->reserve(vtxPerBox * count, idxPerBoxMesh* count); + + auto edge = std::make_shared>(k_lines); + auto idxPerBoxEdge = 24; + if (drawBorder) + edge->reserve(vtxPerBox * count, idxPerBoxEdge * count); for (unsigned i = 0; i < count; i++) { auto pt0 = getter(i); @@ -48,28 +53,43 @@ void KcBars3d::drawImpl_(KvPaint* paint, point_getter getter, unsigned count, un pt1 = { pt0.x() - xw, pt0.y() - yw, baseLine_ }; } - unsigned idxBase = geom->vertexCount(); - char* vtxBuf = (char*)geom->newVertex(vtxPerBox); + unsigned idxBase = mesh->vertexCount(); + char* vtxBuf = (char*)mesh->newVertex(vtxPerBox); KuPrimitiveFactory::makeBox(pt1, pt0, vtxBuf, sizeof(KpVtxBuffer_)); KuPrimitiveFactory::makeBox(pt1, pt0, vtxBuf + sizeof(point3f), sizeof(KpVtxBuffer_)); - auto* idxBuf = geom->newIndex(idxPerBox); + auto* idxBuf = mesh->newIndex(idxPerBoxMesh); KuPrimitiveFactory::makeBox(pt1, pt0, idxBuf); - for (unsigned i = 0; i < idxPerBox; i++) + for (unsigned i = 0; i < idxPerBoxMesh; i++) idxBuf[i] += idxBase; + + if (drawBorder) { + vtxBuf = (char*)edge->newVertex(vtxPerBox); + KuPrimitiveFactory::makeBox(pt1, pt0, vtxBuf); + + idxBuf = edge->newIndex(idxPerBoxEdge); + KuPrimitiveFactory::makeBox(pt1, pt0, idxBuf); + for (unsigned i = 0; i < idxPerBoxEdge; i++) + idxBuf[i] += idxBase; + } } if (drawFill) { paint->apply(fill_); + paint->enableDepthTest(true); auto decl = std::make_shared(); decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_normal); - paint->drawGeom(decl, geom); + paint->drawGeom(decl, mesh); + paint->enableDepthTest(false); } - // TODO: - //if (drawBorder) { - // paint->apply(border_); - // paint->drawRect(pt0, pt1); - //} + if (drawBorder) { // TODO: + paint->apply(border_); + //paint->enableDepthTest(true); + auto decl = std::make_shared(); + decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); + paint->drawGeom(decl, edge); + //paint->enableDepthTest(false); + } } \ No newline at end of file diff --git a/src/plot/KvPaint.h b/src/plot/KvPaint.h index 5e2a50c..323343c 100644 --- a/src/plot/KvPaint.h +++ b/src/plot/KvPaint.h @@ -54,6 +54,8 @@ public: virtual void enableClipBox(point3 lower, point3 upper) = 0; virtual void disableClipBox() = 0; + virtual void enableDepthTest(bool b) = 0; + // project local point/vector to screen point/vector virtual point4 project(const point4& pt) const = 0; -- Gitee From e2021c2fdb7cdd6744ba2f8da47080781039b5f8 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Tue, 27 Dec 2022 09:32:47 +0800 Subject: [PATCH 38/68] add: depth test --- src/imapp/KcImOglPaint.cpp | 3 ++- src/plot/KcBars3d.cpp | 18 +++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index df31618..21c3fd7 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -391,7 +391,8 @@ void KcImOglPaint::drawRenderList_() glLoadIdentity(); glDisable(GL_DEPTH_TEST); - unsigned viewport(-1), clipRect(-1), clipBox(-2), depthTest(false); + unsigned viewport(-1), clipRect(-1), clipBox(-2); + bool depthTest(false); for (auto& rd : renderList_) { auto& state = rd.first; if (std::get<0>(state) != viewport) { diff --git a/src/plot/KcBars3d.cpp b/src/plot/KcBars3d.cpp index 9352f82..e9dc681 100644 --- a/src/plot/KcBars3d.cpp +++ b/src/plot/KcBars3d.cpp @@ -22,15 +22,15 @@ void KcBars3d::drawImpl_(KvPaint* paint, point_getter getter, unsigned count, un auto yw = dim == 1 ? boundingBox().depth() / count : barWidth_(1); bool drawFill = fill_.style != KpBrush::k_none && majorColor(0).a() != 0; - bool drawBorder = border_.style != KpPen::k_none && minorColor().a() != 0 && minorColor() != majorColor(0); + bool drawBorder = border_.style != KpPen::k_none && minorColor().a() != 0; // && minorColor() != majorColor(0); struct KpVtxBuffer_ { point3f pos; - point3f normal; + point3f normal; // TODO: lighting }; - auto mesh = std::make_shared>(k_triangles); + auto mesh = std::make_shared>(k_triangles); auto vtxPerBox = 8; auto idxPerBoxMesh = 36; mesh->reserve(vtxPerBox * count, idxPerBoxMesh* count); @@ -55,8 +55,8 @@ void KcBars3d::drawImpl_(KvPaint* paint, point_getter getter, unsigned count, un unsigned idxBase = mesh->vertexCount(); char* vtxBuf = (char*)mesh->newVertex(vtxPerBox); - KuPrimitiveFactory::makeBox(pt1, pt0, vtxBuf, sizeof(KpVtxBuffer_)); - KuPrimitiveFactory::makeBox(pt1, pt0, vtxBuf + sizeof(point3f), sizeof(KpVtxBuffer_)); + KuPrimitiveFactory::makeBox(pt1, pt0, vtxBuf); + //KuPrimitiveFactory::makeBox(pt1, pt0, vtxBuf + sizeof(point3f), sizeof(KpVtxBuffer_)); auto* idxBuf = mesh->newIndex(idxPerBoxMesh); KuPrimitiveFactory::makeBox(pt1, pt0, idxBuf); @@ -79,17 +79,17 @@ void KcBars3d::drawImpl_(KvPaint* paint, point_getter getter, unsigned count, un paint->enableDepthTest(true); auto decl = std::make_shared(); decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); - decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_normal); + //decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_normal); paint->drawGeom(decl, mesh); paint->enableDepthTest(false); } - if (drawBorder) { // TODO: + if (drawBorder) { paint->apply(border_); - //paint->enableDepthTest(true); + paint->enableDepthTest(true); auto decl = std::make_shared(); decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); paint->drawGeom(decl, edge); - //paint->enableDepthTest(false); + paint->enableDepthTest(false); } } \ No newline at end of file -- Gitee From ff5651434c9f9ce907ca714e56183ed5d58e22db Mon Sep 17 00:00:00 2001 From: koala999cn Date: Tue, 27 Dec 2022 16:13:24 +0800 Subject: [PATCH 39/68] add: draw the dotted & dashed line --- src/imapp/KcImOglPaint.cpp | 34 +++++++++++++++++++++++++--------- src/plot/KpContext.h | 7 ++++--- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 21c3fd7..61e4b2a 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -10,20 +10,26 @@ #include "opengl/KcLineObject.h" #include "opengl/KcLightenObject.h" #include "opengl/KsShaderManager.h" +#include "plot/KpContext.h" namespace kPrivate { - // colorwidthúã˴Ҫstyle(TODO) - void oglLine(int style, const KcImOglPaint::point3& from, const KcImOglPaint::point3& to) + static int lineStipple(int lineStyle) { - glBegin(GL_LINES); - glVertex3f(from.x(), from.y(), from.z()); - glVertex3f(to.x(), to.y(), to.z()); - glEnd(); + switch (lineStyle) + { + case KpPen::k_dot: return 0xAAAA; + case KpPen::k_dash: return 0xCCCC; + case KpPen::k_dash4: return 0xF0F0; + case KpPen::k_dash8: return 0xFF00; + case KpPen::k_dash_dot: return 0xF840; + case KpPen::k_dash_dot_dot: return 0xF888; + } + return 0xFFFF; } - void oglDrawRenderList(const ImDrawList*, const ImDrawCmd* cmd) + static void oglDrawRenderList(const ImDrawList*, const ImDrawCmd* cmd) { auto paint = (KcImOglPaint*)cmd->UserCallbackData; paint->drawRenderList_(); @@ -151,8 +157,18 @@ void KcImOglPaint::drawLine(const point3& from, const point3& to) //glHint(GL_LINE_SMOOTH, GL_NICEST); //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - kPrivate::oglLine(style, pt0, pt1); - + if (style == KpPen::k_solid) { + glDisable(GL_LINE_STIPPLE); + } + else { + glEnable(GL_LINE_STIPPLE); + glLineStipple(1, kPrivate::lineStipple(style)); + } + + glBegin(GL_LINES); + glVertex3f(pt0.x(), pt0.y(), pt0.z()); + glVertex3f(pt1.x(), pt1.y(), pt1.z()); + glEnd(); }; currentRenderList().fns.push_back(drawFn); diff --git a/src/plot/KpContext.h b/src/plot/KpContext.h index 9080c0d..c53109b 100644 --- a/src/plot/KpContext.h +++ b/src/plot/KpContext.h @@ -14,11 +14,12 @@ public: { k_none, k_solid, - k_dash, k_dot, + k_dash, + k_dash4, + k_dash8, k_dash_dot, - k_dash_dot_dot, - k_dash_dot_dash + k_dash_dot_dot }; int style{ k_solid }; -- Gitee From 02dc2e02ca022bbe7eebc353eef5ed4e2e1c44d6 Mon Sep 17 00:00:00 2001 From: koala999 Date: Tue, 27 Dec 2022 21:07:52 +0800 Subject: [PATCH 40/68] =?UTF-8?q?fix:=20color-bar=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E7=95=99=E7=99=BD=E6=97=B6=E6=9C=AA=E6=AD=A3=E7=A1=AE=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=9D=90=E6=A0=87=E7=B3=BB=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcColorBar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plot/KcColorBar.cpp b/src/plot/KcColorBar.cpp index 93f8520..0fbd381 100644 --- a/src/plot/KcColorBar.cpp +++ b/src/plot/KcColorBar.cpp @@ -134,7 +134,10 @@ KcColorBar::size_t KcColorBar::calcSize_(void* cxt) const axis_->setType(location() & KeAlignment::k_bottom ? KcAxis::k_bottom : KcAxis::k_top); } + KvPaint* paint = (KvPaint*)cxt; + paint->pushCoord(KvPaint::k_coord_screen); auto mar = axis_->calcMargins((KvPaint*)cxt); + paint->popCoord(); if (location() & KeAlignment::k_horz_first) return { barWidth_ + mar.left() + mar.right(), barLength_ }; -- Gitee From 6e257c1db137878587a4c5fd6828987359a6a9fe Mon Sep 17 00:00:00 2001 From: koala999 Date: Tue, 27 Dec 2022 22:10:42 +0800 Subject: [PATCH 41/68] new: the 3d surface plottable --- DataVis.vcxproj | 2 + DataVis.vcxproj.filters | 6 ++ src/3d/KuPrimitiveFactory.h | 40 ++++++++ src/imapp/KcImOglPaint.cpp | 12 ++- src/opengl/KcLightenObject.cpp | 2 +- src/opengl/KcLineObject.cpp | 2 +- src/opengl/KcPointObject.cpp | 2 +- src/opengl/KsShaderManager.cpp | 163 ++++++++++++++++++++++----------- src/opengl/KsShaderManager.h | 53 ++++++----- src/plot/KcColorMap.cpp | 10 +- src/plot/KcSurface.cpp | 46 ++++++++++ src/plot/KcSurface.h | 17 ++++ src/plot/KvPlottable.cpp | 2 +- src/plot/KvPlottable.h | 3 + src/prov/KcPvData.cpp | 2 +- src/render/KcRdPlot3d.cpp | 10 +- 16 files changed, 278 insertions(+), 94 deletions(-) create mode 100644 src/plot/KcSurface.cpp create mode 100644 src/plot/KcSurface.h diff --git a/DataVis.vcxproj b/DataVis.vcxproj index e22c9f1..d99cddd 100644 --- a/DataVis.vcxproj +++ b/DataVis.vcxproj @@ -214,6 +214,7 @@ + @@ -401,6 +402,7 @@ + diff --git a/DataVis.vcxproj.filters b/DataVis.vcxproj.filters index 0a63ffa..b6d447d 100644 --- a/DataVis.vcxproj.filters +++ b/DataVis.vcxproj.filters @@ -460,6 +460,9 @@ opengl + + plot + @@ -1047,5 +1050,8 @@ opengl + + plot + \ No newline at end of file diff --git a/src/3d/KuPrimitiveFactory.h b/src/3d/KuPrimitiveFactory.h index 9e0f624..d182c0e 100644 --- a/src/3d/KuPrimitiveFactory.h +++ b/src/3d/KuPrimitiveFactory.h @@ -26,6 +26,17 @@ public: static int makeBox(const point3& lower, const point3& upper, void* obuf, unsigned stride = 0); + // gridquads + // + // gridnx*ny㹹ɣд洢˳£ + // 0, 1, ..., ny-1, + // ny, ny + 1, ..., 2*ny-1, + // ... + // (nx-1)*ny, ..., nx*ny-1 + // + template + static int makeIndexGrid(unsigned nx, unsigned ny, IDX_TYPE* obuf); + private: KuPrimitiveFactory() = delete; }; @@ -144,3 +155,32 @@ int KuPrimitiveFactory::makeBox(const point3& lower, const point3& upper, void* return 8; } } + + +template +int KuPrimitiveFactory::makeIndexGrid(unsigned nx, unsigned ny, IDX_TYPE* obuf) +{ + int count = (nx - 1) * (ny - 1) * 4; // gridquads + + if (obuf) { + for(unsigned i = 1; i < nx; i++) + for (unsigned j = 1; j < ny; j++) { + + if constexpr (!CCW) { + *obuf++ = static_cast((i - 1) * ny + (j - 1)); + *obuf++ = static_cast((i - 1) * ny + j); + *obuf++ = static_cast(i * ny + j); + *obuf++ = static_cast(i * ny + (j - 1)); + } + else { + *obuf++ = static_cast((i - 1) * ny + (j - 1)); + *obuf++ = static_cast(i * ny + (j - 1)); + *obuf++ = static_cast(i * ny + j); + *obuf++ = static_cast((i - 1) * ny + j); + } + + } + } + + return count; +} diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 21c3fd7..219a137 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -79,8 +79,6 @@ void KcImOglPaint::endPaint() KcImOglPaint::point3 KcImOglPaint::toNdc_(const point3& pt) const { auto p = camera_.localToNdc(pt); - - // opengl̶ĬNDCϵpĽϵҪzֵȡ??? return { p.x(), p.y(), p.z() }; } @@ -263,7 +261,7 @@ void KcImOglPaint::pushTextVbo_(KpRenderList_& rl) { if (!rl.texts.empty()) { auto obj = new KcRenderObject(k_quads); - obj->setShader(KsShaderManager::singleton().programColorUV()); + obj->setShader(KsShaderManager::singleton().programSmoothUV()); auto decl = std::make_shared(); decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); @@ -286,6 +284,7 @@ void KcImOglPaint::drawGeom(vtx_decl_ptr decl, geom_ptr geom) assert(geom->vertexSize() == decl->vertexSize()); bool hasNormal = decl->hasNormal(); + bool hasColor = decl->hasColor(); KcRenderObject* obj = hasNormal ? new KcLightenObject(geom->type()) : new KcRenderObject(geom->type()); @@ -293,8 +292,11 @@ void KcImOglPaint::drawGeom(vtx_decl_ptr decl, geom_ptr geom) //((KcLightenObject*)obj)->setNormalMatrix(camera_.getNormalMatrix()); ((KcLightenObject*)obj)->setNormalMatrix(mat4::identity()); } + else if (hasColor) { + obj->setShader(KsShaderManager::singleton().programSmooth()); + } else { - obj->setShader(KsShaderManager::singleton().programMono()); // ȱʡshader + obj->setShader(KsShaderManager::singleton().programFlat()); // ȱʡshader } auto vbo = std::make_shared(); @@ -389,7 +391,7 @@ void KcImOglPaint::drawRenderList_() glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glDisable(GL_DEPTH_TEST); + glDisable(GL_DEPTH_TEST); // depthTestijֵӦ unsigned viewport(-1), clipRect(-1), clipBox(-2); bool depthTest(false); diff --git a/src/opengl/KcLightenObject.cpp b/src/opengl/KcLightenObject.cpp index c34720c..9b29010 100644 --- a/src/opengl/KcLightenObject.cpp +++ b/src/opengl/KcLightenObject.cpp @@ -8,7 +8,7 @@ KcLightenObject::KcLightenObject(KePrimitiveType type) : super_(type) { - prog_ = KsShaderManager::singleton().programMonoLight(); + prog_ = KsShaderManager::singleton().programFlatLight(); } diff --git a/src/opengl/KcLineObject.cpp b/src/opengl/KcLineObject.cpp index 7d0d909..3e262d9 100644 --- a/src/opengl/KcLineObject.cpp +++ b/src/opengl/KcLineObject.cpp @@ -6,7 +6,7 @@ KcLineObject::KcLineObject(KePrimitiveType type) : super_(type) { - prog_ = KsShaderManager::singleton().programMono(); + prog_ = KsShaderManager::singleton().programFlat(); } diff --git a/src/opengl/KcPointObject.cpp b/src/opengl/KcPointObject.cpp index 90568e5..9c92708 100644 --- a/src/opengl/KcPointObject.cpp +++ b/src/opengl/KcPointObject.cpp @@ -6,7 +6,7 @@ KcPointObject::KcPointObject() : super_(k_points) { - prog_ = KsShaderManager::singleton().programMono(); + prog_ = KsShaderManager::singleton().programFlat(); } diff --git a/src/opengl/KsShaderManager.cpp b/src/opengl/KsShaderManager.cpp index 3bda577..d6ef6d1 100644 --- a/src/opengl/KsShaderManager.cpp +++ b/src/opengl/KsShaderManager.cpp @@ -16,9 +16,9 @@ KsShaderManager::~KsShaderManager() } -KsShaderManager::shader_ptr KsShaderManager::vertexShaderMono() +KsShaderManager::shader_ptr KsShaderManager::vertexShaderFlat() { - const static char* vertex_shader_mono = + const static char* vertex_shader_flat = "uniform mat4 matMvp;\n" "uniform vec4 vColor;\n" "uniform int iEnableClip;\n" @@ -41,18 +41,54 @@ KsShaderManager::shader_ptr KsShaderManager::vertexShaderMono() " }\n" "}\n"; - if (vertexShaderMono_ == nullptr) { - vertexShaderMono_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_mono); - assert(vertexShaderMono_->compileStatus()); + if (vertexShaderFlat_ == nullptr) { + vertexShaderFlat_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_flat); + auto info = vertexShaderFlat_->infoLog(); + assert(vertexShaderFlat_->compileStatus()); } - return vertexShaderMono_; + return vertexShaderFlat_; } -KsShaderManager::shader_ptr KsShaderManager::vertexShaderColorUV() +KsShaderManager::shader_ptr KsShaderManager::vertexShaderSmooth() { - const static char* vertex_shader_color_uv = + const static char* vertex_shader_smooth = + "uniform mat4 matMvp;\n" + "uniform int iEnableClip;\n" + "uniform vec3 vClipLower;\n" + "uniform vec3 vClipUpper;\n" + "in vec3 iPosition;\n" + "in vec4 iColor;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_Position = matMvp * vec4(iPosition, 1);\n" + " Frag_Color = iColor;\n" + " if (iEnableClip != 0)\n" + " {\n" + " gl_ClipDistance[0] = iPosition.x - vClipLower.x;\n" + " gl_ClipDistance[1] = iPosition.y - vClipLower.y;\n" + " gl_ClipDistance[2] = iPosition.z - vClipLower.z;\n" + " gl_ClipDistance[3] = vClipUpper.x - iPosition.x;\n" + " gl_ClipDistance[4] = vClipUpper.y - iPosition.y;\n" + " gl_ClipDistance[5] = vClipUpper.z - iPosition.z;\n" + " }\n" + "}\n"; + + if (vertexShaderSmooth_ == nullptr) { + vertexShaderSmooth_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_smooth); + auto info = vertexShaderSmooth_->infoLog(); + assert(vertexShaderSmooth_->compileStatus()); + } + + return vertexShaderSmooth_; +} + + +KsShaderManager::shader_ptr KsShaderManager::vertexShaderSmoothUV() +{ + const static char* vertex_shader_smooth_uv = "uniform mat4 matMvp;\n" "layout (location = 0) in vec3 iPosition;\n" "layout (location = 1) in vec2 iUV;\n" @@ -66,18 +102,19 @@ KsShaderManager::shader_ptr KsShaderManager::vertexShaderColorUV() " Frag_Color = iColor;\n" "}\n"; - if (vertexShaderColorUV_ == nullptr) { - vertexShaderColorUV_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_color_uv); - assert(vertexShaderColorUV_->compileStatus()); + if (vertexShaderSmoothUV_ == nullptr) { + vertexShaderSmoothUV_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_smooth_uv); + auto info = vertexShaderSmoothUV_->infoLog(); + assert(vertexShaderSmoothUV_->compileStatus()); } - return vertexShaderColorUV_; + return vertexShaderSmoothUV_; } -KsShaderManager::shader_ptr KsShaderManager::vertexShaderMonoLight() +KsShaderManager::shader_ptr KsShaderManager::vertexShaderFlatLight() { - const static char* vertex_shader_mono_light = + const static char* vertex_shader_flat_light = "uniform mat4 matMvp;\n" "uniform mat4 matNormal;\n" "uniform vec4 vColor;\n" @@ -106,37 +143,37 @@ KsShaderManager::shader_ptr KsShaderManager::vertexShaderMonoLight() " }\n" "}\n"; - if (vertexShaderMonoLight_ == nullptr) { - vertexShaderMonoLight_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_mono_light); - auto log = vertexShaderMonoLight_->infoLog(); - assert(vertexShaderMonoLight_->compileStatus()); + if (vertexShaderFlatLight_ == nullptr) { + vertexShaderFlatLight_ = std::make_shared(KcGlslShader::k_shader_vertex, vertex_shader_flat_light); + auto info = vertexShaderFlatLight_->infoLog(); + assert(vertexShaderFlatLight_->compileStatus()); } - return vertexShaderMonoLight_; + return vertexShaderFlatLight_; } -KsShaderManager::shader_ptr KsShaderManager::fragShaderNaive() +KsShaderManager::shader_ptr KsShaderManager::fragShaderFlat() { - const static char* frag_shader_naive = + const static char* frag_shader_flat = "varying vec4 Frag_Color;\n" "void main()\n" "{\n" " gl_FragColor = Frag_Color;\n" "}\n"; - if (fragShaderNaive_ == nullptr) { - fragShaderNaive_ = std::make_shared(KcGlslShader::k_shader_fragment, frag_shader_naive); - assert(fragShaderNaive_->compileStatus()); + if (fragShaderFlat_ == nullptr) { + fragShaderFlat_ = std::make_shared(KcGlslShader::k_shader_fragment, frag_shader_flat); + assert(fragShaderFlat_->compileStatus()); } - return fragShaderNaive_; + return fragShaderFlat_; } -KsShaderManager::shader_ptr KsShaderManager::fragShaderColorUV() +KsShaderManager::shader_ptr KsShaderManager::fragShaderSmoothUV() { - const static char* frag_shader_color_uv = + const static char* frag_shader_smooth_uv = "uniform sampler2D Texture;\n" "varying vec2 Frag_UV;\n" "varying vec4 Frag_Color;\n" @@ -145,53 +182,67 @@ KsShaderManager::shader_ptr KsShaderManager::fragShaderColorUV() " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" "}\n"; - if (fragShaderColorUV_ == nullptr) { - fragShaderColorUV_ = std::make_shared(KcGlslShader::k_shader_fragment, frag_shader_color_uv); - assert(fragShaderColorUV_->compileStatus()); + if (fragShaderSmoothUV_ == nullptr) { + fragShaderSmoothUV_ = std::make_shared(KcGlslShader::k_shader_fragment, frag_shader_smooth_uv); + assert(fragShaderSmoothUV_->compileStatus()); + } + + return fragShaderSmoothUV_; +} + + +KsShaderManager::program_ptr KsShaderManager::programFlat() +{ + if (progFlat_ == nullptr) { + progFlat_ = std::make_shared(); + progFlat_->attachShader(vertexShaderFlat()); + progFlat_->attachShader(fragShaderFlat()); + progFlat_->link(); + assert(progFlat_->linked() && progFlat_->linkStatus()); } - return fragShaderColorUV_; + return progFlat_; } -KsShaderManager::program_ptr KsShaderManager::programMono() +KsShaderManager::program_ptr KsShaderManager::programSmooth() { - if (progMono_ == nullptr) { - progMono_ = std::make_shared(); - progMono_->attachShader(vertexShaderMono()); - progMono_->attachShader(fragShaderNaive()); - progMono_->link(); - assert(progMono_->linked() && progMono_->linkStatus()); + if (progSmooth_ == nullptr) { + progSmooth_ = std::make_shared(); + progSmooth_->attachShader(vertexShaderSmooth()); + progSmooth_->attachShader(fragShaderFlat()); + progSmooth_->link(); + assert(progSmooth_->linked() && progSmooth_->linkStatus()); } - return progMono_; + return progSmooth_; } -KsShaderManager::program_ptr KsShaderManager::programColorUV() +KsShaderManager::program_ptr KsShaderManager::programSmoothUV() { - if (progColorUV_ == nullptr) { - progColorUV_ = std::make_shared(); - progColorUV_->attachShader(vertexShaderColorUV()); - progColorUV_->attachShader(fragShaderColorUV()); - progColorUV_->link(); - assert(progColorUV_->linked() && progColorUV_->linkStatus()); + if (progSmoothUV_ == nullptr) { + progSmoothUV_ = std::make_shared(); + progSmoothUV_->attachShader(vertexShaderSmoothUV()); + progSmoothUV_->attachShader(fragShaderSmoothUV()); + progSmoothUV_->link(); + assert(progSmoothUV_->linked() && progSmoothUV_->linkStatus()); } - return progColorUV_; + return progSmoothUV_; } -KsShaderManager::program_ptr KsShaderManager::programMonoLight() +KsShaderManager::program_ptr KsShaderManager::programFlatLight() { - if (progMonoLight_ == nullptr) { - progMonoLight_ = std::make_shared(); - progMonoLight_->attachShader(vertexShaderMonoLight()); - progMonoLight_->attachShader(fragShaderNaive()); - progMonoLight_->link(); - auto info = progMonoLight_->infoLog(); - assert(progMonoLight_->linked() && progMonoLight_->linkStatus()); + if (progFlatLight_ == nullptr) { + progFlatLight_ = std::make_shared(); + progFlatLight_->attachShader(vertexShaderFlatLight()); + progFlatLight_->attachShader(fragShaderFlat()); + progFlatLight_->link(); + auto info = progFlatLight_->infoLog(); + assert(progFlatLight_->linked() && progFlatLight_->linkStatus()); } - return progMonoLight_; + return progFlatLight_; } \ No newline at end of file diff --git a/src/opengl/KsShaderManager.h b/src/opengl/KsShaderManager.h index a716bce..2663544 100644 --- a/src/opengl/KsShaderManager.h +++ b/src/opengl/KsShaderManager.h @@ -20,32 +20,41 @@ public: using shader_ptr = std::shared_ptr; using program_ptr = std::shared_ptr; + // жͬɫɫֵuniformvColorȷ // attr = pos // uniform = matMvp + vColor - shader_ptr vertexShaderMono(); + shader_ptr vertexShaderFlat(); - // attr = pos + uv + color + // ɫɫֵattributeȷ + // attr = pos + color // uniform = matMvp - shader_ptr vertexShaderColorUV(); + shader_ptr vertexShaderSmooth(); + + // attr = pos + color + uv + // uniform = matMvp + shader_ptr vertexShaderSmoothUV(); // attr = pos + normal // uniform = matMvp + matNormal + vColor - shader_ptr vertexShaderMonoLight(); + shader_ptr vertexShaderFlatLight(); // out-color = in-color - shader_ptr fragShaderNaive(); + shader_ptr fragShaderFlat(); // out-color = in-color * tex(uv) - shader_ptr fragShaderColorUV(); + shader_ptr fragShaderSmoothUV(); + + // vertexShaderFlat + fragShaderFlat + program_ptr programFlat(); - // vertexShaderMono_ + fragShaderNaive_ - program_ptr programMono(); + // vertexShaderSmooth + fragShaderFlat + program_ptr programSmooth(); - // vertexShaderColorUV_ + fragShaderColorUV_ - program_ptr programColorUV(); + // vertexShaderSmoothUV + fragShaderSmoothUV + program_ptr programSmoothUV(); - // vertexShaderMonoLight_ + fragShaderNaive_ - program_ptr programMonoLight(); + // vertexShaderFlatLight + fragShaderFlat + program_ptr programFlatLight(); private: KsShaderManager(); @@ -57,13 +66,15 @@ private: private: - shader_ptr vertexShaderMono_; - shader_ptr vertexShaderColorUV_; - shader_ptr vertexShaderMonoLight_; - shader_ptr fragShaderNaive_; - shader_ptr fragShaderColorUV_; - - program_ptr progMono_; - program_ptr progColorUV_; - program_ptr progMonoLight_; + shader_ptr vertexShaderFlat_; + shader_ptr vertexShaderSmooth_; + shader_ptr vertexShaderSmoothUV_; + shader_ptr vertexShaderFlatLight_; + shader_ptr fragShaderFlat_; + shader_ptr fragShaderSmoothUV_; + + program_ptr progFlat_; + program_ptr progSmooth_; + program_ptr progSmoothUV_; + program_ptr progFlatLight_; }; diff --git a/src/plot/KcColorMap.cpp b/src/plot/KcColorMap.cpp index 07c0e5e..bb9819c 100644 --- a/src/plot/KcColorMap.cpp +++ b/src/plot/KcColorMap.cpp @@ -102,21 +102,21 @@ void KcColorMap::drawDiscreted_(KvPaint* paint, KvDiscreted* disc) const dy = disc->range(1).length() / disc->size(disc->dim() > 1 ? 1 : 0); auto half_dx = dx / 2; - auto hfalf_dy = dy /2 ; + auto half_dy = dy /2 ; for (unsigned i = 0; i < disc->size(); i++) { auto pt = disc->pointAt(i, 0); paint->setColor(mapValueToColor_(pt.back())); - paint->fillRect({ pt[0] - half_dx, pt[1] - hfalf_dy, 0 }, - { pt[0] + half_dx, pt[1] + hfalf_dy, 0 }); + paint->fillRect({ pt[0] - half_dx, pt[1] - half_dy, 0 }, + { pt[0] + half_dx, pt[1] + half_dy, 0 }); } if (showBorder_ && clrBorder_.a() != 0) { paint->setColor(clrBorder_); for (unsigned i = 0; i < disc->size(); i++) { auto pt = disc->pointAt(i, 0); - paint->drawRect({ pt[0] - half_dx, pt[1] - hfalf_dy, 0 }, - { pt[0] + half_dx, pt[1] + hfalf_dy, 0 }); + paint->drawRect({ pt[0] - half_dx, pt[1] - half_dy, 0 }, + { pt[0] + half_dx, pt[1] + half_dy, 0 }); } } diff --git a/src/plot/KcSurface.cpp b/src/plot/KcSurface.cpp new file mode 100644 index 0000000..d3d7eac --- /dev/null +++ b/src/plot/KcSurface.cpp @@ -0,0 +1,46 @@ +#include "KcSurface.h" +#include "KvPaint.h" +#include "KvSampled.h" +#include "KtGeometryImpl.h" +#include "KcVertexDeclaration.h" +#include "KuPrimitiveFactory.h" + + +void KcSurface::drawDiscreted_(KvPaint* paint, KvDiscreted* disc) const +{ + auto samp = dynamic_cast(disc); + assert(samp && samp->dim() == 2); + + auto nx = samp->size(0); + auto ny = samp->size(1); + + struct KpVtxBuffer_ + { + point3f pos; + point4f clr; + }; + + auto mesh = std::make_shared>(k_quads); + auto vtx = mesh->newVertex(nx* ny); + auto vtxBuf = vtx; + + for(unsigned i = 0; i < nx; i++) + for (unsigned j = 0; j < ny; j++) { + auto pt = samp->point(i, j, 0); + vtxBuf->pos = point3f(pt[0], pt[1], pt[2]); + vtxBuf->clr = mapValueToColor_(pt[2]); + ++vtxBuf; + } + + auto idxCount = KuPrimitiveFactory::makeIndexGrid(nx, ny, nullptr); + auto idxBuf = mesh->newIndex(idxCount); + KuPrimitiveFactory::makeIndexGrid(nx, ny, idxBuf); + + auto decl = std::make_shared(); + decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); + decl->pushAttribute(KcVertexAttribute::k_float4, KcVertexAttribute::k_diffuse); + + paint->enableDepthTest(true); + paint->drawGeom(decl, mesh); + paint->enableDepthTest(false); +} diff --git a/src/plot/KcSurface.h b/src/plot/KcSurface.h new file mode 100644 index 0000000..8526567 --- /dev/null +++ b/src/plot/KcSurface.h @@ -0,0 +1,17 @@ +#pragma once +#include "KcColorMap.h" + + +// sampled2dݵ3d + +class KcSurface : public KcColorMap +{ + using super_ = KcColorMap; + +public: + using super_::super_; + + +private: + void drawDiscreted_(KvPaint*, KvDiscreted*) const final; +}; diff --git a/src/plot/KvPlottable.cpp b/src/plot/KvPlottable.cpp index b32cf5d..b0824ee 100644 --- a/src/plot/KvPlottable.cpp +++ b/src/plot/KvPlottable.cpp @@ -66,7 +66,7 @@ void KvPlottable::draw(KvPaint* paint) const return; for (unsigned i = 0; i < cont->dim(); i++) - samp->reset(0, cont->range(i).low(), cont->length(i) / sampCount_[i]); + samp->reset(i, cont->range(i).low(), cont->length(i) / sampCount_[i]); disc = samp; } diff --git a/src/plot/KvPlottable.h b/src/plot/KvPlottable.h index 96395af..7b8917b 100644 --- a/src/plot/KvPlottable.h +++ b/src/plot/KvPlottable.h @@ -7,6 +7,9 @@ class KvData; class KvDiscreted; +// ɻƶij +// ʵֶݵIJֻɢ + class KvPlottable : public KvRenderable { public: diff --git a/src/prov/KcPvData.cpp b/src/prov/KcPvData.cpp index a848048..b611da7 100644 --- a/src/prov/KcPvData.cpp +++ b/src/prov/KcPvData.cpp @@ -10,7 +10,7 @@ KcPvData::KcPvData(const std::string_view& name, std::shared_ptr data) : KvDataProvider(name), data_(data) { updateSpec_(); - valueRange_ = data->valueRange(); + valueRange_ = data ? data->valueRange() : kRange(0, 0); } diff --git a/src/render/KcRdPlot3d.cpp b/src/render/KcRdPlot3d.cpp index d3f2d33..bbbca4a 100644 --- a/src/render/KcRdPlot3d.cpp +++ b/src/render/KcRdPlot3d.cpp @@ -3,6 +3,7 @@ #include "plot/KcGraph.h" #include "plot/KcScatter.h" #include "plot/KcBars3d.h" +#include "plot/KcSurface.h" #include "plot/KvCoord.h" // TODO: ˴KvCoordļ #include "prov/KvDataProvider.h" #include "KuStrUtil.h" @@ -79,7 +80,7 @@ void KcRdPlot3d::showProperySet() unsigned KcRdPlot3d::supportPlottableTypes_() const { - return 3; + return 4; } @@ -91,6 +92,8 @@ int KcRdPlot3d::plottableType_(KvPlottable* plt) const return 1; else if (dynamic_cast(plt)) return 2; + else if (dynamic_cast(plt)) + return 3; return -1; } @@ -101,7 +104,7 @@ const char* KcRdPlot3d::plottableTypeStr_(int iType) const assert(iType < supportPlottableTypes_()); static const char* pltTypes[] = { - "graph", "scatter", "bar" + "graph", "scatter", "bar", "surface" }; return pltTypes[iType]; @@ -120,6 +123,9 @@ KvPlottable* KcRdPlot3d::newPlottable_(int iType, const std::string& name) case 2: return new KcBars3d(name); + + case 3: + return new KcSurface(name); } return nullptr; -- Gitee From 39ae9408bbef2c8815a400eb0393a3f95abc8502 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Wed, 28 Dec 2022 11:02:19 +0800 Subject: [PATCH 42/68] =?UTF-8?q?add:=20=E5=9D=90=E6=A0=87=E8=BD=B4?= =?UTF-8?q?=E7=9A=84=E5=B1=9E=E6=80=A7=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/imguix.cpp | 94 ++++++++++++++++++++------ src/imapp/imguix.h | 17 +++++ src/op/KcOpSampler.cpp | 17 ++--- src/prov/KvDataProvider.cpp | 14 ++-- src/render/KcRdPlot3d.cpp | 14 +--- src/render/KvRdPlot.cpp | 128 ++++++++++++++++++++++++++---------- src/render/KvRdPlot.h | 3 + 7 files changed, 204 insertions(+), 83 deletions(-) diff --git a/src/imapp/imguix.cpp b/src/imapp/imguix.cpp index 383c4b5..ac36604 100644 --- a/src/imapp/imguix.cpp +++ b/src/imapp/imguix.cpp @@ -4,6 +4,8 @@ #include "KvDiscreted.h" #include "KcSampled2d.h" #include "layout/KeAlignment.h" +#include "misc/cpp/imgui_stdlib.h" +#include "plot/KpContext.h" namespace kPrivate @@ -66,6 +68,19 @@ namespace kPrivate return headers; } + static void switchAlign(KeAlignment& curAlign, int newAlign) + { + if (curAlign.location() == newAlign) + curAlign.toggleAlginFirst(); + else + curAlign.setLocation(newAlign); + + if (curAlign & KeAlignment::k_hcenter) + curAlign.setAlignFirst(KeAlignment::k_vert_first); + else if (curAlign & KeAlignment::k_vcenter) + curAlign.setAlignFirst(KeAlignment::k_horz_first); + } + } @@ -274,23 +289,51 @@ namespace ImGuiX return res; } + bool treePush(const char* label, bool defaultOpen) + { + return ImGui::TreeNodeEx(label, + defaultOpen ? ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_FramePadding + : ImGuiTreeNodeFlags_FramePadding); + } - static void switchAlign(KeAlignment& curAlign, int newAlign) + void treePop() { - if (curAlign.location() == newAlign) - curAlign.toggleAlginFirst(); - else - curAlign.setLocation(newAlign); + ImGui::TreePop(); + } - if (curAlign & KeAlignment::k_hcenter) - curAlign.setAlignFirst(KeAlignment::k_vert_first); - else if (curAlign & KeAlignment::k_vcenter) - curAlign.setAlignFirst(KeAlignment::k_horz_first); + bool cbTreePush(const char* label, bool* show, bool* open) + { + std::string node("##N"); node += label; + *open = treePush(node.c_str(), *open); + ImGui::SameLine(); + return ImGui::Checkbox(label, show); + } + + void cbTreePop() + { + ImGui::TreePop(); + } + + bool cbInputText(const char* label, bool* show, std::string* text) + { + std::string box("##I"); box += label; + bool res = prefixCheckbox(box.c_str(), show); + res |= ImGui::InputText(label, text); + ImGui::PopItemWidth(); + return res; + } + + bool cbiTreePush(const char* label, bool* show, std::string* text, bool* open) + { + std::string node("##N"); node += label; + *open = treePush(node.c_str(), *open); + ImGui::SameLine(); + return cbInputText(label, show, text); } bool alignment(const char* label, KeAlignment& loc) { - if (ImGui::TreeNodeEx(label, ImGuiTreeNodeFlags_FramePadding)) { + if (treePush(label, false)) { ImVec2 itemSize(ImGui::CalcTextSize("Outter").x * 2, 0); @@ -298,18 +341,18 @@ namespace ImGuiX int spacing = 12; if (ImGui::Button(loc & KeAlignment::k_vert_first ? "NW" : "WN", itemSize)) - switchAlign(loc, KeAlignment::k_left | KeAlignment::k_top); + kPrivate::switchAlign(loc, KeAlignment::k_left | KeAlignment::k_top); ImGui::SameLine(0, spacing); if (ImGui::Button("N", itemSize)) - switchAlign(loc, KeAlignment::k_top | KeAlignment::k_hcenter); + kPrivate::switchAlign(loc, KeAlignment::k_top | KeAlignment::k_hcenter); ImGui::SameLine(0, spacing); if (ImGui::Button(loc & KeAlignment::k_vert_first ? "NE" : "EN", itemSize)) - switchAlign(loc, KeAlignment::k_right | KeAlignment::k_top); + kPrivate::switchAlign(loc, KeAlignment::k_right | KeAlignment::k_top); if (ImGui::Button("W", itemSize)) - switchAlign(loc, KeAlignment::k_left | KeAlignment::k_vcenter); + kPrivate::switchAlign(loc, KeAlignment::k_left | KeAlignment::k_vcenter); ImGui::SameLine(0, spacing); if (ImGui::Button(outter ? "Out" : "In", itemSize)) @@ -317,24 +360,37 @@ namespace ImGuiX ImGui::SameLine(0, spacing); if (ImGui::Button("E", itemSize)) - switchAlign(loc, KeAlignment::k_right | KeAlignment::k_vcenter); + kPrivate::switchAlign(loc, KeAlignment::k_right | KeAlignment::k_vcenter); if (ImGui::Button(loc & KeAlignment::k_vert_first ? "SW" : "WS", itemSize)) - switchAlign(loc, KeAlignment::k_left | KeAlignment::k_bottom); + kPrivate::switchAlign(loc, KeAlignment::k_left | KeAlignment::k_bottom); ImGui::SameLine(0, spacing); if (ImGui::Button("S", itemSize)) - switchAlign(loc, KeAlignment::k_bottom | KeAlignment::k_hcenter); + kPrivate::switchAlign(loc, KeAlignment::k_bottom | KeAlignment::k_hcenter); ImGui::SameLine(0, spacing); if (ImGui::Button(loc & KeAlignment::k_vert_first ? "SE" : "ES", itemSize)) - switchAlign(loc, KeAlignment::k_right | KeAlignment::k_bottom); + kPrivate::switchAlign(loc, KeAlignment::k_right | KeAlignment::k_bottom); - ImGui::TreePop(); + treePop(); return true; } return false; } + + bool pen(KpPen* cxt) + { + ImGui::PushID(cxt); + + bool res = ImGui::SliderFloat("Width", &cxt->width, 0.1, 5.0, "%.1f"); + res |= ImGui::ColorEdit4("Color", cxt->color); + ; + ImGui::PopID(); + + return res; + } + } \ No newline at end of file diff --git a/src/imapp/imguix.h b/src/imapp/imguix.h index 52b26e6..e99a474 100644 --- a/src/imapp/imguix.h +++ b/src/imapp/imguix.h @@ -5,6 +5,7 @@ #include "../plot/KtColor.h" class KvData; +class KpPen; class KeAlignment; // imguiչ @@ -54,4 +55,20 @@ namespace ImGuiX bool prefixCheckbox(const char* label, bool* v); bool alignment(const char* label, KeAlignment& align); + + bool treePush(const char* label, bool defaultOpen); + + void treePop(); + + // treenode + checkbox + label + bool cbTreePush(const char* label, bool* show, bool* open); + + void cbTreePop(); + + // treenode + checkbox + text-editor + label + bool cbiTreePush(const char* label, bool* show, std::string* text, bool* open); + + bool cbInputText(const char* label, bool* show, std::string* text); + + bool pen(KpPen* cxt); } diff --git a/src/op/KcOpSampler.cpp b/src/op/KcOpSampler.cpp index 152b2ce..ca10e7d 100644 --- a/src/op/KcOpSampler.cpp +++ b/src/op/KcOpSampler.cpp @@ -1,17 +1,10 @@ #include "KcOpSampler.h" #include "dsp/KcSampler.h" -#include "imgui.h" +#include "imguix.h" #include "KuStrUtil.h" #include "KtSampling.h" #include "KtuMath.h" -namespace kPrivate -{ - bool TreePush(const char* label); - - void TreePop(); -} - KcOpSampler::KcOpSampler() : super_("Sampler") @@ -144,7 +137,7 @@ void KcOpSampler::showProperySet() } } else { - if (kPrivate::TreePush("Sample Count")) { + if (ImGuiX::treePush("Sample Count", true)) { for (kIndex i = 0; i < dim(0); i++) { std::string label("Dim"); label += KuStrUtil::toString(i + 1); @@ -154,7 +147,7 @@ void KcOpSampler::showProperySet() sampleCountChanged_(); } } - kPrivate::TreePop(); + ImGuiX::treePop(); } } } @@ -169,7 +162,7 @@ void KcOpSampler::showProperySet() } } else { - if (kPrivate::TreePush("Sample Rate")) { + if (ImGuiX::treePush("Sample Rate", true)) { for (kIndex i = 0; i < dim(0); i++) { std::string label("Dim"); label += KuStrUtil::toString(i + 1); @@ -180,7 +173,7 @@ void KcOpSampler::showProperySet() sampleCountChanged_(); } } - kPrivate::TreePop(); + ImGuiX::treePop(); } } } diff --git a/src/prov/KvDataProvider.cpp b/src/prov/KvDataProvider.cpp index 03661c6..8ac7519 100644 --- a/src/prov/KvDataProvider.cpp +++ b/src/prov/KvDataProvider.cpp @@ -1,6 +1,6 @@ #include "KvDataProvider.h" #include -#include "imgui.h" +#include "imguix.h" #include "imapp/KcImDataView.h" #include "imapp/KsImApp.h" #include "imapp/KgImWindowManager.h" @@ -167,13 +167,13 @@ void KvDataProvider::showProperySet() std::string label = "Size(total = "; label += KuStrUtil::toString(total(outPort)); label += ")"; - if (kPrivate::TreePush(label.c_str())) { + if (ImGuiX::treePush(label.c_str(), true)) { for (kIndex i = 0; i < dim(outPort); i++) { std::string label("Dim"); label += KuStrUtil::toString(i + 1); ImGui::LabelText(label.c_str(), "%d", size(outPort, i)); } - kPrivate::TreePop(); + ImGuiX::treePop(); } } } @@ -184,13 +184,13 @@ void KvDataProvider::showProperySet() ImGui::LabelText("Step", "%g", step(outPort, 0)); ImGui::LabelText("Frequency", "%g", 1.0 / step(outPort, 0)); } - else if (kPrivate::TreePush("Step")) { + else if (ImGuiX::treePush("Step", true)) { for (kIndex i = 0; i < dim(outPort); i++) { std::string label("Dim"); label += KuStrUtil::toString(i + 1); ImGui::LabelText(label.c_str(), "%g", step(outPort, i)); } - kPrivate::TreePop(); + ImGuiX::treePop(); } } @@ -200,14 +200,14 @@ void KvDataProvider::showProperySet() ImGui::LabelText("Value Range", "%g - %g", range(outPort, dim(outPort)).low(), range(outPort, dim(outPort)).high()); } - else if (kPrivate::TreePush("Range")) { + else if (ImGuiX::treePush("Range", true)) { for (kIndex i = 0; i <= dim(outPort); i++) { std::string label("Dim"); label += KuStrUtil::toString(i + 1); ImGui::LabelText(label.c_str(), "%g - %g", range(outPort, i).low(), range(outPort, i).high()); } - kPrivate::TreePop(); + ImGuiX::treePop(); } } diff --git a/src/render/KcRdPlot3d.cpp b/src/render/KcRdPlot3d.cpp index d3f2d33..f29f477 100644 --- a/src/render/KcRdPlot3d.cpp +++ b/src/render/KcRdPlot3d.cpp @@ -6,15 +6,7 @@ #include "plot/KvCoord.h" // TODO: ˴KvCoordļ #include "prov/KvDataProvider.h" #include "KuStrUtil.h" -#include "imgui.h" - - -namespace kPrivate -{ - bool TreePush(const char* label); - - void TreePop(); -} +#include "imguix.h" KcRdPlot3d::KcRdPlot3d() @@ -43,7 +35,7 @@ void KcRdPlot3d::showProperySet() { super_::showProperySet(); - if (!kPrivate::TreePush("Projection")) + if (!ImGuiX::treePush("Projection", true)) return; auto plot3d = std::dynamic_pointer_cast(plot_); @@ -73,7 +65,7 @@ void KcRdPlot3d::showProperySet() orient = quatd(rot); } - kPrivate::TreePop(); + ImGuiX::treePop(); } diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index 3c9d7e0..23cf0ec 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -20,20 +20,6 @@ #include "KcSampled2d.h" -namespace kPrivate -{ - bool TreePush(const char* label) - { - return ImGui::TreeNodeEx(label, ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_FramePadding); - } - - void TreePop() - { - ImGui::TreePop(); - } -} - - KvRdPlot::KvRdPlot(const std::string_view& name, const std::shared_ptr& plot) : KvDataRender(name) , plot_(plot) @@ -247,7 +233,7 @@ void KvRdPlot::showProperySet() void KvRdPlot::showPlotProperty_() { - if (kPrivate::TreePush("Plot")) { + if (ImGuiX::treePush("Plot", true)) { bool vis = plot_->visible(); if (ImGuiX::prefixCheckbox("##Plot", &vis)) plot_->setVisible(vis); @@ -260,7 +246,7 @@ void KvRdPlot::showPlotProperty_() auto& coord = plot_->coord(); const char* label[] = { "Invert X", "Invert Y", "Invert Z" }; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < plot_->dim(); i++) { bool inv = coord.axisInversed(i); if (ImGui::Checkbox(label[i], &inv)) coord.inverseAxis(i, inv); @@ -268,14 +254,15 @@ void KvRdPlot::showPlotProperty_() const char* swapStr[] = { "No Swap", "Swap XY", "Swap XZ", "Swap YZ" }; if (ImGui::BeginCombo("Swap Axes", swapStr[coord.axisSwapped()])) { - for (unsigned i = 0; i < std::size(swapStr); i++) + unsigned c = plot_->dim() > 2 ? std::size(swapStr) : plot_->dim(); + for (unsigned i = 0; i < c; i++) if (ImGui::Selectable(swapStr[i], i == coord.axisSwapped())) coord.swapAxis(KvCoord::KeAxisSwapStatus(i)); ImGui::EndCombo(); } - kPrivate::TreePop(); + ImGuiX::treePop(); } } @@ -286,7 +273,7 @@ void KvRdPlot::showThemeProperty_() if (themeMgr.empty()) return; - if (!kPrivate::TreePush("Design")) + if (!ImGuiX::treePush("Design", true)) return; auto groups = themeMgr.listGroups(); @@ -342,13 +329,13 @@ void KvRdPlot::showThemeProperty_() ImGui::EndCombo(); } - kPrivate::TreePop(); + ImGuiX::treePop(); } void KvRdPlot::showCoordProperty_() { - if (!kPrivate::TreePush("Axes")) + if (!ImGuiX::treePush("Axes", true)) return; auto lower = point3f(plot_->coord().lower()); @@ -359,25 +346,98 @@ void KvRdPlot::showCoordProperty_() speed.at(i) = 1; bool extendsChanged(false); - if (ImGui::DragFloatRange2("X", &lower.x(), &upper.x(), speed.x())) - extendsChanged = true; - if (ImGui::DragFloatRange2("Y", &lower.y(), &upper.y(), speed.y())) - extendsChanged = true; - if (ImGui::DragFloatRange2("Z", &lower.z(), &upper.z(), speed.z())) - extendsChanged = true; + static const char* axisName[] = { "X", "Y", "Z" }; + for (char i = 0; i < plot_->dim(); i++) { + if (ImGui::DragFloatRange2(axisName[i], &lower[i], &upper[i], speed[i])) + extendsChanged = true; + } if (extendsChanged) { plot_->coord().setExtents(lower, upper); plot_->autoFit() = false; } - kPrivate::TreePop(); + plot_->coord().forAxis([this](KcAxis& axis) { + ShowAxisProperty_(axis); + return true; + }); + + ImGuiX::treePop(); +} + + +void KvRdPlot::ShowAxisProperty_(KcAxis& axis) +{ + static const char* name[] = { "X", "Y", "Z" }; + static const char* loc[] = { + "near-left", + "near-right", + "near-bottom", + "near-top", + + "far-left", + "far-right", + "far-bottom", + "far-top", + + "floor-left", + "floor-right", + "ceil-left", + "ceil-right", + }; + + std::string label = name[axis.dim()]; label += "["; label += loc[axis.type()]; label += "]"; + + bool open = false; + ImGuiX::cbTreePush(label.c_str(), &axis.visible(), &open); + if (!open) return; + + ImGui::PushID(&axis); + + open = false; + ImGuiX::cbTreePush("Baseline", &axis.showBaseline(), &open); + if (open) { + ImGuiX::pen(&axis.baselineContext()); + ImGuiX::cbTreePop(); + } + + open = false; + ImGuiX::cbTreePush("Title", &axis.showTitle(), &open); + if (open) { + ImGui::InputText("Text", &axis.title()); + ImGui::ColorEdit4("Color##title", axis.titleColor()); + ImGuiX::cbTreePop(); + } + + open = false; + ImGuiX::cbTreePush("Tick", &axis.showTick(), &open); + if (open) { + ImGuiX::pen(&axis.tickContext()); + ImGuiX::cbTreePop(); + } + + open = false; + ImGuiX::cbTreePush("Subtick", &axis.showSubtick(), &open); + if (open) { + ImGuiX::pen(&axis.subtickContext()); + ImGuiX::cbTreePop(); + } + + open = false; + ImGuiX::cbTreePush("Label", &axis.showLabel(), &open); + if (open) { + ImGui::ColorEdit4("Color##label", axis.labelColor()); + ImGuiX::cbTreePop(); + } + + ImGui::PopID(); + ImGuiX::cbTreePop(); } void KvRdPlot::showLegendProperty_() { - if (!kPrivate::TreePush("Legend")) + if (!ImGuiX::treePush("Legend", true)) return; ImGui::Checkbox("Show", &plot_->showLegend()); @@ -385,14 +445,14 @@ void KvRdPlot::showLegendProperty_() auto& loc = plot_->legend()->location(); ImGuiX::alignment("Alignment", loc); - kPrivate::TreePop(); + ImGuiX::treePop(); } void KvRdPlot::showColorBarProperty_() { - if (!kPrivate::TreePush("ColorBar")) + if (!ImGuiX::treePush("ColorBar", true)) return; ImGui::Checkbox("Show", &plot_->showColorBar()); @@ -400,7 +460,7 @@ void KvRdPlot::showColorBarProperty_() auto& loc = plot_->colorBar()->location(); ImGuiX::alignment("Alignment", loc); - kPrivate::TreePop(); + ImGuiX::treePop(); } @@ -408,7 +468,7 @@ void KvRdPlot::showPlottableProperty_() { if (plot_->plottableCount() > 0) { - if (!kPrivate::TreePush("Plottable(s)")) + if (!ImGuiX::treePush("Plottable(s)", false)) return; for (unsigned idx = 0; idx < plot_->plottableCount(); idx++) { @@ -450,7 +510,7 @@ void KvRdPlot::showPlottableProperty_() } } - kPrivate::TreePop(); + ImGuiX::treePop(); } } diff --git a/src/render/KvRdPlot.h b/src/render/KvRdPlot.h index f7b0cb3..ad3eab5 100644 --- a/src/render/KvRdPlot.h +++ b/src/render/KvRdPlot.h @@ -5,6 +5,7 @@ #include "KuStrUtil.h" class KvPlot; +class KcAxis; class KvPlottable; class KvDataProvider; class KvThemedPlot; @@ -66,6 +67,8 @@ protected: virtual void showCoordProperty_(); + virtual void ShowAxisProperty_(KcAxis&); + virtual void showLegendProperty_(); virtual void showColorBarProperty_(); -- Gitee From e6bcfbc2327103c58a29c774b86f167d1bd935c1 Mon Sep 17 00:00:00 2001 From: koala999 Date: Wed, 28 Dec 2022 12:21:03 +0800 Subject: [PATCH 43/68] =?UTF-8?q?fix:=20color-bar=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcCoord3d.cpp | 7 +++++++ src/plot/KvPlot.cpp | 1 + 2 files changed, 8 insertions(+) diff --git a/src/plot/KcCoord3d.cpp b/src/plot/KcCoord3d.cpp index 11aebde..fdf830e 100644 --- a/src/plot/KcCoord3d.cpp +++ b/src/plot/KcCoord3d.cpp @@ -171,6 +171,13 @@ void KcCoord3d::placeElement(KvLayoutElement* ele, KeAlignment loc) assert(!isAncestorOf(ele)); ele->align() = loc; // TODO ȫһ£ʱ򵥴 + + for(unsigned i = 0; i < layCoord_->size(); i++) + if (layCoord_->getAt(i) == 0) { + layCoord_->setAt(i, ele); + return; + } + layCoord_->append(ele); } diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index 2a4a4a6..c3b911e 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -84,6 +84,7 @@ void KvPlot::removeAllPlottables() { assert(legend_); if (colorBar_) { + KuLayoutHelper::take(colorBar_); delete colorBar_; colorBar_ = nullptr; } -- Gitee From e64735304aae6d0cba3f4685e8cfaa7d4aaf8788 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Wed, 28 Dec 2022 16:07:43 +0800 Subject: [PATCH 44/68] =?UTF-8?q?fix:=203d=E5=9D=90=E6=A0=87=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E7=9A=84=E5=9D=90=E6=A0=87=E8=BD=B4typeReal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcAxis.cpp | 67 ++++++++++++++++++++--------------------- src/plot/KcAxis.h | 7 ++--- src/plot/KvCoord.cpp | 9 +++--- src/render/KvRdPlot.cpp | 47 +++++++++++++++-------------- 4 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 4a334be..341594a 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -209,7 +209,7 @@ KcAxis::point3 KcAxis::tickPos(double val) const KcAxis::size_t KcAxis::calcSize_(void* cxt) const { - assert(visible() && length() > 0); + assert(visible() && length() > 0 && dimReal_ < 2); auto paint = (KvPaint*)cxt; @@ -271,44 +271,43 @@ bool KcAxis::tickAndLabelInSameSide_() const KcAxis::KeType KcAxis::typeReal() const { - // ͽ - //constexpr static int swapType[4][3][3] = { - /// KcAxis::k_near_left - //{ - // /*dim0*/ { KcAxis::k_near_left, KcAxis::k_near_bottom, -1 }, - // /*dim1*/ { KcAxis::k_near_left, KcAxis::k_near_bottom, -1 }, - //}, - /// KcAxis::k_near_right - - /// KcAxis::k_near_bottom - - /// KcAxis::k_near_top - //}; - - //return swapType[type_][dimReal_][dimSwapped_]; + enum KeSwapKind + { + swap_none, + swap_xy, + swap_xz, + swap_yz + }; + + // dimReal_dimSwapped_ȡswapKind + // ʹ[dimReal_][dimSwapped_ + 1] + constexpr static int swapKind[3][4] = { + { swap_yz, swap_none, swap_xy, swap_xz }, + { swap_xz, swap_xy, swap_none, swap_yz }, + { swap_xy, swap_xz, swap_yz, swap_none } + }; + // NBάȵύҲӰ쵱ǰķλĿǰδʵֽµķλһ constexpr static int swapType[][4] = { /* swap_none */ /* swap_xy */ /* swap_xz */ /* swap_yz */ - { KcAxis::k_near_left, KcAxis::k_near_bottom, -1, KcAxis::k_ceil_left }, - { KcAxis::k_near_right, KcAxis::k_near_top , -1, KcAxis::k_ceil_right }, - { KcAxis::k_near_bottom, KcAxis::k_near_left, KcAxis::k_floor_right, -1 }, - { KcAxis::k_near_top, KcAxis::k_near_right, KcAxis::k_ceil_right, -1 }, - - { KcAxis::k_far_left, KcAxis::k_far_bottom, -1, KcAxis::k_floor_left }, - { KcAxis::k_far_right, KcAxis::k_far_top, -1, KcAxis::k_floor_right }, - { KcAxis::k_far_bottom, KcAxis::k_far_left, KcAxis::k_floor_left, -1 }, - { KcAxis::k_far_top, KcAxis::k_far_right, KcAxis::k_ceil_left, -1 }, - - { KcAxis::k_floor_left, -1, KcAxis::k_far_bottom, KcAxis::k_far_left }, - { KcAxis::k_floor_right, -1, KcAxis::k_near_bottom, KcAxis::k_far_right }, - { KcAxis::k_ceil_left, -1, KcAxis::k_far_top, KcAxis::k_near_left }, - { KcAxis::k_ceil_right, -1, KcAxis::k_near_top, KcAxis::k_near_right } + { KcAxis::k_near_left, KcAxis::k_near_bottom, KcAxis::k_far_right, KcAxis::k_ceil_left }, + { KcAxis::k_near_right, KcAxis::k_near_top , KcAxis::k_far_left, KcAxis::k_ceil_right }, + { KcAxis::k_near_bottom, KcAxis::k_near_left, KcAxis::k_floor_right, KcAxis::k_far_top }, + { KcAxis::k_near_top, KcAxis::k_near_right, KcAxis::k_ceil_right, KcAxis::k_far_bottom }, + + { KcAxis::k_far_left, KcAxis::k_far_bottom, KcAxis::k_near_right, KcAxis::k_floor_left }, + { KcAxis::k_far_right, KcAxis::k_far_top, KcAxis::k_near_left, KcAxis::k_floor_right }, + { KcAxis::k_far_bottom, KcAxis::k_far_left, KcAxis::k_floor_left, KcAxis::k_near_top }, + { KcAxis::k_far_top, KcAxis::k_far_right, KcAxis::k_ceil_left, KcAxis::k_near_bottom }, + + { KcAxis::k_floor_left, KcAxis::k_ceil_right, KcAxis::k_far_bottom, KcAxis::k_far_left }, + { KcAxis::k_floor_right, KcAxis::k_ceil_left, KcAxis::k_near_bottom, KcAxis::k_far_right }, + { KcAxis::k_ceil_left, KcAxis::k_floor_right, KcAxis::k_far_top, KcAxis::k_near_left }, + { KcAxis::k_ceil_right, KcAxis::k_floor_left, KcAxis::k_near_top, KcAxis::k_near_right } }; - - // TODO: ʱֻǶά - assert(dimReal_ < 2 && dimSwapped_ < 2); - return KeType(swapType[type_][swapped() ? 1 : 0]); + auto t = swapType[type_][swapKind[dimReal_][dimSwapped_ + 1]]; + return KeType(t); } diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index 83ac088..ff3f93e 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -185,12 +185,11 @@ public: bool inversed() const { return inv_; } void setInversed(bool inv) { inv_ = inv; } - bool swapped() const { return dimReal_ != dimSwapped_; } - void setSwapped(int dimSwap) { dimSwapped_ = dimSwap; } - - int dimSwapped() const { return dimSwapped_; } // ؽά KeType typeReal() const; // swapaxisʵλ + // ڲʹ + void setSwapped_(int dimSwap) { dimSwapped_ = dimSwap; } + private: void draw_(KvPaint*, bool calcBox) const; void drawTicks_(KvPaint*, bool calcBox) const; // п̶ diff --git a/src/plot/KvCoord.cpp b/src/plot/KvCoord.cpp index c8186fc..26404ac 100644 --- a/src/plot/KvCoord.cpp +++ b/src/plot/KvCoord.cpp @@ -232,15 +232,16 @@ void KvCoord::swapAxis(KeAxisSwapStatus status) if (swapStatus_ == status) return; + // NB: -1ʾάн constexpr static int swapped[][3] = { { 0, 1, 2 }, // k_axis_swap_none - { 1, 0, 2 }, // k_axis_swap_xy - { 2, 1, 0 }, // k_axis_swap_xz - { 0, 2, 1 } // k_axis_swap_yz + { 1, 0, -1 }, // k_axis_swap_xy + { 2, -1, 0 }, // k_axis_swap_xz + { -1, 2, 1 } // k_axis_swap_yz }; forAxis([status](KcAxis& axis) { - axis.setSwapped(swapped[status][axis.dim()]); + axis.setSwapped_(swapped[status][axis.dim()]); return true; }); diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index 23cf0ec..7de9523 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -242,9 +242,29 @@ void KvRdPlot::showPlotProperty_() ImGui::ColorEdit4("Background", plot_->background().color); - ImGui::Checkbox("Auto Fit", &plot_->autoFit()); - auto& coord = plot_->coord(); + + if (ImGuiX::treePush("Range", true)) { + ImGui::Checkbox("Auto Fit", &plot_->autoFit()); + + auto lower = point3f(coord.lower()); + auto upper = point3f(coord.upper()); + auto speed = (upper - lower) * 0.1; + for (unsigned i = 0; i < speed.size(); i++) + if (speed.at(i) == 0) + speed.at(i) = 1; + + static const char* axisName[] = { "X", "Y", "Z" }; + for (char i = 0; i < plot_->dim(); i++) { + if (ImGui::DragFloatRange2(axisName[i], &lower[i], &upper[i], speed[i])) { + coord.setExtents(lower, upper); + plot_->autoFit() = false; + } + } + + ImGuiX::treePop(); + } + const char* label[] = { "Invert X", "Invert Y", "Invert Z" }; for (int i = 0; i < plot_->dim(); i++) { bool inv = coord.axisInversed(i); @@ -335,28 +355,9 @@ void KvRdPlot::showThemeProperty_() void KvRdPlot::showCoordProperty_() { - if (!ImGuiX::treePush("Axes", true)) + if (!ImGuiX::treePush("Axes", false)) return; - auto lower = point3f(plot_->coord().lower()); - auto upper = point3f(plot_->coord().upper()); - auto speed = (upper - lower) * 0.1; - for (unsigned i = 0; i < speed.size(); i++) - if (speed.at(i) == 0) - speed.at(i) = 1; - - bool extendsChanged(false); - static const char* axisName[] = { "X", "Y", "Z" }; - for (char i = 0; i < plot_->dim(); i++) { - if (ImGui::DragFloatRange2(axisName[i], &lower[i], &upper[i], speed[i])) - extendsChanged = true; - } - - if (extendsChanged) { - plot_->coord().setExtents(lower, upper); - plot_->autoFit() = false; - } - plot_->coord().forAxis([this](KcAxis& axis) { ShowAxisProperty_(axis); return true; @@ -386,7 +387,7 @@ void KvRdPlot::ShowAxisProperty_(KcAxis& axis) "ceil-right", }; - std::string label = name[axis.dim()]; label += "["; label += loc[axis.type()]; label += "]"; + std::string label = name[axis.dim()]; label += " ["; label += loc[axis.typeReal()]; label += "]"; bool open = false; ImGuiX::cbTreePush(label.c_str(), &axis.visible(), &open); -- Gitee From 73ffaee64c87aa7e6b3c77ddbcef6e6e0732a1fd Mon Sep 17 00:00:00 2001 From: koala999cn Date: Wed, 28 Dec 2022 17:12:08 +0800 Subject: [PATCH 45/68] =?UTF-8?q?add:=20=E6=9B=B4=E5=A4=9A=E7=9A=84?= =?UTF-8?q?=E5=9D=90=E6=A0=87=E8=BD=B4=E5=B1=9E=E6=80=A7=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/imguix.cpp | 24 +++++++++++++++++++++--- src/imapp/imguix.h | 2 +- src/plot/KcAxis.cpp | 2 +- src/plot/KcAxis.h | 2 +- src/render/KvRdPlot.cpp | 22 +++++++++++++++++----- src/render/KvRdPlot.h | 2 +- 6 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/imapp/imguix.cpp b/src/imapp/imguix.cpp index ac36604..b977d44 100644 --- a/src/imapp/imguix.cpp +++ b/src/imapp/imguix.cpp @@ -381,13 +381,31 @@ namespace ImGuiX return false; } - bool pen(KpPen* cxt) + bool pen(KpPen* cxt, bool showStyle) { ImGui::PushID(cxt); - bool res = ImGui::SliderFloat("Width", &cxt->width, 0.1, 5.0, "%.1f"); + bool res = false; + + if (showStyle) { + static const char* styles[] = { + "none", "solid", "dot", "dash", + "dash4", "dash8", "dash dot", "dash dot dot" + }; + + if (ImGui::BeginCombo("Style", styles[cxt->style])) { + for (unsigned i = 0; i < std::size(styles); i++) { + if (ImGui::Selectable(styles[i], i == cxt->style)) + cxt->style = i; + } + + ImGui::EndCombo(); + } + } + + res |= ImGui::SliderFloat("Width", &cxt->width, 0.1, 5.0, "%.1f px"); res |= ImGui::ColorEdit4("Color", cxt->color); - ; + ImGui::PopID(); return res; diff --git a/src/imapp/imguix.h b/src/imapp/imguix.h index e99a474..07b73d0 100644 --- a/src/imapp/imguix.h +++ b/src/imapp/imguix.h @@ -70,5 +70,5 @@ namespace ImGuiX bool cbInputText(const char* label, bool* show, std::string* text); - bool pen(KpPen* cxt); + bool pen(KpPen* cxt, bool showStyle); } diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 341594a..076b1f9 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -50,7 +50,7 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const box_ = aabb_t(start(), end()); // draw baseline - if (showBaseline() && !calcBox) { + if (showBaseline() && baselineCxt_.style != KpPen::k_none && !calcBox) { paint->apply(baselineCxt_); paint->drawLine(start(), end()); // } diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index ff3f93e..c4b6158 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -57,7 +57,7 @@ public: struct KpTickContext : public KpPen { - double length; + float length; KpPen& operator=(const KpPen& pen) { style = pen.style; diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index 7de9523..882b55c 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -359,7 +359,7 @@ void KvRdPlot::showCoordProperty_() return; plot_->coord().forAxis([this](KcAxis& axis) { - ShowAxisProperty_(axis); + showAxisProperty_(axis); return true; }); @@ -367,7 +367,19 @@ void KvRdPlot::showCoordProperty_() } -void KvRdPlot::ShowAxisProperty_(KcAxis& axis) +namespace kPrivate +{ + void tickContext(KcAxis::KpTickContext& cxt) + { + ImGuiX::pen(&cxt, false); // no style. tickʼʹsolid + + ImGui::PushID(&cxt); + ImGui::SliderFloat("Length", &cxt.length, 0, 10, "%0.1f px"); + ImGui::PopID(); + } +} + +void KvRdPlot::showAxisProperty_(KcAxis& axis) { static const char* name[] = { "X", "Y", "Z" }; static const char* loc[] = { @@ -398,7 +410,7 @@ void KvRdPlot::ShowAxisProperty_(KcAxis& axis) open = false; ImGuiX::cbTreePush("Baseline", &axis.showBaseline(), &open); if (open) { - ImGuiX::pen(&axis.baselineContext()); + ImGuiX::pen(&axis.baselineContext(), true); ImGuiX::cbTreePop(); } @@ -413,14 +425,14 @@ void KvRdPlot::ShowAxisProperty_(KcAxis& axis) open = false; ImGuiX::cbTreePush("Tick", &axis.showTick(), &open); if (open) { - ImGuiX::pen(&axis.tickContext()); + kPrivate::tickContext(axis.tickContext()); ImGuiX::cbTreePop(); } open = false; ImGuiX::cbTreePush("Subtick", &axis.showSubtick(), &open); if (open) { - ImGuiX::pen(&axis.subtickContext()); + kPrivate::tickContext(axis.subtickContext()); ImGuiX::cbTreePop(); } diff --git a/src/render/KvRdPlot.h b/src/render/KvRdPlot.h index ad3eab5..05601a6 100644 --- a/src/render/KvRdPlot.h +++ b/src/render/KvRdPlot.h @@ -67,7 +67,7 @@ protected: virtual void showCoordProperty_(); - virtual void ShowAxisProperty_(KcAxis&); + virtual void showAxisProperty_(KcAxis&); virtual void showLegendProperty_(); -- Gitee From c03b0403ccda074123e6463495b09ed200e9db48 Mon Sep 17 00:00:00 2001 From: koala999 Date: Wed, 28 Dec 2022 19:34:04 +0800 Subject: [PATCH 46/68] =?UTF-8?q?add:=20opengl=E7=89=88=E7=9A=84fillBetwee?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 102 ++++++++++++++++++++++++++++-------- src/imapp/KcImOglPaint.h | 3 ++ src/opengl/KcRenderObject.h | 16 ++++++ 3 files changed, 98 insertions(+), 23 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 58157eb..ddc3c69 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -3,6 +3,7 @@ #include "imgui_internal.h" #include "glad.h" #include "KcVertexDeclaration.h" +#include "KtLineS2d.h" #include "opengl/KcGlslProgram.h" #include "opengl/KcGlslShader.h" #include "opengl/KcGpuBuffer.h" @@ -127,15 +128,8 @@ void KcImOglPaint::drawPoints(point_getter fn, unsigned count) vbo->setData(vtx.data(), vtx.size() * sizeof(point3f), KcGpuBuffer::k_stream_draw); obj->setVBO(vbo, decl); - obj->setColor(clr_); obj->setSize(pointSize_); - obj->setProjMatrix(camera_.getMvpMat()); - if (curClipBox_ != -1) { - auto& box = clipBoxHistList_[curClipBox_]; - obj->setClipBox({ box.lower(), box.upper() }); - } - - currentRenderList().objs.emplace_back(obj); + pushRenderObject_(obj); } @@ -187,14 +181,89 @@ void KcImOglPaint::drawLineStrip(point_getter fn, unsigned count) vbo->setData(vtx.data(), vtx.size() * sizeof(point3f), KcGpuBuffer::k_stream_draw); obj->setVBO(vbo, decl); - obj->setColor(clr_); obj->setWidth(lineWidth_); + pushRenderObject_(obj); +} + + +void KcImOglPaint::fillBetween(point_getter fn1, point_getter fn2, unsigned count) +{ + // vbo + + auto vbo = std::make_shared(); + + std::vector vtx; + vtx.reserve((count - 1) * 6); // ÿ2Σ6 + + auto p00 = fn1(0); + auto p01 = fn2(0); + + assert(p00.z() == p01.z()); // Ҫ㶼һzƽ + + for (unsigned i = 1; i < count; i++) { + auto p10 = fn1(i); + auto p11 = fn2(i); + + using point2 = KtPoint; + KtLineS2d ln0((const point2&)p00, (const point2&)p10); + KtLineS2d ln1((const point2&)p01, (const point2&)p11); + auto pt = ln0.intersects(ln1); + if (pt) { // ཻ + + float3 ptm(pt->x(), pt->y(), p00.z()); + + vtx.push_back(p01); + vtx.push_back(p00); + vtx.push_back(ptm); + + vtx.push_back(p10); + vtx.push_back(p11); + vtx.push_back(ptm); + } + else { // ཻ + vtx.push_back(p01); + vtx.push_back(p00); + vtx.push_back(p10); + + vtx.push_back(p10); + vtx.push_back(p11); + vtx.push_back(p01); + } + + p00 = p10, p01 = p11; + } + + vbo->setData(vtx.data(), vtx.size() * sizeof(float3), KcGpuBuffer::k_stream_draw); + + auto obj = new KcRenderObject(k_triangles); + + auto decl = std::make_shared(); + decl->pushAttribute(KcVertexAttribute::k_float3, KcVertexAttribute::k_position); + + obj->setVBO(vbo, decl); + pushRenderObject_(obj); +} + + +void KcImOglPaint::pushRenderObject_(KcRenderObject* obj) +{ + assert(obj->vbo() && obj->vertexDecl()); + + obj->setColor(clr_); obj->setProjMatrix(camera_.getMvpMat()); if (curClipBox_ != -1) { auto& box = clipBoxHistList_[curClipBox_]; obj->setClipBox({ box.lower(), box.upper() }); } + if (obj->shader() == nullptr) { // Զshader + auto decl = obj->vertexDecl(); + if (!decl->hasColor()) + obj->setShader(KsShaderManager::singleton().programFlat()); + else + obj->setShader(KsShaderManager::singleton().programSmooth()); + } + currentRenderList().objs.emplace_back(obj); } @@ -308,12 +377,6 @@ void KcImOglPaint::drawGeom(vtx_decl_ptr decl, geom_ptr geom) //((KcLightenObject*)obj)->setNormalMatrix(camera_.getNormalMatrix()); ((KcLightenObject*)obj)->setNormalMatrix(mat4::identity()); } - else if (hasColor) { - obj->setShader(KsShaderManager::singleton().programSmooth()); - } - else { - obj->setShader(KsShaderManager::singleton().programFlat()); // ȱʡshader - } auto vbo = std::make_shared(); vbo->setData(geom->vertexData(), geom->vertexCount() * geom->vertexSize(), KcGpuBuffer::k_stream_draw); @@ -325,14 +388,7 @@ void KcImOglPaint::drawGeom(vtx_decl_ptr decl, geom_ptr geom) obj->setIBO(ibo, geom->indexCount()); } - obj->setColor(clr_); - obj->setProjMatrix(camera_.getMvpMat()); - if (curClipBox_ != -1) { - auto& box = clipBoxHistList_[curClipBox_]; - obj->setClipBox({ box.lower(), box.upper() }); - } - - currentRenderList().objs.emplace_back(obj); + pushRenderObject_(obj); } diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index c95e978..e24c338 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -53,6 +53,7 @@ public: void drawGeom(vtx_decl_ptr decl, geom_ptr geom) override; + void fillBetween(point_getter line1, point_getter line2, unsigned count) override; // ڲImGuiصԻrenderList_Ⱦ void drawRenderList_(); @@ -61,6 +62,8 @@ private: point3 toNdc_(const point3& pt) const; + void pushRenderObject_(KcRenderObject* obj); + private: // render states stacks diff --git a/src/opengl/KcRenderObject.h b/src/opengl/KcRenderObject.h index 9824ac0..956dcc5 100644 --- a/src/opengl/KcRenderObject.h +++ b/src/opengl/KcRenderObject.h @@ -23,14 +23,30 @@ public: : type_(rhs.type_), prog_(rhs.prog_), vbo_(rhs.vbo_), ibo_(rhs.ibo_), vtxDecl_(rhs.vtxDecl_), indexCount_(rhs.indexCount_) {} + std::shared_ptr shader() const { + return prog_; + } + void setShader(std::shared_ptr prog) { prog_ = prog; } + std::shared_ptr vbo() const { + return vbo_; + } + + std::shared_ptr vertexDecl() const { + return vtxDecl_; + } + void setVBO(std::shared_ptr vbo, std::shared_ptr vtxDecl) { vbo_ = vbo, vtxDecl_ = vtxDecl; } + std::shared_ptr ibo() const { + return ibo_; + } + void setIBO(std::shared_ptr ibo, unsigned idxCount) { ibo_ = ibo, indexCount_ = idxCount; } -- Gitee From 9dc4c1414b43dc2aa5df99ea4a0467c264afb59a Mon Sep 17 00:00:00 2001 From: koala999cn Date: Thu, 29 Dec 2022 08:50:04 +0800 Subject: [PATCH 47/68] =?UTF-8?q?fix:=20=E5=B1=8F=E5=B9=95=E5=9D=90?= =?UTF-8?q?=E6=A0=87=E4=B8=8B=E7=9A=84=E5=9D=90=E6=A0=87=E8=BD=B4=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 23 ++++++++++++++++++++--- src/plot/KcCoord2d.cpp | 11 ----------- src/plot/KcCoord2d.h | 2 -- src/plot/KvPlot.cpp | 4 ++-- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index ddc3c69..dc843bb 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -82,11 +82,28 @@ void KcImOglPaint::endPaint() super_::endPaint(); } - +#include "KtuMath.h" KcImOglPaint::point3 KcImOglPaint::toNdc_(const point3& pt) const { - auto p = camera_.localToNdc(pt); - return { p.x(), p.y(), p.z() }; + switch (currentCoord()) + { + case k_coord_world: + { + auto p = camera_.localToNdc(pt); + p.z() = KtuMath::clamp(p.z(), -1, 1); // FIXME: plot2dڴ˴zᳬ޷ʾ + return { p.x(), p.y(), p.z() }; + } + + case k_coord_screen: + { + auto p = camera_.localToWorld(pt); + p = camera_.screenToNdc(p); + return { p.x(), p.y(), p.z() }; + } + } + + assert(false); + return point3(0); } diff --git a/src/plot/KcCoord2d.cpp b/src/plot/KcCoord2d.cpp index 320d9ce..76fb106 100644 --- a/src/plot/KcCoord2d.cpp +++ b/src/plot/KcCoord2d.cpp @@ -78,17 +78,6 @@ void KcCoord2d::forPlane(std::function fn) const } -void KcCoord2d::draw(KvPaint* paint) const -{ - if (visible()) { - auto oldVp = paint->viewport(); - //paint->setViewport(plane_->innerRect()); - KvCoord::draw(paint); - //paint->setViewport(oldVp); // restore the old viewport - } -} - - KtMargins KcCoord2d::calcMargins_(KvPaint* paint) const { auto l = axes_[KcAxis::k_left].front()->calcMargins(paint); diff --git a/src/plot/KcCoord2d.h b/src/plot/KcCoord2d.h index 9a8438d..647bcd7 100644 --- a/src/plot/KcCoord2d.h +++ b/src/plot/KcCoord2d.h @@ -31,8 +31,6 @@ public: void placeElement(KvLayoutElement* ele, KeAlignment loc) final; - void draw(KvPaint*) const final; - axis_list& axes(int type) { return axes_[type]; } private: diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index c3b911e..0f89f6f 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -266,8 +266,8 @@ void KvPlot::syncLegendAndColorBar_(KvPlottable* removedPlt, KvPlottable* addedP legend_->addItem(addedPlt); } else { - assert(colorBar_ == nullptr); // TODO: ͨ - if (colorBar_) { + // assert(colorBar_ == nullptr); + if (colorBar_) { // TODO: δcolor-bar KuLayoutHelper::take(colorBar_); delete colorBar_; } -- Gitee From 68bf8357804fcf7d9089e2daed6de56476114176 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Thu, 29 Dec 2022 09:47:05 +0800 Subject: [PATCH 48/68] add: line-filled graph in 3d space --- src/plot/KcAxis.h | 4 ++-- src/render/KcRdPlot3d.cpp | 34 +++++++++++++++++++++++++++++----- src/render/KcRdPlot3d.h | 1 + src/render/KvRdPlot.cpp | 10 +++++++--- src/render/KvRdPlot.h | 3 +++ 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index c4b6158..df3b52c 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -214,8 +214,8 @@ private: KpPen baselineCxt_; KpTickContext tickCxt_, subtickCxt_; - double labelPadding_{ 2 }; - double titlePadding_{ 2 }; + float labelPadding_{ 2 }; + float titlePadding_{ 2 }; color4f labelColor_{ 0, 0, 0, 1 }, titleColor_{ 0, 0, 0, 1 }; diff --git a/src/render/KcRdPlot3d.cpp b/src/render/KcRdPlot3d.cpp index ec55f94..d4573c5 100644 --- a/src/render/KcRdPlot3d.cpp +++ b/src/render/KcRdPlot3d.cpp @@ -2,6 +2,7 @@ #include "imapp/KcImPlot3d.h" #include "plot/KcGraph.h" #include "plot/KcScatter.h" +#include "plot/KcLineFilled.h" #include "plot/KcBars3d.h" #include "plot/KcSurface.h" #include "plot/KvCoord.h" // TODO: ˴KvCoordļ @@ -72,7 +73,7 @@ void KcRdPlot3d::showProperySet() unsigned KcRdPlot3d::supportPlottableTypes_() const { - return 4; + return 5; } @@ -82,10 +83,12 @@ int KcRdPlot3d::plottableType_(KvPlottable* plt) const return 0; else if (dynamic_cast(plt)) return 1; - else if (dynamic_cast(plt)) + else if (dynamic_cast(plt)) return 2; - else if (dynamic_cast(plt)) + else if (dynamic_cast(plt)) return 3; + else if (dynamic_cast(plt)) + return 4; return -1; } @@ -96,7 +99,7 @@ const char* KcRdPlot3d::plottableTypeStr_(int iType) const assert(iType < supportPlottableTypes_()); static const char* pltTypes[] = { - "graph", "scatter", "bar", "surface" + "graph", "scatter", "line-filled", "bar", "surface" }; return pltTypes[iType]; @@ -114,11 +117,32 @@ KvPlottable* KcRdPlot3d::newPlottable_(int iType, const std::string& name) return new KcScatter(name); case 2: - return new KcBars3d(name); + return new KcLineFilled(name); case 3: + return new KcBars3d(name); + + case 4: return new KcSurface(name); } return nullptr; } + + +bool KcRdPlot3d::plottableMatchData_(int iType, const KvData& d) const +{ + switch (iType) + { + case 2: + return d.dim() == 1; + + case 4: + return d.dim() == 2; + + default: + break; + } + + return true; +} diff --git a/src/render/KcRdPlot3d.h b/src/render/KcRdPlot3d.h index 13acd50..fc14ad1 100644 --- a/src/render/KcRdPlot3d.h +++ b/src/render/KcRdPlot3d.h @@ -24,5 +24,6 @@ private: KvPlottable* newPlottable_(int iType, const std::string& name) final; + bool plottableMatchData_(int iType, const KvData& d) const final; }; diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index 882b55c..6b3ca79 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -531,10 +531,13 @@ void KvRdPlot::showPlottableProperty_() void KvRdPlot::showPlottableTypeProperty_(unsigned idx) { int type = plottableType_(plot_->plottableAt(idx)); + auto data = plot_->plottableAt(idx)->data(); if (ImGui::BeginCombo("Type", plottableTypeStr_(type))) { - for (int i = 0; i < supportPlottableTypes_(); i++) - if (ImGui::Selectable(plottableTypeStr_(i), i == type)) { + + for (int i = 0; i < supportPlottableTypes_(); i++) { + int flags = plottableMatchData_(i, *data) ? 0 : ImGuiSelectableFlags_Disabled; + if (ImGui::Selectable(plottableTypeStr_(i), i == type, flags)) { auto oldPlt = plot_->plottableAt(idx); auto newPlt = newPlottable_(i, oldPlt->name()); @@ -544,7 +547,7 @@ void KvRdPlot::showPlottableTypeProperty_(unsigned idx) majorColors[c] = oldPlt->majorColor(c); newPlt->setMajorColors(majorColors); if (newPlt->minorColorNeeded() && oldPlt->minorColorNeeded()) - newPlt->setMinorColor(oldPlt->minorColor()); + newPlt->setMinorColor(oldPlt->minorColor()); // clone the data newPlt->setData(oldPlt->data()); @@ -557,6 +560,7 @@ void KvRdPlot::showPlottableTypeProperty_(unsigned idx) plot_->setPlottableAt(idx, newPlt); } + } ImGui::EndCombo(); } diff --git a/src/render/KvRdPlot.h b/src/render/KvRdPlot.h index 05601a6..c9a08dd 100644 --- a/src/render/KvRdPlot.h +++ b/src/render/KvRdPlot.h @@ -98,6 +98,9 @@ protected: // iType͵plottable virtual KvPlottable* newPlottable_(int iType, const std::string& name) = 0; + // iType͵plottableǷ֧KvData + virtual bool plottableMatchData_(int iType, const KvData& d) const { return true; } + //////////////////////////////////////////////////// -- Gitee From 9b4e25e3521b34d8488b0cd8ac2798e5c465b33f Mon Sep 17 00:00:00 2001 From: koala999cn Date: Thu, 29 Dec 2022 15:44:17 +0800 Subject: [PATCH 49/68] =?UTF-8?q?add:=20=E7=BB=98=E5=9B=BE=E7=9A=84?= =?UTF-8?q?=E5=8F=8D=E8=B5=B0=E6=A0=B7=E5=B1=9E=E6=80=A7=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imapp/KcImOglPaint.cpp | 23 +++++++++++++++-------- src/imapp/KcImOglPaint.h | 9 ++++++--- src/plot/KvPaint.h | 7 ++++++- src/render/KvRdPlot.cpp | 5 +++++ 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index dc843bb..1eeaf64 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -44,6 +44,7 @@ KcImOglPaint::KcImOglPaint(camera_type& cam) curViewport_ = -1; curClipBox_ = -1; depthTest_ = false; + antialiasing_ = false; } @@ -117,10 +118,6 @@ void KcImOglPaint::drawPoint(const point3& pt) glColor4f(clr.r(), clr.g(), clr.b(), clr.a()); glPointSize(ptSize); - glEnable(GL_POINT_SMOOTH); - glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); - //glEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin(GL_POINTS); glVertex3f(p.x(), p.y(), p.z()); glEnd(); @@ -162,10 +159,7 @@ void KcImOglPaint::drawLine(const point3& from, const point3& to) glLineWidth(lnWidth); glColor4f(clr.r(), clr.g(), clr.b(), clr.a()); - //glEnable(GL_LINE_SMOOTH); - //glHint(GL_LINE_SMOOTH, GL_NICEST); - //glEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (style == KpPen::k_solid) { glDisable(GL_LINE_STIPPLE); } @@ -482,6 +476,19 @@ void KcImOglPaint::drawRenderList_() glLoadIdentity(); glDisable(GL_DEPTH_TEST); // depthTestijֵӦ + if (antialiasing()) { + glEnable(GL_POINT_SMOOTH); + glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); + glEnable(GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH, GL_NICEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glDisable(GL_POINT_SMOOTH); + glDisable(GL_LINE_SMOOTH); + } + unsigned viewport(-1), clipRect(-1), clipBox(-2); bool depthTest(false); for (auto& rd : renderList_) { diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index e24c338..af33f3b 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -34,9 +34,11 @@ public: void enableClipBox(point3 lower, point3 upper) override; void disableClipBox() override; - void enableDepthTest(bool b) override { - depthTest_ = b; - } + void enableDepthTest(bool b) override { depthTest_ = b; } + bool depthTest() const override { return depthTest_; } + + void enableAntialiasing(bool b) override { antialiasing_ = b; } + bool antialiasing() const override { return antialiasing_; } void beginPaint() override; void endPaint() override; @@ -76,6 +78,7 @@ private: unsigned curViewport_; // -1ʾδ unsigned curClipBox_; bool depthTest_; // Ȳԣ + bool antialiasing_; // [0]: viewport idx // [1]: clipRect idx diff --git a/src/plot/KvPaint.h b/src/plot/KvPaint.h index 323343c..47ef02c 100644 --- a/src/plot/KvPaint.h +++ b/src/plot/KvPaint.h @@ -54,7 +54,12 @@ public: virtual void enableClipBox(point3 lower, point3 upper) = 0; virtual void disableClipBox() = 0; - virtual void enableDepthTest(bool b) = 0; + virtual void enableDepthTest(bool b) = 0; // /رȲ + virtual bool depthTest() const = 0; // ǷȲ + + virtual void enableAntialiasing(bool b) = 0; // /رշ + virtual bool antialiasing() const = 0; // Ƿ˷ + // project local point/vector to screen point/vector virtual point4 project(const point4& pt) const = 0; diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index 6b3ca79..a924eab 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -13,6 +13,7 @@ #include "plot/KsThemeManager.h" #include "plot/KcThemedPlotImpl_.h" #include "plot/KvCoord.h" +#include "plot/KvPaint.h" #include "plot/KcLegend.h" #include "plot/KcColorBar.h" #include "KvNode.h" @@ -242,6 +243,10 @@ void KvRdPlot::showPlotProperty_() ImGui::ColorEdit4("Background", plot_->background().color); + bool anti = plot_->paint().antialiasing(); + if (ImGui::Checkbox("Antialiasing", &anti)) + plot_->paint().enableAntialiasing(anti); + auto& coord = plot_->coord(); if (ImGuiX::treePush("Range", true)) { -- Gitee From a8fba33f433fb42c5257fa9714a98851d097628b Mon Sep 17 00:00:00 2001 From: koala999cn Date: Fri, 30 Dec 2022 11:31:05 +0800 Subject: [PATCH 50/68] =?UTF-8?q?add:=20=E5=9D=90=E6=A0=87=E8=BD=B4?= =?UTF-8?q?=E5=88=BB=E5=BA=A6=E7=9A=84=E5=A7=BF=E6=80=81=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base/KtuMath.h | 8 ++++ src/plot/KcAxis.cpp | 57 ++++++++++++++++++++++++--- src/plot/KcAxis.h | 86 +++++++++++++++++++++++------------------ src/plot/KcColorBar.cpp | 4 -- src/plot/KcCoord2d.cpp | 9 ----- src/plot/KcCoord3d.cpp | 27 ------------- src/render/KvRdPlot.cpp | 20 +++++++++- 7 files changed, 128 insertions(+), 83 deletions(-) diff --git a/src/base/KtuMath.h b/src/base/KtuMath.h index 60aa37f..a73ca98 100644 --- a/src/base/KtuMath.h +++ b/src/base/KtuMath.h @@ -71,6 +71,14 @@ public: } + static constexpr KREAL deg2Rad(KREAL d) { + return d * (pi / 180); + } + + static constexpr KREAL rad2Deg(KREAL r) { + return r * (180 / pi); + } + static KREAL mid(KREAL left, KREAL right) { return (left + right) / 2; } // 返回left和right在log域的中值 diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 076b1f9..9bf47e6 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -4,6 +4,7 @@ #include "KvPaint.h" #include "KtuMath.h" #include "KtLine.h" +#include "KtMatrix3.h" #include "layout/KeAlignment.h" #include "layout/KuLayoutUtil.h" @@ -57,10 +58,20 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const auto realShowTitle = showTitle() && !title().empty(); + // tickOrient_labelOrient_ֻһ + if (realShowTitle || showTick() || showLabel()) { + // TODO: if (calcBox) plot3dʱ򲻻üģʽ + tickOrient_ = calcTickOrient_(); + if (paint->currentCoord() == KvPaint::k_coord_screen) + tickOrient_.y() *= -1; // TODO: ޸õķ + labelOrient_ = tickCxt_.side == k_inside ? -tickOrient_ : tickOrient_; + } + + // draw ticks & label if (showTick() || showLabel()) drawTicks_(paint, calcBox); - else if (realShowTitle) + else if (realShowTitle) titleAnchor_ = (start() + end()) / 2 + labelOrient_ * titlePadding_ / paint->projectv(labelOrient_).length(); // draw title @@ -71,6 +82,41 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const } +KcAxis::vec3 KcAxis::calcTickOrient_() const +{ + // 12Ĭ + static const vec3 baseOrient[] = { + -KcAxis::vec3::unitX(), // k_near_left + KcAxis::vec3::unitX(), // k_near_right + -KcAxis::vec3::unitY(), // k_near_bottom + KcAxis::vec3::unitY(), // k_near_top + + -KcAxis::vec3::unitX(), // k_far_left + KcAxis::vec3::unitX(), // k_far_right + -KcAxis::vec3::unitY(), // k_far_bottom + KcAxis::vec3::unitY(), // k_far_top + + -KcAxis::vec3::unitX(), // k_floor_left + KcAxis::vec3::unitX(), // k_floor_right + -KcAxis::vec3::unitX(), // k_ceil_left + KcAxis::vec3::unitX() // k_ceil_right + }; + + vec3 orient = (tickCxt_.side == k_inside) ? -baseOrient[typeReal()] : baseOrient[typeReal()]; + + // ̬תyawpitch + + auto vAxis = (end() - start()).getNormalize(); // ᷽ʸ + KtMatrix3 mat; + mat.fromAngleAxis(tickCxt_.pitch, vAxis); // תpitch + orient = mat * orient; + + auto vPrep = orient.cross(vAxis); // ̶ߺĴֱʸ + mat.fromAngleAxis(tickCxt_.yaw, vPrep.getNormalize()); + return (mat * orient).getNormalize(); +} + + void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const { assert(showTick() || showLabel()); @@ -81,7 +127,6 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const ticker()->generate(lower(), upper(), showSubtick(), showLabel()); const auto& ticks = ticker()->ticks(); - assert(KtuMath::almostEqual(tickOrient().length(), 1)); // Ļ1س߶ȣ൱ٸλ auto tl = paint->projectv(tickOrient_); @@ -161,12 +206,12 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const void KcAxis::drawTick_(KvPaint* paint, const point3& anchor, double length, bool calcBox) const { - auto d = tickOrient() * length; + auto d = tickOrient_ * length; if (!calcBox) - paint->drawLine(tickBothSide() ? anchor - d : anchor, anchor + d); + paint->drawLine(tickCxt_.side == k_bothside ? anchor - d : anchor, anchor + d); else { box_.merge(anchor + d); - if (tickBothSide()) + if (tickCxt_.side == k_bothside) box_.merge(anchor - d); } } @@ -306,6 +351,8 @@ KcAxis::KeType KcAxis::typeReal() const { KcAxis::k_ceil_right, KcAxis::k_floor_left, KcAxis::k_near_top, KcAxis::k_near_right } }; + if (dimReal_ == -1) return type_; // color-barᣬ޽ + auto t = swapType[type_][swapKind[dimReal_][dimSwapped_ + 1]]; return KeType(t); } diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index df3b52c..47abdb9 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -48,16 +48,25 @@ public: k_top = k_near_top }; - enum KeTickOrient + enum KeTextLayout { - k_x, k_neg_x, k_bi_x, - k_y, k_neg_y, k_bi_y, - k_z, k_neg_z, k_bi_z + k_horz_top, // ׼壬ͷϲ࣬ײ² + k_horz_bottom, // µõĺ棬ͷ²࣬ײϲ + k_vert_left, // 棬ͷ࣬ײҲ + k_vert_right // 棬ͷҲ࣬ײ + }; + + enum KeTickSide + { + k_inside, k_outside, k_bothside }; struct KpTickContext : public KpPen { - float length; + float length{ 5 }; + KeTickSide side{ k_outside }; + float yaw{ 0 }; // tickĴֱߵתǶȣȣ + float pitch{ 0 }; // ڻ׼λãתǶȣȣ KpPen& operator=(const KpPen& pen) { style = pen.style; @@ -84,14 +93,14 @@ public: start_ = st, end_ = ed; } - const vec3& tickOrient() const { return tickOrient_; } - vec3& tickOrient() { return tickOrient_; } + //const vec3& tickOrient() const { return tickOrient_; } + //vec3& tickOrient() { return tickOrient_; } - const vec3& labelOrient() const { return labelOrient_; } - vec3& labelOrient() { return labelOrient_; } + //const vec3& labelOrient() const { return labelOrient_; } + //vec3& labelOrient() { return labelOrient_; } - bool tickBothSide() const { return tickBothSide_; } - bool& tickBothSide() { return tickBothSide_; } + //bool tickBothSide() const { return tickBothSide_; } + //bool& tickBothSide() { return tickBothSide_; } /// range @@ -196,6 +205,9 @@ private: void drawTick_(KvPaint*, const point3& anchor, double length, bool calcBox) const; // Ƶ̶ߣ̶븱̶ void drawLabel_(KvPaint* paint, const std::string_view& label, const point3& anchor, bool calcBox) const; + // tickij + vec3 calcTickOrient_() const; + int labelAlignment_(KvPaint* paint, bool toggleTopBottom) const; // labelorientationжlabelalignment bool tickAndLabelInSameSide_() const; // жticktick-labelǷλͬ @@ -214,17 +226,34 @@ private: KpPen baselineCxt_; KpTickContext tickCxt_, subtickCxt_; + // label + // + // ʼ״̬£label-boxλڿ̶ṹɵƽ + // + // label-boxIJ̬anchor + // labelλ࣬anchorλlabel-boxright-center + // labelλҲ࣬anchorλlabel-boxleft-center + // lebelλ²࣬anchorλlabel-boxtop-center + // lebelλϲ࣬anchorλlabel-boxbottom-center + // ڲlabelPadding_£labeltickͬ࣬anchor̶ߵĩغϣ̶ȵغ + float labelPadding_{ 2 }; - float titlePadding_{ 2 }; + KeTextLayout labelLayout_{ k_horz_top }; + color4f labelColor_{ 0, 0, 0, 1 }; + bool labelBillboard_{ true }; // ԹģʽʾlabelʱlabelhDirʼճĻҲ࣬vDirʼճĻ² + //KpFont labelFont_; + float labelYaw_{ 0 }; // label-boxƽĴߣanchor㣩תǶȣȣlabelBillboard_ΪfalseʱЧ + float labelPitch_{ 0 }; //תǶȣȣlabelBillboard_ΪfalseʱЧ - color4f labelColor_{ 0, 0, 0, 1 }, titleColor_{ 0, 0, 0, 1 }; + // title - //QFont labelFont_, titleFont_; + float titlePadding_{ 2 }; + KeTextLayout titleLayout_{ k_horz_top }; + color4f titleColor_{ 0, 0, 0, 1 }; + //KpFont titleFont_; point3 start_, end_; - vec3 tickOrient_; - vec3 labelOrient_; - bool tickBothSide_{ false }; + //bool tickBothSide_{ false }; std::shared_ptr ticker_; @@ -233,28 +262,11 @@ private: bool main_{ true }; // Ƿ bool inv_{ false }; // Ƿת - // ³Աlabel-boxlayoutposeTODO - - // ʼ״̬£label-boxλڿ̶ṹɵƽ - // - // label-boxIJ̬anchor - // labelλ࣬anchorλlabel-boxright-center - // labelλҲ࣬anchorλlabel-boxleft-center - // lebelλ²࣬anchorλlabel-boxtop-center - // lebelλϲ࣬anchorλlabel-boxbottom-center - // ڲlabelPadding_£labeltickͬ࣬anchor̶ߵĩغϣ̶ȵغ - - // ñȷlabel-boxijʼ״̬ - bool labelVertical_{ false }; // true labelıУı˳+y/-z᷽չ - // falselebelıУı˳+x᷽չ - - // ñȷlabel-boxڳʼֵ̬仯 - point3 pose_{ 0, 0, 0 }; // pose_[0]ʾƫyawlabel-boxƽĴߣanchor㣩תǶ - // pose_[1]ʾpitchƽֱߣanchor㣩תǶ - // pose_[2]ʾrollĴߣanchor㣩תǶ - // Ϊߴ㻺ʱ + // + mutable vec3 tickOrient_; + mutable vec3 labelOrient_; std::vector labelSize_; mutable point2 titleSize_; mutable point3 titleAnchor_; // titleıtop-left diff --git a/src/plot/KcColorBar.cpp b/src/plot/KcColorBar.cpp index 0fbd381..6f66f6e 100644 --- a/src/plot/KcColorBar.cpp +++ b/src/plot/KcColorBar.cpp @@ -124,13 +124,9 @@ KcColorBar::size_t KcColorBar::calcSize_(void* cxt) const } if (location() & KeAlignment::k_horz_first) { - axis_->tickOrient() = axis_->labelOrient() = - (location() & KeAlignment::k_right) ? KcAxis::vec3::unitX() : -KcAxis::vec3::unitX(); axis_->setType(location() & KeAlignment::k_right ? KcAxis::k_right : KcAxis::k_left); } else { - axis_->tickOrient() = axis_->labelOrient() = - (location() & KeAlignment::k_bottom) ? KcAxis::vec3::unitY() : -KcAxis::vec3::unitY(); axis_->setType(location() & KeAlignment::k_bottom ? KcAxis::k_bottom : KcAxis::k_top); } diff --git a/src/plot/KcCoord2d.cpp b/src/plot/KcCoord2d.cpp index 76fb106..c615a95 100644 --- a/src/plot/KcCoord2d.cpp +++ b/src/plot/KcCoord2d.cpp @@ -25,15 +25,6 @@ KcCoord2d::KcCoord2d(const point2& lower, const point2& upper) setExtents({ lower.x(), lower.y(), -1 }, { upper.x(), upper.y(), 1 }); - axes_[KcAxis::k_left].front()->tickOrient() = - axes_[KcAxis::k_left].front()->labelOrient() = -KcAxis::vec3::unitX(); - axes_[KcAxis::k_right].front()->tickOrient() = - axes_[KcAxis::k_right].front()->labelOrient() = KcAxis::vec3::unitX(); - axes_[KcAxis::k_bottom].front()->tickOrient() = - axes_[KcAxis::k_bottom].front()->labelOrient() = -KcAxis::vec3::unitY(); - axes_[KcAxis::k_top].front()->tickOrient() = - axes_[KcAxis::k_top].front()->labelOrient() = KcAxis::vec3::unitY(); - static const char* title[] = { "X", "Y" }; for (unsigned i = 0; i < 4; i++) axes_[i].front()->title() = title[axes_[i].front()->dim()]; diff --git a/src/plot/KcCoord3d.cpp b/src/plot/KcCoord3d.cpp index fdf830e..df2091c 100644 --- a/src/plot/KcCoord3d.cpp +++ b/src/plot/KcCoord3d.cpp @@ -30,33 +30,6 @@ KcCoord3d::KcCoord3d(const point3& lower, const point3& upper) setExtents(lower, upper); - axes_[KcAxis::k_far_bottom]->tickOrient() = - axes_[KcAxis::k_far_bottom]->labelOrient() = -KcAxis::vec3::unitY(); - axes_[KcAxis::k_far_top]->tickOrient() = - axes_[KcAxis::k_far_top]->labelOrient() = KcAxis::vec3::unitY(); - axes_[KcAxis::k_near_top]->tickOrient() = - axes_[KcAxis::k_near_top]->labelOrient() = KcAxis::vec3::unitY(); - axes_[KcAxis::k_near_bottom]->tickOrient() = - axes_[KcAxis::k_near_bottom]->labelOrient() = -KcAxis::vec3::unitY(); - - axes_[KcAxis::k_far_left]->tickOrient() = - axes_[KcAxis::k_far_left]->labelOrient() = -KcAxis::vec3::unitX(); - axes_[KcAxis::k_far_right]->tickOrient() = - axes_[KcAxis::k_far_right]->labelOrient() = KcAxis::vec3::unitX(); - axes_[KcAxis::k_near_right]->tickOrient() = - axes_[KcAxis::k_near_right]->labelOrient() = KcAxis::vec3::unitX(); - axes_[KcAxis::k_near_left]->tickOrient() = - axes_[KcAxis::k_near_left]->labelOrient() = -KcAxis::vec3::unitX(); - - axes_[KcAxis::k_floor_left]->tickOrient() = - axes_[KcAxis::k_floor_left]->labelOrient() = -KcAxis::vec3::unitX(); - axes_[KcAxis::k_floor_right]->tickOrient() = - axes_[KcAxis::k_floor_right]->labelOrient() = KcAxis::vec3::unitX(); - axes_[KcAxis::k_ceil_right]->tickOrient() = - axes_[KcAxis::k_ceil_right]->labelOrient() = KcAxis::vec3::unitX(); - axes_[KcAxis::k_ceil_left]->tickOrient() = - axes_[KcAxis::k_ceil_left]->labelOrient() = -KcAxis::vec3::unitX(); - static const char* title[] = { "X", "Y", "Z" }; for (unsigned i = 0; i < std::size(axes_); i++) { axes_[i]->visible() = false; diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index a924eab..9309e87 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -379,7 +379,25 @@ namespace kPrivate ImGuiX::pen(&cxt, false); // no style. tickʼʹsolid ImGui::PushID(&cxt); - ImGui::SliderFloat("Length", &cxt.length, 0, 10, "%0.1f px"); + + const static char* side[] = { "inside", "outside", "bothside" }; + if (ImGui::BeginCombo("Side", side[cxt.side])) { + for (unsigned i = 0; i < std::size(side); i++) + if (ImGui::Selectable(side[i], i == cxt.side)) + cxt.side = KcAxis::KeTickSide(i); + ImGui::EndCombo(); + } + + ImGui::SliderFloat("Length", &cxt.length, 0, 25, "%0.1f px"); + + float yaw = KtuMath::rad2Deg(cxt.yaw); + if (ImGui::SliderFloat("Yaw", &yaw, -90, 90, "%.f deg")) + cxt.yaw = KtuMath::deg2Rad(yaw); + + float pitch = KtuMath::rad2Deg(cxt.pitch); + if (ImGui::SliderFloat("Pitch", &pitch, -90, 90, "%.f deg")) + cxt.pitch = KtuMath::deg2Rad(pitch); + ImGui::PopID(); } } -- Gitee From 22446ef006de888c723d65d3c38898c128d0c5e8 Mon Sep 17 00:00:00 2001 From: koala999 Date: Fri, 30 Dec 2022 13:08:45 +0800 Subject: [PATCH 51/68] clean code --- src/plot/KcAxis.cpp | 5 ++++- src/render/KvRdPlot.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 9bf47e6..eca1b2f 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -113,7 +113,10 @@ KcAxis::vec3 KcAxis::calcTickOrient_() const auto vPrep = orient.cross(vAxis); // ̶ߺĴֱʸ mat.fromAngleAxis(tickCxt_.yaw, vPrep.getNormalize()); - return (mat * orient).getNormalize(); + orient = mat * orient; + orient.normalize(); + + return orient; } diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index 9309e87..3f37fbf 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -388,7 +388,7 @@ namespace kPrivate ImGui::EndCombo(); } - ImGui::SliderFloat("Length", &cxt.length, 0, 25, "%0.1f px"); + ImGui::SliderFloat("Length", &cxt.length, 0, 25, "%.1f px"); float yaw = KtuMath::rad2Deg(cxt.yaw); if (ImGui::SliderFloat("Yaw", &yaw, -90, 90, "%.f deg")) -- Gitee From 4bba932684f163dae30e4234ab04d407cb0ab2b2 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Fri, 30 Dec 2022 15:04:20 +0800 Subject: [PATCH 52/68] =?UTF-8?q?fix:=20=E5=9D=90=E6=A0=87=E8=BD=B4?= =?UTF-8?q?=E4=BA=A4=E6=8D=A2=E6=83=85=E5=86=B5=E4=B8=8B=E7=9A=84=E5=88=BB?= =?UTF-8?q?=E5=BA=A6=E6=97=8B=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 3 ++- src/imapp/KcImPaint.cpp | 6 ++++++ src/imapp/KcImPaint.h | 2 ++ src/plot/KcAxis.cpp | 16 ++++++++-------- src/plot/KcAxis.h | 2 +- src/plot/KvPaint.h | 12 ++++++++++++ 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/TODO.md b/TODO.md index 68e4be9..f51e700 100644 --- a/TODO.md +++ b/TODO.md @@ -29,5 +29,6 @@ ## FIXME 1. 使用layout系统后,plot的axis留白出现问题 -2. 三维坐标系下,虚线的绘制在旋转到特定方向时会出现错位 +2. 三维坐标系下,虚线的绘制(ImGui)在旋转到特定方向时会出现错位 --> 使用opengl绘制后,该问题没再出现 3. 加载大的text数据文件很慢 +4. 坐标轴刻度旋转时出现突变 diff --git a/src/imapp/KcImPaint.cpp b/src/imapp/KcImPaint.cpp index 235d8c4..aaa922a 100644 --- a/src/imapp/KcImPaint.cpp +++ b/src/imapp/KcImPaint.cpp @@ -126,6 +126,12 @@ KcImPaint::point4 KcImPaint::localToWorld(const point4& pt) const } +KcImPaint::point4 KcImPaint::worldToLocal(const point4& pt) const +{ + return camera_.worldToLocal(pt); +} + + void KcImPaint::setColor(const color_t& clr) { clr_ = clr; diff --git a/src/imapp/KcImPaint.h b/src/imapp/KcImPaint.h index 849a655..01fdc36 100644 --- a/src/imapp/KcImPaint.h +++ b/src/imapp/KcImPaint.h @@ -33,6 +33,8 @@ public: point4 localToWorld(const point4& pt) const override; + point4 worldToLocal(const point4& pt) const override; + void setColor(const color_t& clr) override; void setPointSize(float_t size) override; diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index eca1b2f..b326129 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -61,7 +61,7 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const // tickOrient_labelOrient_ֻһ if (realShowTitle || showTick() || showLabel()) { // TODO: if (calcBox) plot3dʱ򲻻üģʽ - tickOrient_ = calcTickOrient_(); + tickOrient_ = calcTickOrient_(paint); if (paint->currentCoord() == KvPaint::k_coord_screen) tickOrient_.y() *= -1; // TODO: ޸õķ labelOrient_ = tickCxt_.side == k_inside ? -tickOrient_ : tickOrient_; @@ -82,7 +82,7 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const } -KcAxis::vec3 KcAxis::calcTickOrient_() const +KcAxis::vec3 KcAxis::calcTickOrient_(KvPaint* paint) const { // 12Ĭ static const vec3 baseOrient[] = { @@ -102,11 +102,12 @@ KcAxis::vec3 KcAxis::calcTickOrient_() const KcAxis::vec3::unitX() // k_ceil_right }; - vec3 orient = (tickCxt_.side == k_inside) ? -baseOrient[typeReal()] : baseOrient[typeReal()]; - - // ̬תyawpitch + // ̬תyawpitch任ϵת - auto vAxis = (end() - start()).getNormalize(); // ᷽ʸ + vec3 orient = (tickCxt_.side == k_inside) ? -baseOrient[typeReal()] : baseOrient[typeReal()]; + // ˴orientΪ + + auto vAxis = paint->localToWorldV(end() - start()).getNormalize(); // ᷽ʸ KtMatrix3 mat; mat.fromAngleAxis(tickCxt_.pitch, vAxis); // תpitch orient = mat * orient; @@ -114,9 +115,8 @@ KcAxis::vec3 KcAxis::calcTickOrient_() const auto vPrep = orient.cross(vAxis); // ̶ߺĴֱʸ mat.fromAngleAxis(tickCxt_.yaw, vPrep.getNormalize()); orient = mat * orient; - orient.normalize(); - return orient; + return paint->worldToLocalV(orient).getNormalize(); // 任ؾֲϵ } diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index 47abdb9..6f72a36 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -206,7 +206,7 @@ private: void drawLabel_(KvPaint* paint, const std::string_view& label, const point3& anchor, bool calcBox) const; // tickij - vec3 calcTickOrient_() const; + vec3 calcTickOrient_(KvPaint*) const; int labelAlignment_(KvPaint* paint, bool toggleTopBottom) const; // labelorientationжlabelalignment bool tickAndLabelInSameSide_() const; // жticktick-labelǷλͬ diff --git a/src/plot/KvPaint.h b/src/plot/KvPaint.h index 47ef02c..b421569 100644 --- a/src/plot/KvPaint.h +++ b/src/plot/KvPaint.h @@ -69,6 +69,8 @@ public: virtual point4 localToWorld(const point4& pt) const = 0; + virtual point4 worldToLocal(const point4& pt) const = 0; + virtual void setColor(const color_t& clr) = 0; virtual void setPointSize(double size) = 0; @@ -152,6 +154,11 @@ public: return { r.x(), r.y(), r.z() }; } + point3 worldToLocalP(const point3& pt) const { + auto r = worldToLocal(point4(pt.x(), pt.y(), pt.z(), 1)); + return { r.x(), r.y(), r.z() }; + } + // ʸͶӰ point3 projectv(const point3& v) const { auto r = project(point4(v.x(), v.y(), v.z(), 0)); @@ -173,6 +180,11 @@ public: return { r.x(), r.y(), r.z() }; } + point3 worldToLocalV(const point3& pt) const { + auto r = worldToLocal(point4(pt.x(), pt.y(), pt.z(), 0)); + return { r.x(), r.y(), r.z() }; + } + void drawRect(const rect_t& rc) { drawRect(point3(rc.lower().x(), rc.lower().y(), 0), point3(rc.upper().x(), rc.upper().y(), 0)); -- Gitee From 513bc1950a4fe8706ed8ae8a9492e112403e629e Mon Sep 17 00:00:00 2001 From: koala999 Date: Fri, 30 Dec 2022 20:20:27 +0800 Subject: [PATCH 53/68] =?UTF-8?q?fix:=20=E5=9C=A8screen=E5=9D=90=E6=A0=87?= =?UTF-8?q?=E7=B3=BB=E4=B8=8B=E7=BB=98=E5=88=B6colorbar=E5=9D=90=E6=A0=87?= =?UTF-8?q?=E8=BD=B4=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/3d/KtMatrix4.h | 2 +- src/imapp/KcImOglPaint.cpp | 16 +++++++++++++++- src/imapp/KcImPaint.cpp | 24 +++++++++++++++++++----- src/plot/KvPaint.h | 5 +++-- src/plot/KvPlot.cpp | 10 ++++++---- src/render/KcRdPlot3d.cpp | 6 +++--- 6 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/3d/KtMatrix4.h b/src/3d/KtMatrix4.h index b4f2752..efff5d9 100644 --- a/src/3d/KtMatrix4.h +++ b/src/3d/KtMatrix4.h @@ -618,7 +618,7 @@ template KtMatrix4 KtMatrix4::projectPerspective(KReal fovyInDegree, KReal aspectRatio, KReal znear, KReal zfar) { KReal ymax, xmax; - ymax = znear * std::tan(fovyInDegree * KtuMath::pi / 180); + ymax = znear * std::tan(KtuMath::deg2Rad(fovyInDegree)); xmax = ymax * aspectRatio; return projectFrustum(-xmax, xmax, -ymax, ymax, znear, zfar); } diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 1eeaf64..59569e4 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -88,19 +88,33 @@ KcImOglPaint::point3 KcImOglPaint::toNdc_(const point3& pt) const { switch (currentCoord()) { - case k_coord_world: + case k_coord_local: { auto p = camera_.localToNdc(pt); p.z() = KtuMath::clamp(p.z(), -1, 1); // FIXME: plot2dڴ˴zᳬ޷ʾ return { p.x(), p.y(), p.z() }; } + case k_coord_world: + { + auto p = camera_.worldToNdc(pt); + p.z() = KtuMath::clamp(p.z(), -1, 1); // FIXME: plot2dڴ˴zᳬ޷ʾ + return { p.x(), p.y(), p.z() }; + } + case k_coord_screen: + { + auto p = camera_.screenToNdc(pt); + return { p.x(), p.y(), p.z() }; + } + + case k_coord_local_screen: { auto p = camera_.localToWorld(pt); p = camera_.screenToNdc(p); return { p.x(), p.y(), p.z() }; } + } assert(false); diff --git a/src/imapp/KcImPaint.cpp b/src/imapp/KcImPaint.cpp index aaa922a..9914197 100644 --- a/src/imapp/KcImPaint.cpp +++ b/src/imapp/KcImPaint.cpp @@ -10,12 +10,13 @@ KcImPaint::KcImPaint(camera_type& cam) : camera_(cam) { - coords_.push_back(k_coord_world); + coords_.push_back(k_coord_local); } void KcImPaint::beginPaint() { + assert(coords_.size() == 1 && coords_.back() == k_coord_local); camera_.updateProjectMatrixs(); } @@ -23,6 +24,7 @@ void KcImPaint::beginPaint() void KcImPaint::endPaint() { // depth sorting + assert(coords_.size() == 1 && coords_.back() == k_coord_local); } @@ -86,12 +88,18 @@ KcImPaint::point4 KcImPaint::project(const point4& pt) const { switch (coords_.back()) { - case k_coord_world: + case k_coord_local: return camera_.localToScreen(pt); - case k_coord_screen: + case k_coord_world: + return camera_.worldToScreen(pt); + + case k_coord_local_screen: return camera_.localToWorld(pt); // ִоֲ任 + case k_coord_screen: + return pt; + default: break; } @@ -105,12 +113,18 @@ KcImPaint::point4 KcImPaint::unproject(const point4& pt) const { switch (coords_.back()) { - case k_coord_world: + case k_coord_local: return camera_.screenToLocal(pt); - case k_coord_screen: + case k_coord_world: + return camera_.screenToWorld(pt); + + case k_coord_local_screen: return camera_.worldToLocal(pt); // ִоֲ任 + case k_coord_screen: + return pt; + default: break; } diff --git a/src/plot/KvPaint.h b/src/plot/KvPaint.h index b421569..92ed31e 100644 --- a/src/plot/KvPaint.h +++ b/src/plot/KvPaint.h @@ -40,9 +40,10 @@ public: enum KeCoordType { + k_coord_local, k_coord_world, // ϵͼϵ - k_coord_screen, // Ļϵ - k_coord_viewport // 淶Ϊ[0, 1]ı׼ϵ + k_coord_local_screen, + k_coord_screen // Ļϵ }; // ı䵱ǰϵ diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index 0f89f6f..128f692 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -255,9 +255,11 @@ void KvPlot::syncLegendAndColorBar_(KvPlottable* removedPlt, KvPlottable* addedP } else { assert(colorBar_); - KuLayoutHelper::take(colorBar_); - if (colorBar_) delete colorBar_; - colorBar_ = nullptr; + if (colorBar_) { + KuLayoutHelper::take(colorBar_); + if (colorBar_) delete colorBar_; + colorBar_ = nullptr; + } } } @@ -266,7 +268,7 @@ void KvPlot::syncLegendAndColorBar_(KvPlottable* removedPlt, KvPlottable* addedP legend_->addItem(addedPlt); } else { - // assert(colorBar_ == nullptr); + assert(colorBar_ == nullptr); if (colorBar_) { // TODO: δcolor-bar KuLayoutHelper::take(colorBar_); delete colorBar_; diff --git a/src/render/KcRdPlot3d.cpp b/src/render/KcRdPlot3d.cpp index d4573c5..5ce1547 100644 --- a/src/render/KcRdPlot3d.cpp +++ b/src/render/KcRdPlot3d.cpp @@ -58,11 +58,11 @@ void KcRdPlot3d::showProperySet() orient.toRotateMatrix(rot); point3d angle; rot.toEulerAngleXYZ(angle); - angle *= 180 / KtuMath::pi; + angle *= KtuMath::rad2Deg(1); minVal = -180; maxVal = 180; - if(ImGui::DragScalarN("Rotation", ImGuiDataType_Double, angle, 3, 0.5, &minVal, &maxVal, "%.1fdeg")) { - angle *= KtuMath::pi / 180; + if(ImGui::DragScalarN("Rotation", ImGuiDataType_Double, angle, 3, 0.5, &minVal, &maxVal, "%.1f deg")) { + angle *= KtuMath::deg2Rad(1); rot.fromEulerAngleXYZ(angle); orient = quatd(rot); } -- Gitee From 78a229c240d872411074ca6c2e88fa75d090824e Mon Sep 17 00:00:00 2001 From: koala999 Date: Sat, 31 Dec 2022 20:54:14 +0800 Subject: [PATCH 54/68] =?UTF-8?q?try:=20tick-label=E7=9A=843d=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E5=B1=9E=E6=80=A7=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcAxis.cpp | 30 +++++++++++++++++------- src/plot/KcAxis.h | 51 +++++++++++++++++++++++++++++------------ src/render/KvRdPlot.cpp | 1 + 3 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index b326129..047122d 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -364,16 +364,30 @@ KcAxis::KeType KcAxis::typeReal() const // TODO: õʵַ void KcAxis::calcLabelPos_(KvPaint* paint, const std::string_view& label, const point3& anchor, point3& topLeft, point3& hDir, point3& vDir) const { - // ƣҲĻ - KeAlignment align = labelAlignment_(paint, paint->currentCoord() == KvPaint::k_coord_screen); + auto textBox = paint->textSize(label.data()); + if (labelLayout_ == k_vert_left || labelLayout_ == k_vert_right) + std::swap(textBox.x(), textBox.y()); - auto anchorInScreen = paint->projectp(anchor); - auto rc = KuLayoutUtil::anchorAlignedRect({ anchorInScreen.x(), anchorInScreen.y() }, paint->textSize(label.data()), align); - auto topLeftInScreen = point3(rc.lower().x(), rc.lower().y(), anchorInScreen.z()); // TODO: תӦò + if (labelBillboard_) { // ģʽʼ˳+xչ - topLeft = paint->unprojectp(topLeftInScreen); - hDir = paint->unprojectv(vec3::unitX()); - vDir = paint->unprojectv(vec3::unitY()); + bool toggle = paint->currentCoord() == KvPaint::k_coord_screen || paint->currentCoord() == KvPaint::k_coord_local_screen; + KeAlignment align = labelAlignment_(paint, toggle); + + auto anchorInScreen = paint->projectp(anchor); + auto rc = KuLayoutUtil::anchorAlignedRect({ anchorInScreen.x(), anchorInScreen.y() }, textBox, align); + auto topLeftInScreen = point3(rc.lower().x(), rc.lower().y(), anchorInScreen.z()); // TODO: תӦò + + topLeft = paint->unprojectp(topLeftInScreen); + + hDir = paint->unprojectv(vec3::unitX()); + vDir = paint->unprojectv(vec3::unitY()); + } + else { + hDir = (end() - start()).getNormalize(); + if (dim() > 0) hDir *= -1; + vDir = labelOrient_; + topLeft = anchor - hDir * (textBox.x() / 2) / paint->projectv(hDir).length(); + } } diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index 6f72a36..38d5c6a 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -138,39 +138,61 @@ public: showTitle_ = true, showLabel_ = true; } - const std::string& title() const { return title_; } - std::string& title() { return title_; } - - const std::vector& labels() const { return labels_; } - void setLabels(const std::vector& ls) { labels_ = ls; } - const KpPen& baselineContext() const { return baselineCxt_; } KpPen& baselineContext() { return baselineCxt_; } + std::shared_ptr ticker() const; + void setTicker(std::shared_ptr tic); + const KpTickContext& tickContext() const { return tickCxt_; } KpTickContext& tickContext() { return tickCxt_; } const KpTickContext& subtickContext() const { return subtickCxt_; } KpTickContext& subtickContext() { return subtickCxt_; } - /// colors + /// title properties + + const std::string& title() const { return title_; } + std::string& title() { return title_; } + + //QFont titleFont() const { return titleFont_; } + //void setTitleFont(QFont font) { titleFont_ = font; } const color4f& titleColor() const { return titleColor_; } color4f& titleColor() { return titleColor_; } - const color4f& labelColor() const { return labelColor_; } - color4f& labelColor() { return labelColor_; } + float titlePadding() const { return titlePadding_; } + float& titlePadding() { return titlePadding_; } + + KeTextLayout titleLayout() const { return titleLayout_; } + KeTextLayout& titleLayout() { return titleLayout_; } - /// fonts + /// label properties + + const std::vector& labels() const { return labels_; } + void setLabels(const std::vector& ls) { labels_ = ls; } //QFont labelFont() const { return labelFont_; } //void setLabelFont(QFont font) { labelFont_ = font; } - //QFont titleFont() const { return titleFont_; } - //void setTitleFont(QFont font) { titleFont_ = font; } + const color4f& labelColor() const { return labelColor_; } + color4f& labelColor() { return labelColor_; } + + float labelPadding() const { return labelPadding_; } + float& labelPadding() { return labelPadding_; } + + KeTextLayout labelLayout() const { return labelLayout_; } + KeTextLayout& labelLayout() { return labelLayout_; } + + bool labelBillboard() const { return labelBillboard_; } + bool& labelBillboard() { return labelBillboard_; } + + float labelYaw() const { return labelYaw_; } + float& labelYaw() { return labelYaw_; } + + float labelPitch() const { return labelPitch_; } + float& labelPitch() { return labelPitch_; } - std::shared_ptr ticker() const; - void setTicker(std::shared_ptr tic); // NB֮󣨼calcSize֮󣩣úܷЧֵ aabb_t boundingBox() const override { @@ -253,7 +275,6 @@ private: //KpFont titleFont_; point3 start_, end_; - //bool tickBothSide_{ false }; std::shared_ptr ticker_; diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index 3f37fbf..73d4471 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -462,6 +462,7 @@ void KvRdPlot::showAxisProperty_(KcAxis& axis) open = false; ImGuiX::cbTreePush("Label", &axis.showLabel(), &open); if (open) { + ImGui::Checkbox("Billboard", &axis.labelBillboard()); ImGui::ColorEdit4("Color##label", axis.labelColor()); ImGuiX::cbTreePop(); } -- Gitee From eaa13f75f64ed8d8f00f9bbe97a568b84fb58b20 Mon Sep 17 00:00:00 2001 From: koala999 Date: Sun, 1 Jan 2023 20:49:06 +0800 Subject: [PATCH 55/68] =?UTF-8?q?add:=20tick-label=E5=9C=A8billboard?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E4=B8=8B=E7=9A=84=E6=A8=AA=E7=AB=964?= =?UTF-8?q?=E7=B1=BB=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 2 ++ src/plot/KcAxis.cpp | 37 ++++++++++++++++++++++++++++++++----- src/plot/KcAxis.h | 4 ++-- src/render/KvRdPlot.cpp | 14 ++++++++++++++ 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/TODO.md b/TODO.md index f51e700..8c4cf50 100644 --- a/TODO.md +++ b/TODO.md @@ -32,3 +32,5 @@ 2. 三维坐标系下,虚线的绘制(ImGui)在旋转到特定方向时会出现错位 --> 使用opengl绘制后,该问题没再出现 3. 加载大的text数据文件很慢 4. 坐标轴刻度旋转时出现突变 +5. 3d透视投影模式下,坐标轴的刻度线和文字全部消失 +6. plot3d在交换坐标轴后,鼠标操控坐标系姿态出现问题 \ No newline at end of file diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 047122d..11545c6 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -375,16 +375,43 @@ void KcAxis::calcLabelPos_(KvPaint* paint, const std::string_view& label, const auto anchorInScreen = paint->projectp(anchor); auto rc = KuLayoutUtil::anchorAlignedRect({ anchorInScreen.x(), anchorInScreen.y() }, textBox, align); - auto topLeftInScreen = point3(rc.lower().x(), rc.lower().y(), anchorInScreen.z()); // TODO: תӦò + point3 topLeftInScreen; + + switch (labelLayout_) + { + case KcAxis::k_horz_top: // ȱʡ + topLeftInScreen = point3(rc.lower().x(), rc.lower().y(), anchorInScreen.z()); + hDir = paint->unprojectv(vec3::unitX()); + vDir = paint->unprojectv(vec3::unitY()); + break; + + case KcAxis::k_horz_bottom: // µߵtopLeft½ + topLeftInScreen = point3(rc.upper().x(), rc.upper().y(), anchorInScreen.z()); + hDir = paint->unprojectv(-vec3::unitX()); + vDir = paint->unprojectv(-vec3::unitY()); + break; + + case KcAxis::k_vert_left: // 沼֣topLeft½ + topLeftInScreen = point3(rc.lower().x(), rc.upper().y(), anchorInScreen.z()); + hDir = paint->unprojectv(-vec3::unitY()); + vDir = paint->unprojectv(vec3::unitX()); + break; + + case KcAxis::k_vert_right:// 沼֣topLeftϽ + topLeftInScreen = point3(rc.upper().x(), rc.lower().y(), anchorInScreen.z()); + hDir = paint->unprojectv(vec3::unitY()); + vDir = paint->unprojectv(-vec3::unitX()); + break; + + default: + break; + } topLeft = paint->unprojectp(topLeftInScreen); - - hDir = paint->unprojectv(vec3::unitX()); - vDir = paint->unprojectv(vec3::unitY()); } else { hDir = (end() - start()).getNormalize(); - if (dim() > 0) hDir *= -1; + if (dimSwapped_ > 0) hDir *= -1; // TODO: swap_yzģʽ£ֻǷ vDir = labelOrient_; topLeft = anchor - hDir * (textBox.x() / 2) / paint->projectv(hDir).length(); } diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index 38d5c6a..8062b14 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -278,8 +278,8 @@ private: std::shared_ptr ticker_; - int dimReal_; // 0ʾxᣬ1ʾyᣬ2ʾzᣬ-1ʾ?ʾcolorbar - int dimSwapped_; + int dimReal_; // 0ʾxᣬ1ʾyᣬ2ʾzᣬ-1ʾ뽻ᣨʾcolorbar + int dimSwapped_; // -1ʾάȵύ bool main_{ true }; // Ƿ bool inv_{ false }; // Ƿת diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index 73d4471..7dcd4b5 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -463,6 +463,20 @@ void KvRdPlot::showAxisProperty_(KcAxis& axis) ImGuiX::cbTreePush("Label", &axis.showLabel(), &open); if (open) { ImGui::Checkbox("Billboard", &axis.labelBillboard()); + + static const char* layouts[] = { + "standard", + "upside down", + "vertical left", + "vertical rigth" + }; + if (ImGui::BeginCombo("Layout", layouts[axis.labelLayout()])) { + for (unsigned i = 0; i < std::size(layouts); i++) + if (ImGui::Selectable(layouts[i], i == axis.labelLayout())) + axis.labelLayout() = KcAxis::KeTextLayout(i); + ImGui::EndCombo(); + } + ImGui::ColorEdit4("Color##label", axis.labelColor()); ImGuiX::cbTreePop(); } -- Gitee From 18e0f115b6fb23d01dd25c1ca183b55f9a785104 Mon Sep 17 00:00:00 2001 From: koala999 Date: Mon, 2 Jan 2023 13:20:55 +0800 Subject: [PATCH 56/68] =?UTF-8?q?refactor:=202d/3d=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E7=9A=84text=E7=BB=98=E5=88=B6=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcAxis.cpp | 116 +++++++++++++++++---------------- src/plot/KcAxis.h | 66 +++++++------------ src/plot/KcThemedPlotImpl_.cpp | 4 +- src/render/KvRdPlot.cpp | 53 ++++++++++----- 4 files changed, 120 insertions(+), 119 deletions(-) diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 11545c6..2a1c5c4 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -76,8 +76,8 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const // draw title if (realShowTitle) { - paint->setColor(titleColor()); - drawLabel_(paint, title_, titleAnchor_, calcBox); + paint->setColor(titleContext().color); + drawText_(paint, title_, titleCxt_, titleAnchor_, calcBox); } } @@ -169,12 +169,12 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const if (showLabel()) { // TODO: paint->setFont(); - paint->setColor(labelColor()); + paint->setColor(labelContext().color); auto& labels = ticker()->labels(); point2 maxLabelSize(0); for (unsigned i = 0; i < ticks.size(); i++) { auto label = i < labels_.size() ? labels_[i] : labels[i]; - drawLabel_(paint, label, labelAnchors[i], calcBox); + drawText_(paint, label, labelCxt_, labelAnchors[i], calcBox); if (showTitle()) maxLabelSize = point2::ceil(maxLabelSize, paint->textSize(label.c_str())); @@ -339,19 +339,19 @@ KcAxis::KeType KcAxis::typeReal() const constexpr static int swapType[][4] = { /* swap_none */ /* swap_xy */ /* swap_xz */ /* swap_yz */ { KcAxis::k_near_left, KcAxis::k_near_bottom, KcAxis::k_far_right, KcAxis::k_ceil_left }, - { KcAxis::k_near_right, KcAxis::k_near_top , KcAxis::k_far_left, KcAxis::k_ceil_right }, + { KcAxis::k_near_right, KcAxis::k_near_top , KcAxis::k_near_right, KcAxis::k_ceil_right }, { KcAxis::k_near_bottom, KcAxis::k_near_left, KcAxis::k_floor_right, KcAxis::k_far_top }, - { KcAxis::k_near_top, KcAxis::k_near_right, KcAxis::k_ceil_right, KcAxis::k_far_bottom }, + { KcAxis::k_near_top, KcAxis::k_near_right, KcAxis::k_ceil_right, KcAxis::k_near_top }, - { KcAxis::k_far_left, KcAxis::k_far_bottom, KcAxis::k_near_right, KcAxis::k_floor_left }, + { KcAxis::k_far_left, KcAxis::k_far_bottom, KcAxis::k_far_left, KcAxis::k_floor_left }, { KcAxis::k_far_right, KcAxis::k_far_top, KcAxis::k_near_left, KcAxis::k_floor_right }, - { KcAxis::k_far_bottom, KcAxis::k_far_left, KcAxis::k_floor_left, KcAxis::k_near_top }, + { KcAxis::k_far_bottom, KcAxis::k_far_left, KcAxis::k_floor_left, KcAxis::k_far_bottom }, { KcAxis::k_far_top, KcAxis::k_far_right, KcAxis::k_ceil_left, KcAxis::k_near_bottom }, - { KcAxis::k_floor_left, KcAxis::k_ceil_right, KcAxis::k_far_bottom, KcAxis::k_far_left }, + { KcAxis::k_floor_left, KcAxis::k_floor_left, KcAxis::k_far_bottom, KcAxis::k_far_left }, { KcAxis::k_floor_right, KcAxis::k_ceil_left, KcAxis::k_near_bottom, KcAxis::k_far_right }, { KcAxis::k_ceil_left, KcAxis::k_floor_right, KcAxis::k_far_top, KcAxis::k_near_left }, - { KcAxis::k_ceil_right, KcAxis::k_floor_left, KcAxis::k_near_top, KcAxis::k_near_right } + { KcAxis::k_ceil_right, KcAxis::k_ceil_right, KcAxis::k_near_top, KcAxis::k_near_right } }; if (dimReal_ == -1) return type_; // color-barᣬ޽ @@ -361,76 +361,80 @@ KcAxis::KeType KcAxis::typeReal() const } -// TODO: õʵַ -void KcAxis::calcLabelPos_(KvPaint* paint, const std::string_view& label, const point3& anchor, point3& topLeft, point3& hDir, point3& vDir) const +void KcAxis::calcTextPos_(KvPaint* paint, const std::string_view& label, const KpTextContext& cxt, + const point3& anchor, point3& topLeft, vec3& hDir, vec3& vDir) const { auto textBox = paint->textSize(label.data()); - if (labelLayout_ == k_vert_left || labelLayout_ == k_vert_right) + if (cxt.layout == k_vert_left || cxt.layout == k_vert_right) std::swap(textBox.x(), textBox.y()); - if (labelBillboard_) { // ģʽʼ˳+xչ + if (cxt.billboard) { // ģʽʼ˳+xչ bool toggle = paint->currentCoord() == KvPaint::k_coord_screen || paint->currentCoord() == KvPaint::k_coord_local_screen; KeAlignment align = labelAlignment_(paint, toggle); auto anchorInScreen = paint->projectp(anchor); auto rc = KuLayoutUtil::anchorAlignedRect({ anchorInScreen.x(), anchorInScreen.y() }, textBox, align); - point3 topLeftInScreen; - - switch (labelLayout_) - { - case KcAxis::k_horz_top: // ȱʡ - topLeftInScreen = point3(rc.lower().x(), rc.lower().y(), anchorInScreen.z()); - hDir = paint->unprojectv(vec3::unitX()); - vDir = paint->unprojectv(vec3::unitY()); - break; - - case KcAxis::k_horz_bottom: // µߵtopLeft½ - topLeftInScreen = point3(rc.upper().x(), rc.upper().y(), anchorInScreen.z()); - hDir = paint->unprojectv(-vec3::unitX()); - vDir = paint->unprojectv(-vec3::unitY()); - break; - - case KcAxis::k_vert_left: // 沼֣topLeft½ - topLeftInScreen = point3(rc.lower().x(), rc.upper().y(), anchorInScreen.z()); - hDir = paint->unprojectv(-vec3::unitY()); - vDir = paint->unprojectv(vec3::unitX()); - break; - - case KcAxis::k_vert_right:// 沼֣topLeftϽ - topLeftInScreen = point3(rc.upper().x(), rc.lower().y(), anchorInScreen.z()); - hDir = paint->unprojectv(vec3::unitY()); - vDir = paint->unprojectv(-vec3::unitX()); - break; - - default: - break; - } - - topLeft = paint->unprojectp(topLeftInScreen); + topLeft = paint->unprojectp({ rc.lower().x(), rc.lower().y(), anchorInScreen.z() }); + hDir = paint->unprojectv(vec3::unitX()); + vDir = paint->unprojectv(vec3::unitY()); } else { - hDir = (end() - start()).getNormalize(); - if (dimSwapped_ > 0) hDir *= -1; // TODO: swap_yzģʽ£ֻǷ vDir = labelOrient_; + hDir = (end() - start()).getNormalize(); + + vec3 h = paint->projectv(hDir); + vec3 v = paint->projectv(vDir); + auto zDir = h.cross(v); + if (zDir.z() < 0) + hDir *= -1; // hDirȷάռĿɶ + topLeft = anchor - hDir * (textBox.x() / 2) / paint->projectv(hDir).length(); } + + textBox /= point2d(paint->projectv(hDir).length(), paint->projectv(vDir).length()); + + fixTextLayout_(cxt.layout, textBox, topLeft, hDir, vDir); } -void KcAxis::drawLabel_(KvPaint* paint, const std::string_view& label, const point3& anchor, bool calcBox) const +void KcAxis::fixTextLayout_(KeTextLayout lay, const size_t& textBox, point3& topLeft, vec3& hDir, vec3& vDir) +{ + switch (lay) + { + case KcAxis::k_horz_bottom: // µߵtopLeft½ + topLeft += hDir * textBox.x() + vDir * textBox.y(); + hDir *= -1; vDir *= -1; + break; + + case KcAxis::k_vert_left: // 沼֣topLeft½ + topLeft += vDir * textBox.y(); + std::swap(hDir, vDir); hDir *= -1; + break; + + case KcAxis::k_vert_right:// 沼֣topLeftϽ + topLeft += hDir * textBox.x(); + std::swap(hDir, vDir); vDir *= -1; + break; + + case KcAxis::k_horz_top: // ȱʡ֣ + default: + break; + } +} + +void KcAxis::drawText_(KvPaint* paint, const std::string_view& label, const KpTextContext& cxt, const point3& anchor, bool calcBox) const { - point3 topLeft, hDir, vDir; - calcLabelPos_(paint, label.data(), anchor, topLeft, hDir, vDir); + point3 topLeft; + vec3 hDir, vDir; + calcTextPos_(paint, label.data(), cxt, anchor, topLeft, hDir, vDir); if (!calcBox) { paint->drawText(topLeft, hDir, vDir, label.data()); } else { auto sz = paint->textSize(label.data()); - auto h = paint->projectv(hDir) * sz.x(); - auto v = paint->projectv(vDir) * sz.y(); - h = paint->unprojectv(h); - v = paint->unprojectv(v); + auto h = hDir * sz.x() / paint->projectv(hDir).length(); + auto v = vDir * sz.y() / paint->projectv(vDir).length(); box_.merge({ topLeft, topLeft + h + v }); } } diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index 8062b14..3d54176 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -76,6 +76,16 @@ public: } }; + struct KpTextContext + { + KpFont font; + color4f color{ 0, 0, 0, 1 }; + KeTextLayout layout{ k_horz_top }; + bool billboard{ false }; // ǷԹģʽʾtexttruetexthDirʼճĻҲ࣬vDirʼճĻ² + float yaw{ 0 }; // text-boxƽĴߣĵ㣩תǶȣȣ + float pitch{ 0 }; // hDirvDirתǶȣȣ + }; + KcAxis(KeType type, int dim, bool main); KeType type() const { return type_; } @@ -93,14 +103,6 @@ public: start_ = st, end_ = ed; } - //const vec3& tickOrient() const { return tickOrient_; } - //vec3& tickOrient() { return tickOrient_; } - - //const vec3& labelOrient() const { return labelOrient_; } - //vec3& labelOrient() { return labelOrient_; } - - //bool tickBothSide() const { return tickBothSide_; } - //bool& tickBothSide() { return tickBothSide_; } /// range @@ -155,43 +157,22 @@ public: const std::string& title() const { return title_; } std::string& title() { return title_; } - //QFont titleFont() const { return titleFont_; } - //void setTitleFont(QFont font) { titleFont_ = font; } - - const color4f& titleColor() const { return titleColor_; } - color4f& titleColor() { return titleColor_; } - float titlePadding() const { return titlePadding_; } float& titlePadding() { return titlePadding_; } - KeTextLayout titleLayout() const { return titleLayout_; } - KeTextLayout& titleLayout() { return titleLayout_; } + KpTextContext titleContext() const { return titleCxt_; } + KpTextContext& titleContext() { return titleCxt_; } /// label properties const std::vector& labels() const { return labels_; } void setLabels(const std::vector& ls) { labels_ = ls; } - //QFont labelFont() const { return labelFont_; } - //void setLabelFont(QFont font) { labelFont_ = font; } - - const color4f& labelColor() const { return labelColor_; } - color4f& labelColor() { return labelColor_; } - float labelPadding() const { return labelPadding_; } float& labelPadding() { return labelPadding_; } - KeTextLayout labelLayout() const { return labelLayout_; } - KeTextLayout& labelLayout() { return labelLayout_; } - - bool labelBillboard() const { return labelBillboard_; } - bool& labelBillboard() { return labelBillboard_; } - - float labelYaw() const { return labelYaw_; } - float& labelYaw() { return labelYaw_; } - - float labelPitch() const { return labelPitch_; } - float& labelPitch() { return labelPitch_; } + KpTextContext labelContext() const { return labelCxt_; } + KpTextContext& labelContext() { return labelCxt_; } // NB֮󣨼calcSize֮󣩣úܷЧֵ @@ -225,7 +206,7 @@ private: void draw_(KvPaint*, bool calcBox) const; void drawTicks_(KvPaint*, bool calcBox) const; // п̶ void drawTick_(KvPaint*, const point3& anchor, double length, bool calcBox) const; // Ƶ̶ߣ̶븱̶ - void drawLabel_(KvPaint* paint, const std::string_view& label, const point3& anchor, bool calcBox) const; + void drawText_(KvPaint* paint, const std::string_view& label, const KpTextContext& cxt, const point3& anchor, bool calcBox) const; // tickij vec3 calcTickOrient_(KvPaint*) const; @@ -236,7 +217,11 @@ private: size_t calcSize_(void* cxt) const final; // 3dռı3topLeft, hDir, vDir - void calcLabelPos_(KvPaint*, const std::string_view& label, const point3& anchor, point3& topLeft, point3& hDir, point3& vDir) const; + void calcTextPos_(KvPaint*, const std::string_view& label, const KpTextContext& cxt, + const point3& anchor, point3& topLeft, vec3& hDir, vec3& vDir) const; + + // layouttopLefthDir & vDir + static void fixTextLayout_(KeTextLayout lay, const size_t& textBox, point3& topLeft, vec3& hDir, vec3& vDir); private: KeType type_; @@ -260,19 +245,12 @@ private: // ڲlabelPadding_£labeltickͬ࣬anchor̶ߵĩغϣ̶ȵغ float labelPadding_{ 2 }; - KeTextLayout labelLayout_{ k_horz_top }; - color4f labelColor_{ 0, 0, 0, 1 }; - bool labelBillboard_{ true }; // ԹģʽʾlabelʱlabelhDirʼճĻҲ࣬vDirʼճĻ² - //KpFont labelFont_; - float labelYaw_{ 0 }; // label-boxƽĴߣanchor㣩תǶȣȣlabelBillboard_ΪfalseʱЧ - float labelPitch_{ 0 }; //תǶȣȣlabelBillboard_ΪfalseʱЧ + KpTextContext labelCxt_; // title float titlePadding_{ 2 }; - KeTextLayout titleLayout_{ k_horz_top }; - color4f titleColor_{ 0, 0, 0, 1 }; - //KpFont titleFont_; + KpTextContext titleCxt_; point3 start_, end_; diff --git a/src/plot/KcThemedPlotImpl_.cpp b/src/plot/KcThemedPlotImpl_.cpp index 3701ec3..420e934 100644 --- a/src/plot/KcThemedPlotImpl_.cpp +++ b/src/plot/KcThemedPlotImpl_.cpp @@ -168,9 +168,9 @@ void KcThemedPlotImpl_::applyTextColor(int level, std::function::rad2Deg(cxt.yaw); + if (ImGui::SliderFloat("Yaw", &yaw, -90, 90, "%.f deg")) + cxt.yaw = KtuMath::deg2Rad(yaw); + + float pitch = KtuMath::rad2Deg(cxt.pitch); + if (ImGui::SliderFloat("Pitch", &pitch, -90, 90, "%.f deg")) + cxt.pitch = KtuMath::deg2Rad(pitch); + } + + ImGui::PopID(); + } } void KvRdPlot::showAxisProperty_(KcAxis& axis) @@ -441,7 +475,7 @@ void KvRdPlot::showAxisProperty_(KcAxis& axis) ImGuiX::cbTreePush("Title", &axis.showTitle(), &open); if (open) { ImGui::InputText("Text", &axis.title()); - ImGui::ColorEdit4("Color##title", axis.titleColor()); + kPrivate::textContext(axis.titleContext(), false); ImGuiX::cbTreePop(); } @@ -462,22 +496,7 @@ void KvRdPlot::showAxisProperty_(KcAxis& axis) open = false; ImGuiX::cbTreePush("Label", &axis.showLabel(), &open); if (open) { - ImGui::Checkbox("Billboard", &axis.labelBillboard()); - - static const char* layouts[] = { - "standard", - "upside down", - "vertical left", - "vertical rigth" - }; - if (ImGui::BeginCombo("Layout", layouts[axis.labelLayout()])) { - for (unsigned i = 0; i < std::size(layouts); i++) - if (ImGui::Selectable(layouts[i], i == axis.labelLayout())) - axis.labelLayout() = KcAxis::KeTextLayout(i); - ImGui::EndCombo(); - } - - ImGui::ColorEdit4("Color##label", axis.labelColor()); + kPrivate::textContext(axis.labelContext(), true); ImGuiX::cbTreePop(); } -- Gitee From b24ea3dcdfb3e5fd722c6164cb3d2e7ebab04bad Mon Sep 17 00:00:00 2001 From: koala999 Date: Tue, 3 Jan 2023 07:41:22 +0800 Subject: [PATCH 57/68] =?UTF-8?q?fix:=20=E8=AE=BE=E7=BD=AE=E8=A7=86?= =?UTF-8?q?=E5=8F=A3=E6=97=B6=E6=9C=AA=E6=9B=B4=E6=96=B0=E8=A7=86=E5=8F=A3?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=8F=98=E6=8D=A2=E7=9F=A9=E9=98=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/3d/KtProjector3d.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/3d/KtProjector3d.h b/src/3d/KtProjector3d.h index 9dd8847..e65e393 100644 --- a/src/3d/KtProjector3d.h +++ b/src/3d/KtProjector3d.h @@ -297,6 +297,9 @@ void KtProjector::setViewport(const rect& vp) nsMat_ = vsMat_ * nvMat_; wsMat_ = nsMat_ * vpMat_; + + vsMatR_.reset(); + nsMatR_.reset(); } @@ -304,10 +307,13 @@ template void KtProjector::updateProjectMatrixs() { vpMat_ = projMat_ * viewMat_; + wsMat_ = nsMat_ * vpMat_; + vpMatR_.reset(); - resetModelRelatedMats_(); + viewMatR_.reset(); + projMatR_.reset(); - wsMat_ = nsMat_ * vpMat_; + resetModelRelatedMats_(); } @@ -317,14 +323,8 @@ void KtProjector::resetModelRelatedMats_() mvMat_.reset(); mvpMat_.reset(); mMatR_.reset(); - viewMatR_.reset(); - projMatR_.reset(); mvMatR_.reset(); mvpMatR_.reset(); - vpMatR_.reset(); - - vsMatR_.reset(); - nsMatR_.reset(); } -- Gitee From bc860786ef35a6250e44079d9c754bd87cc28dd1 Mon Sep 17 00:00:00 2001 From: koala999 Date: Tue, 3 Jan 2023 07:41:44 +0800 Subject: [PATCH 58/68] =?UTF-8?q?refactor:=20=E5=9D=90=E6=A0=87=E8=BD=B4?= =?UTF-8?q?=E6=A0=87=E9=A2=98=E5=9C=A8=E4=B8=89=E7=BB=B4=E7=A9=BA=E9=97=B4?= =?UTF-8?q?=E7=9A=84=E5=AE=9A=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcAxis.cpp | 75 +++++++++++++++++++++++++++-------------- src/plot/KcAxis.h | 12 ++++--- src/plot/KcCoord3d.cpp | 16 ++++----- src/plot/KcCoord3d.h | 2 -- src/plot/KvCoord.cpp | 15 +++++++-- src/plot/KvPlot.cpp | 8 +++-- src/plot/KvPlot.h | 3 ++ src/render/KvRdPlot.cpp | 2 ++ 8 files changed, 88 insertions(+), 45 deletions(-) diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 2a1c5c4..37253fa 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -71,12 +71,14 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const // draw ticks & label if (showTick() || showLabel()) drawTicks_(paint, calcBox); - else if (realShowTitle) - titleAnchor_ = (start() + end()) / 2 + labelOrient_ * titlePadding_ / paint->projectv(labelOrient_).length(); + //else if (realShowTitle) + // titleAnchor_ = (start() + end()) / 2 + labelOrient_ * titlePadding_ / paint->projectv(labelOrient_).length(); // draw title if (realShowTitle) { paint->setColor(titleContext().color); + if (calcBox) + titleAnchor_ = calcTitleAnchor_(paint); drawText_(paint, title_, titleCxt_, titleAnchor_, calcBox); } } @@ -145,12 +147,12 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const if (showLabel()) labelAnchors.resize(ticks.size()); - if (showTitle()) { +/* if (showTitle()) { titleAnchor_ = (start() + end()) / 2 + labelOrient_ * titlePadding_ * labelPaddingPerPixel; if (sameSide && showTick()) titleAnchor_ += tickOrient_ * tickCxt_.length * tickLenPerPixel; - } + }*/ for (unsigned i = 0; i < ticks.size(); i++) { auto anchor = tickPos(ticks[i]); @@ -176,10 +178,11 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const auto label = i < labels_.size() ? labels_[i] : labels[i]; drawText_(paint, label, labelCxt_, labelAnchors[i], calcBox); - if (showTitle()) - maxLabelSize = point2::ceil(maxLabelSize, paint->textSize(label.c_str())); + //if (showTitle()) + // maxLabelSize = point2::ceil(maxLabelSize, paint->textSize(label.c_str())); } + /* if (showTitle() || calcBox) { vec3 h = vec3::unitX() * maxLabelSize.x(); // TODO: hDir @@ -191,7 +194,7 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const auto maxSqLen = std::max(h.squaredLength(), v.squaredLength()); titleAnchor_ += labelOrient_ * (std::sqrt(maxSqLen) + labelPadding_ ) * labelPaddingPerPixel; - } + }*/ } // minor @@ -257,28 +260,32 @@ KcAxis::point3 KcAxis::tickPos(double val) const KcAxis::size_t KcAxis::calcSize_(void* cxt) const { - assert(visible() && length() > 0 && dimReal_ < 2); + assert(visible()); - auto paint = (KvPaint*)cxt; + if (length() > 0) { - switch (typeReal()) - { - case KcAxis::k_left: - return { std::max(calcMargins(paint).left(), baselineCxt_.width), 0 }; + auto paint = (KvPaint*)cxt; + auto marg = calcMargins(paint); - case KcAxis::k_right: - return { std::max(calcMargins(paint).right(), baselineCxt_.width), 0 }; + switch (typeReal()) + { + case KcAxis::k_left: + return { std::max(marg.left(), baselineCxt_.width), 0 }; - case KcAxis::k_bottom: - return { 0, std::max(calcMargins(paint).bottom(), baselineCxt_.width) }; + case KcAxis::k_right: + return { std::max(marg.right(), baselineCxt_.width), 0 }; - case KcAxis::k_top: - return { 0, std::max(calcMargins(paint).top(), baselineCxt_.width) }; + case KcAxis::k_bottom: + return { 0, std::max(marg.bottom(), baselineCxt_.width) }; - default: - break; + case KcAxis::k_top: + return { 0, std::max(marg.top(), baselineCxt_.width) }; + + default: + break; + } } - + return { 0, 0 }; } @@ -302,7 +309,7 @@ KtMargins KcAxis::calcMargins(KvPaint* paint) const margs.right() = u.x(); margs.bottom() = u.y(); margs.top() = l.y(); - assert(margs.ge({ 0, 0, 0, 0 })); + //assert(margs.ge({ 0, 0, 0, 0 })); return margs; } @@ -376,8 +383,8 @@ void KcAxis::calcTextPos_(KvPaint* paint, const std::string_view& label, const K auto anchorInScreen = paint->projectp(anchor); auto rc = KuLayoutUtil::anchorAlignedRect({ anchorInScreen.x(), anchorInScreen.y() }, textBox, align); topLeft = paint->unprojectp({ rc.lower().x(), rc.lower().y(), anchorInScreen.z() }); - hDir = paint->unprojectv(vec3::unitX()); - vDir = paint->unprojectv(vec3::unitY()); + hDir = paint->unprojectv(vec3::unitX()).getNormalize(); + vDir = paint->unprojectv(vec3::unitY()).getNormalize(); } else { vDir = labelOrient_; @@ -428,6 +435,9 @@ void KcAxis::drawText_(KvPaint* paint, const std::string_view& label, const KpTe point3 topLeft; vec3 hDir, vDir; calcTextPos_(paint, label.data(), cxt, anchor, topLeft, hDir, vDir); + assert(KtuMath::almostEqual(1.0, hDir.length())); + assert(KtuMath::almostEqual(1.0, vDir.length())); + if (!calcBox) { paint->drawText(topLeft, hDir, vDir, label.data()); } @@ -438,3 +448,18 @@ void KcAxis::drawText_(KvPaint* paint, const std::string_view& label, const KpTe box_.merge({ topLeft, topLeft + h + v }); } } + + +KcAxis::point3 KcAxis::calcTitleAnchor_(KvPaint* paint) const +{ + auto center = (start() + end()) / 2; + + aabb_t inner(start(), end()); + auto low = box_.lower() - inner.lower(); + auto up = box_.upper() - inner.upper(); + point3 dir = labelOrient_.getNormalize(); + for (int i = 0; i < 3; i++) + dir[i] = KtuMath::sign(dir[i]) * std::max(dir[i] * low[i], dir[i] * up[i]); + + return center + dir; +} diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index 3d54176..33d8637 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -81,7 +81,7 @@ public: KpFont font; color4f color{ 0, 0, 0, 1 }; KeTextLayout layout{ k_horz_top }; - bool billboard{ false }; // ǷԹģʽʾtexttruetexthDirʼճĻҲ࣬vDirʼճĻ² + bool billboard{ true }; // ǷԹģʽʾtexttruetexthDirʼճĻҲ࣬vDirʼճĻ² float yaw{ 0 }; // text-boxƽĴߣĵ㣩תǶȣȣ float pitch{ 0 }; // hDirvDirתǶȣȣ }; @@ -203,18 +203,20 @@ public: void setSwapped_(int dimSwap) { dimSwapped_ = dimSwap; } private: + size_t calcSize_(void* cxt) const final; + void draw_(KvPaint*, bool calcBox) const; void drawTicks_(KvPaint*, bool calcBox) const; // п̶ void drawTick_(KvPaint*, const point3& anchor, double length, bool calcBox) const; // Ƶ̶ߣ̶븱̶ void drawText_(KvPaint* paint, const std::string_view& label, const KpTextContext& cxt, const point3& anchor, bool calcBox) const; - // tickij - vec3 calcTickOrient_(KvPaint*) const; - int labelAlignment_(KvPaint* paint, bool toggleTopBottom) const; // labelorientationжlabelalignment bool tickAndLabelInSameSide_() const; // жticktick-labelǷλͬ - size_t calcSize_(void* cxt) const final; + // tickij + vec3 calcTickOrient_(KvPaint*) const; + + point3 calcTitleAnchor_(KvPaint*) const; // 3dռı3topLeft, hDir, vDir void calcTextPos_(KvPaint*, const std::string_view& label, const KpTextContext& cxt, diff --git a/src/plot/KcCoord3d.cpp b/src/plot/KcCoord3d.cpp index df2091c..3930f06 100644 --- a/src/plot/KcCoord3d.cpp +++ b/src/plot/KcCoord3d.cpp @@ -77,12 +77,6 @@ KcCoord3d::KcCoord3d(const point3& lower, const point3& upper) } -KcCoord3d::aabb_t KcCoord3d::boundingBox() const -{ - return { lower(), upper() }; -} - - void KcCoord3d::forAxis(std::function fn) const { for (unsigned i = 0; i < std::size(axes_); i++) @@ -111,10 +105,16 @@ KcCoord3d::size_t KcCoord3d::calcSize_(void* cxt) const layCoord_->calcSize(cxt); + forAxis([cxt](KcAxis& axis) { + if (axis.visible()) + axis.calcSize(cxt); + return true; + }); + if (!layCoord_->empty()) { // ҪʱżrcCoord_ - aabb_t box(lower(), upper()); - auto corns = box.allCorners(); + auto corns = boundingBox().allCorners(); + rcCoord_.setNull(); for (auto& i : corns) { i = ((KvPaint*)cxt)->projectp(i); diff --git a/src/plot/KcCoord3d.h b/src/plot/KcCoord3d.h index 4dd8087..8a38c45 100644 --- a/src/plot/KcCoord3d.h +++ b/src/plot/KcCoord3d.h @@ -20,8 +20,6 @@ public: KcCoord3d(); KcCoord3d(const point3& lower, const point3& upper); - aabb_t boundingBox() const override; - void forAxis(std::function) const override; void forPlane(std::function) const override; diff --git a/src/plot/KvCoord.cpp b/src/plot/KvCoord.cpp index 26404ac..c278bcf 100644 --- a/src/plot/KvCoord.cpp +++ b/src/plot/KvCoord.cpp @@ -134,7 +134,18 @@ void KvCoord::draw(KvPaint* paint) const KvCoord::aabb_t KvCoord::boundingBox() const { - auto l = lower(), u = upper(); + aabb_t box(lower(), upper()); + + // NB: axisaabb֮󣬻ӰͶӰ + // NB: ⣬ܶԷKvCoord::boundingBox֪{ lower, upper } + //forAxis([&box](KcAxis& axis) { + // if (axis.visible()) + // box.merge(axis.boundingBox()); + // return true; + // }); + + auto& l = box.lower(); + auto& u = box.upper(); switch (swapStatus_) { @@ -154,7 +165,7 @@ KvCoord::aabb_t KvCoord::boundingBox() const break; } - return { l, u }; + return box; } diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index 128f692..2777476 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -154,8 +154,10 @@ void KvPlot::update() int KvPlot::fixPlotView_() { - if (dim() != 2) + if (dim() != 2) { + assert(paint_->viewport() == coord_->getPlotRect()); return 0; // ֻplot2d + } auto rcCanvas = paint_->viewport(); auto rcPlot = coord_->getPlotRect(); @@ -254,7 +256,7 @@ void KvPlot::syncLegendAndColorBar_(KvPlottable* removedPlt, KvPlottable* addedP legend_->removeItem(removedPlt); } else { - assert(colorBar_); + //assert(colorBar_); // TODO: if (colorBar_) { KuLayoutHelper::take(colorBar_); if (colorBar_) delete colorBar_; @@ -268,7 +270,7 @@ void KvPlot::syncLegendAndColorBar_(KvPlottable* removedPlt, KvPlottable* addedP legend_->addItem(addedPlt); } else { - assert(colorBar_ == nullptr); + //assert(colorBar_ == nullptr); if (colorBar_) { // TODO: δcolor-bar KuLayoutHelper::take(colorBar_); delete colorBar_; diff --git a/src/plot/KvPlot.h b/src/plot/KvPlot.h index b47a382..805804b 100644 --- a/src/plot/KvPlot.h +++ b/src/plot/KvPlot.h @@ -46,6 +46,9 @@ public: bool showColorBar() const { return showColorBar_; } bool& showColorBar() { return showColorBar_; } + bool showLayoutRect() const { return showLayoutRect_; } + bool& showLayoutRect() { return showLayoutRect_; } + KvPaint& paint() { return *paint_.get(); } KvCoord& coord() { return *coord_.get(); } diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index ffe86b9..6043f39 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -287,6 +287,8 @@ void KvRdPlot::showPlotProperty_() ImGui::EndCombo(); } + ImGui::Checkbox("Show Layout Rect", &plot_->showLayoutRect()); + ImGuiX::treePop(); } } -- Gitee From 8f62979e89c6ab60ac5b63fe3af14c7cabafdbc7 Mon Sep 17 00:00:00 2001 From: koala999cn Date: Tue, 3 Jan 2023 10:31:08 +0800 Subject: [PATCH 59/68] clean code --- src/plot/KcAxis.cpp | 58 +++++++++++++++------------------------------ src/plot/KvPlot.cpp | 11 ++++++++- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 37253fa..dd2af70 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -47,38 +47,42 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const { assert(visible()); - if (calcBox) - box_ = aabb_t(start(), end()); - // draw baseline - if (showBaseline() && baselineCxt_.style != KpPen::k_none && !calcBox) { - paint->apply(baselineCxt_); - paint->drawLine(start(), end()); // + if (showBaseline() && baselineCxt_.style != KpPen::k_none) { + if (!calcBox) { + paint->apply(baselineCxt_); + paint->drawLine(start(), end()); // + } + else { + box_ = aabb_t(start(), end()); + } } auto realShowTitle = showTitle() && !title().empty(); // tickOrient_labelOrient_ֻһ if (realShowTitle || showTick() || showLabel()) { - // TODO: if (calcBox) plot3dʱ򲻻üģʽ - tickOrient_ = calcTickOrient_(paint); - if (paint->currentCoord() == KvPaint::k_coord_screen) - tickOrient_.y() *= -1; // TODO: ޸õķ - labelOrient_ = tickCxt_.side == k_inside ? -tickOrient_ : tickOrient_; + if (calcBox) { + tickOrient_ = calcTickOrient_(paint); + if (paint->currentCoord() == KvPaint::k_coord_screen) + tickOrient_.y() *= -1; // TODO: ޸õķ + labelOrient_ = tickCxt_.side == k_inside ? -tickOrient_ : tickOrient_; + } } // draw ticks & label if (showTick() || showLabel()) drawTicks_(paint, calcBox); - //else if (realShowTitle) - // titleAnchor_ = (start() + end()) / 2 + labelOrient_ * titlePadding_ / paint->projectv(labelOrient_).length(); // draw title if (realShowTitle) { - paint->setColor(titleContext().color); + if (calcBox) - titleAnchor_ = calcTitleAnchor_(paint); + titleAnchor_ = calcTitleAnchor_(paint); // NB: ȷÿȾֻһ + else + paint->setColor(titleContext().color); + drawText_(paint, title_, titleCxt_, titleAnchor_, calcBox); } } @@ -147,13 +151,6 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const if (showLabel()) labelAnchors.resize(ticks.size()); -/* if (showTitle()) { - titleAnchor_ = (start() + end()) / 2 + labelOrient_ * titlePadding_ * labelPaddingPerPixel; - - if (sameSide && showTick()) - titleAnchor_ += tickOrient_ * tickCxt_.length * tickLenPerPixel; - }*/ - for (unsigned i = 0; i < ticks.size(); i++) { auto anchor = tickPos(ticks[i]); @@ -177,24 +174,7 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const for (unsigned i = 0; i < ticks.size(); i++) { auto label = i < labels_.size() ? labels_[i] : labels[i]; drawText_(paint, label, labelCxt_, labelAnchors[i], calcBox); - - //if (showTitle()) - // maxLabelSize = point2::ceil(maxLabelSize, paint->textSize(label.c_str())); } - - /* - if (showTitle() || calcBox) { - - vec3 h = vec3::unitX() * maxLabelSize.x(); // TODO: hDir - vec3 v = vec3::unitY() * maxLabelSize.y(); // TODO: vDir - - h = h.projectedTo(ll); - v = v.projectedTo(ll); - - auto maxSqLen = std::max(h.squaredLength(), v.squaredLength()); - - titleAnchor_ += labelOrient_ * (std::sqrt(maxSqLen) + labelPadding_ ) * labelPaddingPerPixel; - }*/ } // minor diff --git a/src/plot/KvPlot.cpp b/src/plot/KvPlot.cpp index 2777476..32343b5 100644 --- a/src/plot/KvPlot.cpp +++ b/src/plot/KvPlot.cpp @@ -103,11 +103,18 @@ void KvPlot::update() if (axisSwapped) paint_->pushLocal(coord_->axisSwapMatrix()); // ѹύautoProject_Ҫ + auto oRect = paint_->viewport(); + auto iRect = oRect; + auto margs = margins(); + iRect.deflate({ margs.left(), margs.top() }, { margs.right(), margs.bottom() }); + //paint_->setViewport(iRect); + autoProject_(); paint_->beginPaint(); - updateLayout_(paint_->viewport()); + updateLayout_(oRect); + assert(layout_->innerRect() == iRect); paint_->setViewport(layout_->innerRect()); // ˴ѹinnerRectKcCoord3dfixPlotView_plot3dӿƫ // TODO: źͨõʵ @@ -115,6 +122,8 @@ void KvPlot::update() // ӿƫƣҪplot2dϵlowerƵӿڵ½ǣ auto locals = fixPlotView_(); // ˴localsջpop + //paint_->setViewport(coord_->getPlotRect()); + coord_->draw(paint_.get()); auto axisInversed = coord_->axisInversed(); -- Gitee From 27122d75a086def6e85c9abf10ec0bf7c6191bfa Mon Sep 17 00:00:00 2001 From: koala999cn Date: Tue, 3 Jan 2023 10:31:15 +0800 Subject: [PATCH 60/68] update TODO.md --- TODO.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TODO.md b/TODO.md index 8c4cf50..f0d3253 100644 --- a/TODO.md +++ b/TODO.md @@ -10,7 +10,7 @@ 5. plot3d的legend布局 --> ok 6. colorbar --> ok 7. axis的反向设置 --> ok -8. 中文字体显示 +8. 中文字体显示 --> 暂时使用imgui的中文字体支持 9. opengl加速 10. 导出图片 11. 导出矢量图 @@ -28,9 +28,9 @@ 3. 给数据加时间戳stamp ## FIXME -1. 使用layout系统后,plot的axis留白出现问题 -2. 三维坐标系下,虚线的绘制(ImGui)在旋转到特定方向时会出现错位 --> 使用opengl绘制后,该问题没再出现 +1. 使用layout系统后,plot的axis留白出现问题 --> 主要因为布局计算之后压入了缩放矩阵,而前期计算的anchor和contentSize(世界坐标)却没有正常缩放 +2. 三维坐标系下,虚线的绘制(ImGui)在旋转到特定方向时会出现错位 --> 使用opengl绘制后,该问题没再出现,估计由于计算误差引起 3. 加载大的text数据文件很慢 4. 坐标轴刻度旋转时出现突变 -5. 3d透视投影模式下,坐标轴的刻度线和文字全部消失 +5. 3d透视投影模式下,坐标轴的刻度线和文字全部消失 --> 须同步修改opengl的投影方式 6. plot3d在交换坐标轴后,鼠标操控坐标系姿态出现问题 \ No newline at end of file -- Gitee From 0cc540729d731ccb517ec5b2fba8e25ae9676328 Mon Sep 17 00:00:00 2001 From: koala999 Date: Wed, 4 Jan 2023 10:05:32 +0800 Subject: [PATCH 61/68] =?UTF-8?q?fix:=20=E7=94=B1=E4=BA=8E=E5=8E=8B?= =?UTF-8?q?=E5=85=A5=E7=BC=A9=E6=94=BE=E7=9F=A9=E9=98=B5=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E5=9D=90=E6=A0=87=E8=BD=B4title=E5=AE=9A=E4=BD=8D?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 2 +- src/plot/KcAxis.cpp | 33 ++++++++++++++++++++------------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/TODO.md b/TODO.md index f0d3253..8c127d2 100644 --- a/TODO.md +++ b/TODO.md @@ -28,7 +28,7 @@ 3. 给数据加时间戳stamp ## FIXME -1. 使用layout系统后,plot的axis留白出现问题 --> 主要因为布局计算之后压入了缩放矩阵,而前期计算的anchor和contentSize(世界坐标)却没有正常缩放 +1. 使用layout系统后,plot的axis留白出现问题 --> tick-label超出coord的innerRect区域 2. 三维坐标系下,虚线的绘制(ImGui)在旋转到特定方向时会出现错位 --> 使用opengl绘制后,该问题没再出现,估计由于计算误差引起 3. 加载大的text数据文件很慢 4. 坐标轴刻度旋转时出现突变 diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index dd2af70..0798dc5 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -47,27 +47,32 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const { assert(visible()); + // NB: calcBoxǷΪtrue¼box_ + // Ϊ㲼֣calcBoxΪtrueʵƣcalcBoxΪfalseʱ + // 仯ջܲͬرǺ߿ѹscale + // ͵ǰڼbox_صijȺλò + box_.setNull(); + // draw baseline if (showBaseline() && baselineCxt_.style != KpPen::k_none) { if (!calcBox) { paint->apply(baselineCxt_); paint->drawLine(start(), end()); // } - else { - box_ = aabb_t(start(), end()); - } + + box_ = aabb_t(start(), end()); } auto realShowTitle = showTitle() && !title().empty(); // tickOrient_labelOrient_ֻһ if (realShowTitle || showTick() || showLabel()) { - if (calcBox) { + //if (calcBox) { tickOrient_ = calcTickOrient_(paint); if (paint->currentCoord() == KvPaint::k_coord_screen) tickOrient_.y() *= -1; // TODO: ޸õķ labelOrient_ = tickCxt_.side == k_inside ? -tickOrient_ : tickOrient_; - } + //} } @@ -78,11 +83,10 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const // draw title if (realShowTitle) { - if (calcBox) - titleAnchor_ = calcTitleAnchor_(paint); // NB: ȷÿȾֻһ - else + if (!calcBox) paint->setColor(titleContext().color); + titleAnchor_ = calcTitleAnchor_(paint); drawText_(paint, title_, titleCxt_, titleAnchor_, calcBox); } } @@ -195,11 +199,11 @@ void KcAxis::drawTick_(KvPaint* paint, const point3& anchor, double length, bool auto d = tickOrient_ * length; if (!calcBox) paint->drawLine(tickCxt_.side == k_bothside ? anchor - d : anchor, anchor + d); - else { + //else { box_.merge(anchor + d); if (tickCxt_.side == k_bothside) box_.merge(anchor - d); - } + //} } @@ -421,12 +425,12 @@ void KcAxis::drawText_(KvPaint* paint, const std::string_view& label, const KpTe if (!calcBox) { paint->drawText(topLeft, hDir, vDir, label.data()); } - else { + //else { auto sz = paint->textSize(label.data()); auto h = hDir * sz.x() / paint->projectv(hDir).length(); auto v = vDir * sz.y() / paint->projectv(vDir).length(); box_.merge({ topLeft, topLeft + h + v }); - } + //} } @@ -437,9 +441,12 @@ KcAxis::point3 KcAxis::calcTitleAnchor_(KvPaint* paint) const aabb_t inner(start(), end()); auto low = box_.lower() - inner.lower(); auto up = box_.upper() - inner.upper(); - point3 dir = labelOrient_.getNormalize(); + point3 dir = labelOrient_; for (int i = 0; i < 3; i++) dir[i] = KtuMath::sign(dir[i]) * std::max(dir[i] * low[i], dir[i] * up[i]); + // padding + dir += labelOrient_ * titlePadding_ / paint->projectv(labelOrient_).length(); + return center + dir; } -- Gitee From 21f1862e9f784191aa53cdd0cdcc2c3707f0d0d1 Mon Sep 17 00:00:00 2001 From: koala999 Date: Wed, 4 Jan 2023 11:33:47 +0800 Subject: [PATCH 62/68] =?UTF-8?q?refactor:=20=E6=9B=B4=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=9A=84=E5=9D=90=E6=A0=87=E8=BD=B4label=E5=B8=83=E5=B1=80?= =?UTF-8?q?=EF=BC=88=E5=B0=BD=E9=87=8F=E9=81=BF=E5=85=8Dlabel=E7=BB=98?= =?UTF-8?q?=E5=88=B6=E5=88=B0=E5=9D=90=E6=A0=87=E8=BD=B4=E4=B8=8A=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plot/KcAxis.cpp | 45 ++++++++++++++++++++++----------------------- src/plot/KcAxis.h | 5 ++++- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 0798dc5..bc7919d 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -142,10 +142,8 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const // Ļ1س߶ȣ൱ٸλ - auto tl = paint->projectv(tickOrient_); - auto ll = paint->projectv(labelOrient_); - float_t tickLenPerPixel = 1 / tl.length(); - float_t labelPaddingPerPixel = 1 / ll.length(); + float_t tickLenPerPixel = 1. / paint->projectv(tickOrient_).length(); + float_t labelPaddingPerPixel = 1. / paint->projectv(labelOrient_).length(); if (!calcBox) paint->apply(tickCxt_); @@ -174,9 +172,10 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const // TODO: paint->setFont(); paint->setColor(labelContext().color); auto& labels = ticker()->labels(); - point2 maxLabelSize(0); for (unsigned i = 0; i < ticks.size(); i++) { auto label = i < labels_.size() ? labels_[i] : labels[i]; + paint->setPointSize(3); + paint->drawPoint(labelAnchors[i]); // for debug drawText_(paint, label, labelCxt_, labelAnchors[i], calcBox); } } @@ -207,22 +206,15 @@ void KcAxis::drawTick_(KvPaint* paint, const point3& anchor, double length, bool } -int KcAxis::labelAlignment_(KvPaint* paint, bool toggleTopBottom) const +int KcAxis::labelAlignment_(KvPaint* paint) const { - int align(0); - auto labelOrient = paint->localToWorldV(labelOrient_); // labelOrient_ + auto axisOrient = paint->projectv(end() - start()); + auto labelOrient = paint->projectv(labelOrient_); // TODO: labeltitle - if (labelOrient.x() > 0) - align |= KeAlignment::k_left; - else if (labelOrient.x() < 0) - align |= KeAlignment::k_right; - - if (labelOrient.y() > 0 || labelOrient.z() < 0 ) - align |= toggleTopBottom ? KeAlignment::k_top : KeAlignment::k_bottom; - else if (labelOrient.y() < 0 || labelOrient.z() > 0) - align |= toggleTopBottom ? KeAlignment::k_bottom : KeAlignment::k_top; - - return align; + if (std::abs(axisOrient.x()) < std::abs(axisOrient.y())) + return labelOrient.x() > 0 ? KeAlignment::k_left : KeAlignment::k_right; + else + return labelOrient.y() > 0 ? KeAlignment::k_top : KeAlignment::k_bottom; } @@ -361,9 +353,7 @@ void KcAxis::calcTextPos_(KvPaint* paint, const std::string_view& label, const K if (cxt.billboard) { // ģʽʼ˳+xչ - bool toggle = paint->currentCoord() == KvPaint::k_coord_screen || paint->currentCoord() == KvPaint::k_coord_local_screen; - KeAlignment align = labelAlignment_(paint, toggle); - + auto align = labelAlignment_(paint); auto anchorInScreen = paint->projectp(anchor); auto rc = KuLayoutUtil::anchorAlignedRect({ anchorInScreen.x(), anchorInScreen.y() }, textBox, align); topLeft = paint->unprojectp({ rc.lower().x(), rc.lower().y(), anchorInScreen.z() }); @@ -383,9 +373,11 @@ void KcAxis::calcTextPos_(KvPaint* paint, const std::string_view& label, const K topLeft = anchor - hDir * (textBox.x() / 2) / paint->projectv(hDir).length(); } + // fixTextLayout_ҪtextBoxΪߴ磬˴б任 textBox /= point2d(paint->projectv(hDir).length(), paint->projectv(vDir).length()); - fixTextLayout_(cxt.layout, textBox, topLeft, hDir, vDir); + + fixTextRotation_(cxt, anchor, topLeft, hDir, vDir); } @@ -414,6 +406,13 @@ void KcAxis::fixTextLayout_(KeTextLayout lay, const size_t& textBox, point3& top } } + +void KcAxis::fixTextRotation_(const KpTextContext& cxt, const point3& anchor, point3& topLeft, vec3& hDir, vec3& vDir) const +{ + +} + + void KcAxis::drawText_(KvPaint* paint, const std::string_view& label, const KpTextContext& cxt, const point3& anchor, bool calcBox) const { point3 topLeft; diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index 33d8637..2fc1241 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -210,7 +210,7 @@ private: void drawTick_(KvPaint*, const point3& anchor, double length, bool calcBox) const; // Ƶ̶ߣ̶븱̶ void drawText_(KvPaint* paint, const std::string_view& label, const KpTextContext& cxt, const point3& anchor, bool calcBox) const; - int labelAlignment_(KvPaint* paint, bool toggleTopBottom) const; // labelorientationжlabelalignment + int labelAlignment_(KvPaint* paint) const; // labelorientationжlabelalignment bool tickAndLabelInSameSide_() const; // жticktick-labelǷλͬ // tickij @@ -225,6 +225,9 @@ private: // layouttopLefthDir & vDir static void fixTextLayout_(KeTextLayout lay, const size_t& textBox, point3& topLeft, vec3& hDir, vec3& vDir); + // ıתyaw & pitch + void fixTextRotation_(const KpTextContext& cxt, const point3& anchor, point3& topLeft, vec3& hDir, vec3& vDir) const; + private: KeType type_; std::string title_; -- Gitee From 2ffd70fd7f7dc7072581339d4e8653b084ef4b48 Mon Sep 17 00:00:00 2001 From: koala999 Date: Wed, 4 Jan 2023 20:04:17 +0800 Subject: [PATCH 63/68] =?UTF-8?q?add:=20=E5=9D=90=E6=A0=87=E8=BD=B4?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E7=9A=84=E6=97=8B=E8=BD=AC=E5=92=8Cpadding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/3d/KtLine.h | 13 +++-- src/3d/KtProjector3d.h | 4 +- src/imapp/KcImPaint.cpp | 2 +- src/plot/KcAxis.cpp | 105 +++++++++++++++++++++++++++++----------- src/plot/KcAxis.h | 11 ++++- src/render/KvRdPlot.cpp | 74 ++++++++++++++-------------- 6 files changed, 133 insertions(+), 76 deletions(-) diff --git a/src/3d/KtLine.h b/src/3d/KtLine.h index 4f29049..b1a9c52 100644 --- a/src/3d/KtLine.h +++ b/src/3d/KtLine.h @@ -2,7 +2,8 @@ #include "KtVector3.h" // ֱߣL(t) = B + tM -template +// @RAY: trueʾΪߣlineֻdir_չ +template class KtLine { using point3 = KtPoint; @@ -23,6 +24,8 @@ public: const vec3& dir() const { return dir_; } vec3& dir() { return dir_; } + constexpr bool isRay() const { return RAY; } + point3 pointAt(KReal t) { return point_ + dir_ * t; } KReal distanceTo(const point3& pt) { return std::sqrt(squaredDistanceTo(pt)); } // ߼ľ @@ -49,8 +52,8 @@ protected: // PֱL(t)=B+tM֮ľD = |P-(B+t0M)| // t0 = M(P-B)/(MM) -template -KReal KtLine::squaredDistanceTo(const point3& pt) +template +KReal KtLine::squaredDistanceTo(const point3& pt) { auto diff = pt - point_; // P-B auto t0 = diff.dot(dir_); // M(P-B) @@ -70,8 +73,8 @@ KReal KtLine::squaredDistanceTo(const point3& pt) // s = (be-cd)/(ac-b^2), t = (bd-ae)/(ac-b^2), // ac-b^2 = 0, ֱƽУʱʸһԿȡ // s = -d/a, t = 0 -template -KReal KtLine::squaredDistanceTo(const KtLine& l) +template +KReal KtLine::squaredDistanceTo(const KtLine& l) { auto diff = point_ - l.point(); KReal a = dir().squaredLength(); diff --git a/src/3d/KtProjector3d.h b/src/3d/KtProjector3d.h index e65e393..61a7fa1 100644 --- a/src/3d/KtProjector3d.h +++ b/src/3d/KtProjector3d.h @@ -292,8 +292,8 @@ void KtProjector::setViewport(const rect& vp) } // x, yƫ0.5൱round - vsMat_.m03() += 0.5; - vsMat_.m13() += 0.5; + //vsMat_.m03() += 0.5; + //vsMat_.m13() += 0.5; nsMat_ = vsMat_ * nvMat_; wsMat_ = nsMat_ * vpMat_; diff --git a/src/imapp/KcImPaint.cpp b/src/imapp/KcImPaint.cpp index 9914197..0b83103 100644 --- a/src/imapp/KcImPaint.cpp +++ b/src/imapp/KcImPaint.cpp @@ -384,7 +384,7 @@ KcImPaint::point2 KcImPaint::textSize(const char* text) const ImVec2 KcImPaint::project_(const point3& pt, bool round) const { auto pos = projectp(pt); - return round ? ImVec2(int(pos.x()), int(pos.y())) : ImVec2(pos.x(), pos.y()); + return round ? ImVec2(std::round(pos.x()), std::round(pos.y())) : ImVec2(pos.x(), pos.y()); } diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index bc7919d..685127e 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -68,10 +68,8 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const // tickOrient_labelOrient_ֻһ if (realShowTitle || showTick() || showLabel()) { //if (calcBox) { - tickOrient_ = calcTickOrient_(paint); - if (paint->currentCoord() == KvPaint::k_coord_screen) - tickOrient_.y() *= -1; // TODO: ޸õķ - labelOrient_ = tickCxt_.side == k_inside ? -tickOrient_ : tickOrient_; + calcTickOrient_(paint); + calcLabelOrient_(paint); //} } @@ -86,16 +84,16 @@ void KcAxis::draw_(KvPaint* paint, bool calcBox) const if (!calcBox) paint->setColor(titleContext().color); - titleAnchor_ = calcTitleAnchor_(paint); + calcTitleAnchor_(paint); drawText_(paint, title_, titleCxt_, titleAnchor_, calcBox); } } -KcAxis::vec3 KcAxis::calcTickOrient_(KvPaint* paint) const +KcAxis::vec3 KcAxis::outsideOrient_() const { // 12Ĭ - static const vec3 baseOrient[] = { + static const vec3 outsideOrient[] = { -KcAxis::vec3::unitX(), // k_near_left KcAxis::vec3::unitX(), // k_near_right -KcAxis::vec3::unitY(), // k_near_bottom @@ -112,21 +110,59 @@ KcAxis::vec3 KcAxis::calcTickOrient_(KvPaint* paint) const KcAxis::vec3::unitX() // k_ceil_right }; - // ̬תyawpitch任ϵת + return outsideOrient[typeReal()]; +} + + +KcAxis::vec3 KcAxis::insideOrient_() const +{ + return -outsideOrient_(); +} + + +KcAxis::vec3 KcAxis::axisOrient_() const +{ + return (end() - start()).getNormalize(); +} - vec3 orient = (tickCxt_.side == k_inside) ? -baseOrient[typeReal()] : baseOrient[typeReal()]; + +void KcAxis::calcTickOrient_(KvPaint* paint) const +{ // ˴orientΪ - - auto vAxis = paint->localToWorldV(end() - start()).getNormalize(); // ᷽ʸ + vec3 tickOrient = (tickCxt_.side == k_inside) ? insideOrient_() : outsideOrient_(); + + auto vAxis = paint->localToWorldV(axisOrient_()); // ᷽ʸ KtMatrix3 mat; mat.fromAngleAxis(tickCxt_.pitch, vAxis); // תpitch - orient = mat * orient; + tickOrient = mat * tickOrient; - auto vPrep = orient.cross(vAxis); // ̶ߺĴֱʸ + auto vPrep = tickOrient.cross(vAxis); // ̶ߺĴֱʸ mat.fromAngleAxis(tickCxt_.yaw, vPrep.getNormalize()); - orient = mat * orient; + tickOrient = mat * tickOrient; - return paint->worldToLocalV(orient).getNormalize(); // 任ؾֲϵ + tickOrient_ = paint->worldToLocalV(tickOrient).getNormalize(); // 任ؾֲϵ + + if (paint->currentCoord() == KvPaint::k_coord_screen) + tickOrient_.y() *= -1; // TODO: ޸õķ +} + + +void KcAxis::calcLabelOrient_(KvPaint* paint) const +{ + labelOrient_ = tickCxt_.side == k_inside ? -tickOrient_ : tickOrient_; + + // labelOrient_任Ϊֱaxisķ + auto axisOrient = axisOrient_(); + labelOrient_ = axisOrient.cross(labelOrient_); + labelOrient_ = labelOrient_.cross(axisOrient).getNormalize(); + + // NB:ȷlabelʼճࣨtickOrientaxisOrientƽʱlabelOrient_ָڲࣩ + if (labelOrient_.dot(outsideOrient_()) < 0) + labelOrient_ *= -1; + + KtMatrix3 mat; + mat.fromAngleAxis(labelCxt_.pitch, axisOrient); + labelOrient_ = mat * labelOrient_; } @@ -174,9 +210,9 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const auto& labels = ticker()->labels(); for (unsigned i = 0; i < ticks.size(); i++) { auto label = i < labels_.size() ? labels_[i] : labels[i]; - paint->setPointSize(3); - paint->drawPoint(labelAnchors[i]); // for debug drawText_(paint, label, labelCxt_, labelAnchors[i], calcBox); + //paint->setPointSize(3); + //paint->drawPoint(labelAnchors[i]); // for debug } } @@ -211,10 +247,12 @@ int KcAxis::labelAlignment_(KvPaint* paint) const auto axisOrient = paint->projectv(end() - start()); auto labelOrient = paint->projectv(labelOrient_); // TODO: labeltitle - if (std::abs(axisOrient.x()) < std::abs(axisOrient.y())) + if (std::abs(axisOrient.x()) < std::abs(axisOrient.y())) { return labelOrient.x() > 0 ? KeAlignment::k_left : KeAlignment::k_right; - else + } + else { return labelOrient.y() > 0 ? KeAlignment::k_top : KeAlignment::k_bottom; + } } @@ -353,16 +391,17 @@ void KcAxis::calcTextPos_(KvPaint* paint, const std::string_view& label, const K if (cxt.billboard) { // ģʽʼ˳+xչ + hDir = paint->unprojectv(vec3::unitX()).getNormalize(); + vDir = paint->unprojectv(vec3::unitY()).getNormalize(); + auto align = labelAlignment_(paint); auto anchorInScreen = paint->projectp(anchor); auto rc = KuLayoutUtil::anchorAlignedRect({ anchorInScreen.x(), anchorInScreen.y() }, textBox, align); topLeft = paint->unprojectp({ rc.lower().x(), rc.lower().y(), anchorInScreen.z() }); - hDir = paint->unprojectv(vec3::unitX()).getNormalize(); - vDir = paint->unprojectv(vec3::unitY()).getNormalize(); } else { vDir = labelOrient_; - hDir = (end() - start()).getNormalize(); + hDir = axisOrient_(); vec3 h = paint->projectv(hDir); vec3 v = paint->projectv(vDir); @@ -409,7 +448,16 @@ void KcAxis::fixTextLayout_(KeTextLayout lay, const size_t& textBox, point3& top void KcAxis::fixTextRotation_(const KpTextContext& cxt, const point3& anchor, point3& topLeft, vec3& hDir, vec3& vDir) const { + auto vAxis = axisOrient_(); + KtMatrix3 mat; + mat.fromAngleAxis(cxt.yaw, hDir.cross(vDir).normalize()); + + hDir = mat * hDir; + vDir = mat * vDir; + //vDir = hDir.cross(vDir).cross(hDir); + assert(KtuMath::almostEqual(hDir.dot(vDir), 0)); + topLeft = anchor + mat * (topLeft - anchor); } @@ -433,19 +481,22 @@ void KcAxis::drawText_(KvPaint* paint, const std::string_view& label, const KpTe } -KcAxis::point3 KcAxis::calcTitleAnchor_(KvPaint* paint) const +void KcAxis::calcTitleAnchor_(KvPaint* paint) const { auto center = (start() + end()) / 2; aabb_t inner(start(), end()); auto low = box_.lower() - inner.lower(); auto up = box_.upper() - inner.upper(); - point3 dir = labelOrient_; + auto orient = labelOrient_; + point3 shift; for (int i = 0; i < 3; i++) - dir[i] = KtuMath::sign(dir[i]) * std::max(dir[i] * low[i], dir[i] * up[i]); + shift[i] = std::max(orient[i] * low[i], orient[i] * up[i]); + + titleAnchor_ = center + orient * shift; // padding - dir += labelOrient_ * titlePadding_ / paint->projectv(labelOrient_).length(); + titleAnchor_ += orient * titlePadding_ / paint->projectv(orient).length(); - return center + dir; + // paint->drawBox(box_.lower(), box_.upper()); // for debug } diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index 2fc1241..c21d769 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -205,6 +205,10 @@ public: private: size_t calcSize_(void* cxt) const final; + vec3 outsideOrient_() const; + vec3 insideOrient_() const; + vec3 axisOrient_() const; + void draw_(KvPaint*, bool calcBox) const; void drawTicks_(KvPaint*, bool calcBox) const; // п̶ void drawTick_(KvPaint*, const point3& anchor, double length, bool calcBox) const; // Ƶ̶ߣ̶븱̶ @@ -214,9 +218,12 @@ private: bool tickAndLabelInSameSide_() const; // жticktick-labelǷλͬ // tickij - vec3 calcTickOrient_(KvPaint*) const; + void calcTickOrient_(KvPaint*) const; + + // labelij. calcTickOrient_֮ + void calcLabelOrient_(KvPaint*) const; - point3 calcTitleAnchor_(KvPaint*) const; + void calcTitleAnchor_(KvPaint*) const; // 3dռı3topLeft, hDir, vDir void calcTextPos_(KvPaint*, const std::string_view& label, const KpTextContext& cxt, diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index 6043f39..d05fb04 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -243,38 +243,18 @@ void KvRdPlot::showPlotProperty_() ImGui::ColorEdit4("Background", plot_->background().color); - bool anti = plot_->paint().antialiasing(); - if (ImGui::Checkbox("Antialiasing", &anti)) - plot_->paint().enableAntialiasing(anti); - auto& coord = plot_->coord(); - - if (ImGuiX::treePush("Range", true)) { - ImGui::Checkbox("Auto Fit", &plot_->autoFit()); - - auto lower = point3f(coord.lower()); - auto upper = point3f(coord.upper()); - auto speed = (upper - lower) * 0.1; - for (unsigned i = 0; i < speed.size(); i++) - if (speed.at(i) == 0) - speed.at(i) = 1; - - static const char* axisName[] = { "X", "Y", "Z" }; - for (char i = 0; i < plot_->dim(); i++) { - if (ImGui::DragFloatRange2(axisName[i], &lower[i], &upper[i], speed[i])) { - coord.setExtents(lower, upper); - plot_->autoFit() = false; - } + auto lower = point3f(coord.lower()); + auto upper = point3f(coord.upper()); + auto speed = (upper - lower) * 0.1; + for (unsigned i = 0; i < speed.size(); i++) + if (speed.at(i) == 0) speed.at(i) = 1; + static const char* axisName[] = { "X Range", "Y Range", "Z Range" }; + for (char i = 0; i < plot_->dim(); i++) { + if (ImGui::DragFloatRange2(axisName[i], &lower[i], &upper[i], speed[i])) { + coord.setExtents(lower, upper); + plot_->autoFit() = false; } - - ImGuiX::treePop(); - } - - const char* label[] = { "Invert X", "Invert Y", "Invert Z" }; - for (int i = 0; i < plot_->dim(); i++) { - bool inv = coord.axisInversed(i); - if (ImGui::Checkbox(label[i], &inv)) - coord.inverseAxis(i, inv); } const char* swapStr[] = { "No Swap", "Swap XY", "Swap XZ", "Swap YZ" }; @@ -287,6 +267,18 @@ void KvRdPlot::showPlotProperty_() ImGui::EndCombo(); } + ImGui::Checkbox("Auto Fit", &plot_->autoFit()); + const char* label[] = { "Invert X", "Invert Y", "Invert Z" }; + for (int i = 0; i < plot_->dim(); i++) { + bool inv = coord.axisInversed(i); + if (ImGui::Checkbox(label[i], &inv)) + coord.inverseAxis(i, inv); + } + + bool anti = plot_->paint().antialiasing(); + if (ImGui::Checkbox("Antialiasing", &anti)) + plot_->paint().enableAntialiasing(anti); + ImGui::Checkbox("Show Layout Rect", &plot_->showLayoutRect()); ImGuiX::treePop(); @@ -376,18 +368,20 @@ void KvRdPlot::showCoordProperty_() namespace kPrivate { - void tickContext(KcAxis::KpTickContext& cxt) + void tickContext(KcAxis::KpTickContext& cxt, bool showSide) { ImGuiX::pen(&cxt, false); // no style. tickʼʹsolid ImGui::PushID(&cxt); - const static char* side[] = { "inside", "outside", "bothside" }; - if (ImGui::BeginCombo("Side", side[cxt.side])) { - for (unsigned i = 0; i < std::size(side); i++) - if (ImGui::Selectable(side[i], i == cxt.side)) - cxt.side = KcAxis::KeTickSide(i); - ImGui::EndCombo(); + if (showSide) { + const static char* side[] = { "inside", "outside", "bothside" }; + if (ImGui::BeginCombo("Side", side[cxt.side])) { + for (unsigned i = 0; i < std::size(side); i++) + if (ImGui::Selectable(side[i], i == cxt.side)) + cxt.side = KcAxis::KeTickSide(i); + ImGui::EndCombo(); + } } ImGui::SliderFloat("Length", &cxt.length, 0, 25, "%.1f px"); @@ -478,20 +472,21 @@ void KvRdPlot::showAxisProperty_(KcAxis& axis) if (open) { ImGui::InputText("Text", &axis.title()); kPrivate::textContext(axis.titleContext(), false); + ImGui::DragFloat("Padding", &axis.titlePadding(), 1, 0, 20, "%.f px"); ImGuiX::cbTreePop(); } open = false; ImGuiX::cbTreePush("Tick", &axis.showTick(), &open); if (open) { - kPrivate::tickContext(axis.tickContext()); + kPrivate::tickContext(axis.tickContext(), true); ImGuiX::cbTreePop(); } open = false; ImGuiX::cbTreePush("Subtick", &axis.showSubtick(), &open); if (open) { - kPrivate::tickContext(axis.subtickContext()); + kPrivate::tickContext(axis.subtickContext(), false); ImGuiX::cbTreePop(); } @@ -499,6 +494,7 @@ void KvRdPlot::showAxisProperty_(KcAxis& axis) ImGuiX::cbTreePush("Label", &axis.showLabel(), &open); if (open) { kPrivate::textContext(axis.labelContext(), true); + ImGui::DragFloat("Padding", &axis.labelPadding(), 1, 0, 20, "%.f px"); ImGuiX::cbTreePop(); } -- Gitee From 490d19304bc5b5fd0ef8066f2864c6a65dda155d Mon Sep 17 00:00:00 2001 From: koala999 Date: Thu, 5 Jan 2023 10:34:45 +0800 Subject: [PATCH 64/68] =?UTF-8?q?refactor:=20=E7=A1=AE=E4=BF=9D=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E6=A1=86=E5=9C=A8billboard=E6=A8=A1=E5=BC=8F=E4=B8=8B?= =?UTF-8?q?=E6=97=8B=E8=BD=AC=E7=9A=84=E5=9E=82=E7=9B=B4=E5=85=B3=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/3d/KtQuaternion.h | 8 ++++---- src/plot/KcAxis.cpp | 42 +++++++++++++++++++++++++----------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/3d/KtQuaternion.h b/src/3d/KtQuaternion.h index 18580b9..0d5688c 100644 --- a/src/3d/KtQuaternion.h +++ b/src/3d/KtQuaternion.h @@ -379,8 +379,8 @@ KReal KtQuaternion::roll() { // roll = atan2(localy.z, localy.y); - KReal dx = 2 * v.x; - KReal dz = 2 * v.z; + KReal dx = 2 * x(); + KReal dz = 2 * z(); return std::atan2(dz * y() + dx * w(), 1 - dx * x() - dz * z()); } @@ -391,8 +391,8 @@ KReal KtQuaternion::yaw() { // yaw = atan2(localx.y, localx.x); - KReal dy = 2 * v.y; - KReal dz = 2 * v.z; + KReal dy = 2 * y(); + KReal dz = 2 * z(); return std::atan2(dy * x() + dz * w(), 1 - dy * y() - dz * z()); } diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index 685127e..efc8505 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -4,7 +4,7 @@ #include "KvPaint.h" #include "KtuMath.h" #include "KtLine.h" -#include "KtMatrix3.h" +#include "KtQuaternion.h" #include "layout/KeAlignment.h" #include "layout/KuLayoutUtil.h" @@ -131,16 +131,15 @@ void KcAxis::calcTickOrient_(KvPaint* paint) const // ˴orientΪ vec3 tickOrient = (tickCxt_.side == k_inside) ? insideOrient_() : outsideOrient_(); - auto vAxis = paint->localToWorldV(axisOrient_()); // ᷽ʸ - KtMatrix3 mat; - mat.fromAngleAxis(tickCxt_.pitch, vAxis); // תpitch - tickOrient = mat * tickOrient; + auto vAxis = paint->localToWorldV(axisOrient_()).normalize(); // ᷽ʸ + KtQuaternion quatPitch(tickCxt_.pitch, vAxis); // תpitch + tickOrient = quatPitch * tickOrient; - auto vPrep = tickOrient.cross(vAxis); // ̶ߺĴֱʸ - mat.fromAngleAxis(tickCxt_.yaw, vPrep.getNormalize()); - tickOrient = mat * tickOrient; + auto vPrep = tickOrient.cross(vAxis).normalize(); // ̶ߺĴֱʸ + KtQuaternion quatYaw(tickCxt_.yaw, vPrep); + tickOrient = quatYaw * tickOrient; - tickOrient_ = paint->worldToLocalV(tickOrient).getNormalize(); // 任ؾֲϵ + tickOrient_ = paint->worldToLocalV(tickOrient).normalize(); // 任ؾֲϵ if (paint->currentCoord() == KvPaint::k_coord_screen) tickOrient_.y() *= -1; // TODO: ޸õķ @@ -417,6 +416,14 @@ void KcAxis::calcTextPos_(KvPaint* paint, const std::string_view& label, const K fixTextLayout_(cxt.layout, textBox, topLeft, hDir, vDir); fixTextRotation_(cxt, anchor, topLeft, hDir, vDir); + + if (cxt.billboard && cxt.yaw) { + // vDirȷhDirĻϵ´ֱ + vec3 hDirS = paint->projectv(hDir); + vec3 vDirS = paint->projectv(vDir); + vDirS = hDirS.cross(vDirS).cross(hDirS); + vDir = paint->unprojectv(vDirS).normalize(); + } } @@ -448,16 +455,17 @@ void KcAxis::fixTextLayout_(KeTextLayout lay, const size_t& textBox, point3& top void KcAxis::fixTextRotation_(const KpTextContext& cxt, const point3& anchor, point3& topLeft, vec3& hDir, vec3& vDir) const { - auto vAxis = axisOrient_(); - KtMatrix3 mat; + if (cxt.yaw == 0) + return; + + KtQuaternion quat(cxt.yaw, vDir.cross(hDir).normalize()); - mat.fromAngleAxis(cxt.yaw, hDir.cross(vDir).normalize()); + auto yaw = quat.yaw(); - hDir = mat * hDir; - vDir = mat * vDir; - //vDir = hDir.cross(vDir).cross(hDir); - assert(KtuMath::almostEqual(hDir.dot(vDir), 0)); - topLeft = anchor + mat * (topLeft - anchor); + hDir = (quat * hDir).normalize(); + vDir = (quat * vDir).normalize(); + //assert(KtuMath::almostEqual(hDir.dot(vDir), 0)); + topLeft = anchor + quat * (topLeft - anchor); } -- Gitee From b721b888391cb2b9618f6090a8df56d26b72362b Mon Sep 17 00:00:00 2001 From: koala999 Date: Thu, 5 Jan 2023 14:42:03 +0800 Subject: [PATCH 65/68] update some matrix values --- data/matrix-7v7.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/matrix-7v7.txt b/data/matrix-7v7.txt index d4b0d3c..4653d64 100644 --- a/data/matrix-7v7.txt +++ b/data/matrix-7v7.txt @@ -1,7 +1,7 @@ -0.8 2.4 2.5 3.9 0.0 4.0 0.0 -2.4 0.0 4.0 1.0 2.7 0.0 0.0 +0.8 2.4 2.5 3.9 0.0 4.0 1.6 +2.4 0.0 4.0 1.0 2.7 0.0 3.3 1.1 2.4 0.8 4.3 1.9 4.4 0.0 -0.6 0.0 0.3 0.0 3.1 0.0 0.0 -0.7 1.7 0.6 2.6 2.2 6.2 0.0 -1.3 1.2 0.0 0.0 0.0 3.2 5.1 -0.1 2.0 0.0 1.4 0.0 1.9 6.3 \ No newline at end of file +0.6 0.0 0.3 1.0 3.1 2.0 4.8 +0.7 1.7 0.6 2.6 2.2 6.2 2.7 +1.3 1.2 2.9 4.0 0.0 3.2 5.1 +0.1 2.0 5.0 1.4 3.0 1.9 6.3 \ No newline at end of file -- Gitee From 2e4698f086a352912cad0666209328e59527b1bb Mon Sep 17 00:00:00 2001 From: koala999 Date: Thu, 5 Jan 2023 14:43:15 +0800 Subject: [PATCH 66/68] fix: a fatal error of KtPoint::operator/= --- src/3d/KtPoint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3d/KtPoint.h b/src/3d/KtPoint.h index 995c657..6364315 100644 --- a/src/3d/KtPoint.h +++ b/src/3d/KtPoint.h @@ -115,7 +115,7 @@ public: } KtPoint& operator/=(T factor) { for (unsigned i = 0; i < size(); i++) - at[i] = at(i) / factor; + at(i) = at(i) / factor; return *this; } -- Gitee From 3ca0af68c6f3e7c16b2bcf15760c0819e6eaa9ef Mon Sep 17 00:00:00 2001 From: koala999 Date: Thu, 5 Jan 2023 14:45:02 +0800 Subject: [PATCH 67/68] =?UTF-8?q?fix:=20=E9=80=8F=E8=A7=86=E6=8A=95?= =?UTF-8?q?=E5=BD=B1=E6=A8=A1=E5=BC=8F=E4=B8=8B=E7=9A=84=E7=BA=BF=E6=AE=B5?= =?UTF-8?q?=E5=92=8C=E6=96=87=E5=AD=97=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/3d/KtProjector3d.h | 7 ++++--- src/imapp/KcImOglPaint.cpp | 8 +++----- src/imapp/KcImOglPaint.h | 8 ++++---- src/imapp/KcImPaint.cpp | 8 ++++---- src/plot/KcAxis.cpp | 35 +++++++++++++++++++++-------------- src/plot/KcAxis.h | 3 +++ src/plot/KvPaint.h | 15 +++++++++------ src/render/KvRdPlot.cpp | 26 +++++++++++++------------- 8 files changed, 61 insertions(+), 49 deletions(-) diff --git a/src/3d/KtProjector3d.h b/src/3d/KtProjector3d.h index 61a7fa1..f37ff10 100644 --- a/src/3d/KtProjector3d.h +++ b/src/3d/KtProjector3d.h @@ -82,7 +82,7 @@ public: vec4 worldToClip(const vec4& pt) const { return vpMat_ * pt; } vec4 worldToNdc(const vec4& pt) const { return clipToNdc(worldToClip(pt)); } vec4 worldToViewport(const vec4& pt) const { return clipToViewport(worldToClip(pt)); } - vec4 worldToScreen(const vec4& pt) const { return (wsMat_* pt).homogenize(); } + vec4 worldToScreen(const vec4& pt) const { return wsMat_ * pt; } vec4 eyeToLocal(const vec4& pt) const { return getMvMatR_() * pt; } vec4 eyeToWorld(const vec4& pt) const { return getViewMatR_() * pt; } @@ -95,15 +95,16 @@ public: vec4 clipToWorld(const vec4& pt) const { return getVpMatR_() * pt; } vec4 clipToEye(const vec4& pt) const { return getProjMatR_() * pt; } vec4 clipToNdc(const vec4& pt) const { return vec4(pt).homogenize(); } + vec4 clipToViewport(const vec4& pt) const { return ndcToViewport(clipToNdc(pt)); } vec4 clipToScreen(const vec4& pt) const { return ndcToScreen(clipToNdc(pt)); } vec4 ndcToLocal(const vec4& pt) const { return clipToLocal(ndcToClip(pt)); } vec4 ndcToWorld(const vec4& pt) const { return clipToWorld(ndcToClip(pt)); } vec4 ndcToEye(const vec4& pt) const { return clipToEye(ndcToClip(pt)); } - vec4 ndcToClip(const vec4& pt) const { return pt; } // ֪wֵֻܷԭֵ + vec4 ndcToClip(const vec4& pt) const { return pt; } vec4 ndcToViewport(const vec4& pt) const { return nvMat_ * pt; } - vec4 ndcToScreen(const vec4& pt) const { return nsMat_ * pt; } + vec4 ndcToScreen(const vec4& pt) const { return nsMat_ * pt; } vec4 viewportToLocal(const vec4& pt) const { return ndcToLocal(viewportToNdc(pt)); } vec4 viewportToWorld(const vec4& pt) const { return ndcToWorld(viewportToNdc(pt)); } diff --git a/src/imapp/KcImOglPaint.cpp b/src/imapp/KcImOglPaint.cpp index 59569e4..bff4a8b 100644 --- a/src/imapp/KcImOglPaint.cpp +++ b/src/imapp/KcImOglPaint.cpp @@ -4,6 +4,7 @@ #include "glad.h" #include "KcVertexDeclaration.h" #include "KtLineS2d.h" +#include "KtuMath.h" #include "opengl/KcGlslProgram.h" #include "opengl/KcGlslShader.h" #include "opengl/KcGpuBuffer.h" @@ -41,10 +42,7 @@ namespace kPrivate KcImOglPaint::KcImOglPaint(camera_type& cam) : super_(cam) { - curViewport_ = -1; - curClipBox_ = -1; - depthTest_ = false; - antialiasing_ = false; + } @@ -83,7 +81,7 @@ void KcImOglPaint::endPaint() super_::endPaint(); } -#include "KtuMath.h" + KcImOglPaint::point3 KcImOglPaint::toNdc_(const point3& pt) const { switch (currentCoord()) diff --git a/src/imapp/KcImOglPaint.h b/src/imapp/KcImOglPaint.h index af33f3b..84a2868 100644 --- a/src/imapp/KcImOglPaint.h +++ b/src/imapp/KcImOglPaint.h @@ -75,10 +75,10 @@ private: std::vector clipBoxHistList_; // άռüboxб std::vector clipRectStack_; - unsigned curViewport_; // -1ʾδ - unsigned curClipBox_; - bool depthTest_; // Ȳԣ - bool antialiasing_; + unsigned curViewport_{ unsigned(-1) }; // -1ʾδ + unsigned curClipBox_{ unsigned(-1) }; + bool depthTest_{ false }; // Ȳԣ + bool antialiasing_{ false }; // [0]: viewport idx // [1]: clipRect idx diff --git a/src/imapp/KcImPaint.cpp b/src/imapp/KcImPaint.cpp index 0b83103..7afb91d 100644 --- a/src/imapp/KcImPaint.cpp +++ b/src/imapp/KcImPaint.cpp @@ -89,10 +89,10 @@ KcImPaint::point4 KcImPaint::project(const point4& pt) const switch (coords_.back()) { case k_coord_local: - return camera_.localToScreen(pt); + return camera_.localToScreen(pt).homogenize(); // NB: ͸ͶӰһ case k_coord_world: - return camera_.worldToScreen(pt); + return camera_.worldToScreen(pt).homogenize(); // NB: ͸ͶӰһ case k_coord_local_screen: return camera_.localToWorld(pt); // ִоֲ任 @@ -114,10 +114,10 @@ KcImPaint::point4 KcImPaint::unproject(const point4& pt) const switch (coords_.back()) { case k_coord_local: - return camera_.screenToLocal(pt); + return camera_.screenToLocal(pt).homogenize(); case k_coord_world: - return camera_.screenToWorld(pt); + return camera_.screenToWorld(pt).homogenize(); case k_coord_local_screen: return camera_.worldToLocal(pt); // ִоֲ任 diff --git a/src/plot/KcAxis.cpp b/src/plot/KcAxis.cpp index efc8505..0d011da 100644 --- a/src/plot/KcAxis.cpp +++ b/src/plot/KcAxis.cpp @@ -165,6 +165,13 @@ void KcAxis::calcLabelOrient_(KvPaint* paint) const } +KcAxis::float_t KcAxis::orientScale_(KvPaint* paint, const vec3& o) +{ + assert(KtuMath::almostEqual(o.length(), 1.0)); + return 1. / paint->projectv(o).length(); +} + + void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const { assert(showTick() || showLabel()); @@ -177,8 +184,8 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const // Ļ1س߶ȣ൱ٸλ - float_t tickLenPerPixel = 1. / paint->projectv(tickOrient_).length(); - float_t labelPaddingPerPixel = 1. / paint->projectv(labelOrient_).length(); + float_t tickOrientScale = orientScale_(paint, tickOrient_); + float_t labelOrientScale = orientScale_(paint, labelOrient_); if (!calcBox) paint->apply(tickCxt_); @@ -192,13 +199,13 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const auto anchor = tickPos(ticks[i]); if (showTick()) - drawTick_(paint, anchor, tickCxt_.length * tickLenPerPixel, calcBox); + drawTick_(paint, anchor, tickCxt_.length * tickOrientScale, calcBox); if (showLabel()) { - labelAnchors[i] = anchor + labelOrient_ * labelPadding_ * labelPaddingPerPixel; + labelAnchors[i] = anchor + labelOrient_ * labelPadding_ * labelOrientScale; if (sameSide && showTick()) - labelAnchors[i] += tickOrient_ * tickCxt_.length * tickLenPerPixel; + labelAnchors[i] += tickOrient_ * tickCxt_.length * tickOrientScale; } } @@ -220,7 +227,7 @@ void KcAxis::drawTicks_(KvPaint* paint, bool calcBox) const if (showSubtick() && !subticks.empty()) { paint->apply(subtickCxt_); - double subtickLen = subtickCxt_.length * tickLenPerPixel; + double subtickLen = subtickCxt_.length * tickOrientScale; for (unsigned i = 0; i < subticks.size(); i++) drawTick_(paint, tickPos(subticks[i]), subtickLen, calcBox); @@ -387,11 +394,11 @@ void KcAxis::calcTextPos_(KvPaint* paint, const std::string_view& label, const K auto textBox = paint->textSize(label.data()); if (cxt.layout == k_vert_left || cxt.layout == k_vert_right) std::swap(textBox.x(), textBox.y()); - + if (cxt.billboard) { // ģʽʼ˳+xչ - hDir = paint->unprojectv(vec3::unitX()).getNormalize(); - vDir = paint->unprojectv(vec3::unitY()).getNormalize(); + hDir = paint->unprojectv(vec3::unitX()).normalize(); + vDir = paint->unprojectv(vec3::unitY()).normalize(); auto align = labelAlignment_(paint); auto anchorInScreen = paint->projectp(anchor); @@ -408,11 +415,11 @@ void KcAxis::calcTextPos_(KvPaint* paint, const std::string_view& label, const K if (zDir.z() < 0) hDir *= -1; // hDirȷάռĿɶ - topLeft = anchor - hDir * (textBox.x() / 2) / paint->projectv(hDir).length(); + topLeft = anchor - hDir * (textBox.x() / 2) * orientScale_(paint, hDir); } // fixTextLayout_ҪtextBoxΪߴ磬˴б任 - textBox /= point2d(paint->projectv(hDir).length(), paint->projectv(vDir).length()); + textBox *= point2(orientScale_(paint, hDir), orientScale_(paint, vDir)); fixTextLayout_(cxt.layout, textBox, topLeft, hDir, vDir); fixTextRotation_(cxt, anchor, topLeft, hDir, vDir); @@ -482,8 +489,8 @@ void KcAxis::drawText_(KvPaint* paint, const std::string_view& label, const KpTe } //else { auto sz = paint->textSize(label.data()); - auto h = hDir * sz.x() / paint->projectv(hDir).length(); - auto v = vDir * sz.y() / paint->projectv(vDir).length(); + auto h = hDir * sz.x() * orientScale_(paint, hDir); + auto v = vDir * sz.y() * orientScale_(paint, vDir); box_.merge({ topLeft, topLeft + h + v }); //} } @@ -504,7 +511,7 @@ void KcAxis::calcTitleAnchor_(KvPaint* paint) const titleAnchor_ = center + orient * shift; // padding - titleAnchor_ += orient * titlePadding_ / paint->projectv(orient).length(); + titleAnchor_ += orient * titlePadding_ * orientScale_(paint, orient); // paint->drawBox(box_.lower(), box_.upper()); // for debug } diff --git a/src/plot/KcAxis.h b/src/plot/KcAxis.h index c21d769..f9dd5ff 100644 --- a/src/plot/KcAxis.h +++ b/src/plot/KcAxis.h @@ -209,6 +209,9 @@ private: vec3 insideOrient_() const; vec3 axisOrient_() const; + // 귽oϣ1Ļλ1أ൱ڶ絥λ + static float_t orientScale_(KvPaint*, const vec3& o); + void draw_(KvPaint*, bool calcBox) const; void drawTicks_(KvPaint*, bool calcBox) const; // п̶ void drawTick_(KvPaint*, const point3& anchor, double length, bool calcBox) const; // Ƶ̶ߣ̶븱̶ diff --git a/src/plot/KvPaint.h b/src/plot/KvPaint.h index 92ed31e..c4182ae 100644 --- a/src/plot/KvPaint.h +++ b/src/plot/KvPaint.h @@ -137,11 +137,13 @@ public: // ͶӰ point3 projectp(const point3& pt) const { auto r = project(point4(pt.x(), pt.y(), pt.z(), 1)); + assert(r.w() == 1); return { r.x(), r.y(), r.z() }; } point3 unprojectp(const point3& pt) const { auto r = unproject(point4(pt.x(), pt.y(), pt.z(), 1)); + assert(r.w() == 1); // NB: ͸ͶӰģʽ£Խһ return { r.x(), r.y(), r.z() }; } @@ -162,18 +164,19 @@ public: // ʸͶӰ point3 projectv(const point3& v) const { - auto r = project(point4(v.x(), v.y(), v.z(), 0)); - return { r.x(), r.y(), r.z() }; + //auto r = project(point4(v.x(), v.y(), v.z(), 0)); + //return { r.x(), r.y(), r.z() }; + return projectp(v) - projectp(point3(0)); // TODO: ͸ͶӰģʽ£ֱʹ } point3 unprojectv(const point3& pt) const { - auto r = unproject(point4(pt.x(), pt.y(), pt.z(), 0)); - return { r.x(), r.y(), r.z() }; + //auto r = unproject(point4(pt.x(), pt.y(), pt.z(), 0)); + //return { r.x(), r.y(), r.z() }; + return unprojectp(pt) - unprojectp(point3(0)); // TODO: ͸ͶӰģʽ£ֱʹ } point3 unprojectv(const point2& pt) const { - auto r = unproject(point4(pt.x(), pt.y(), 0, 0)); - return { r.x(), r.y(), r.z() }; + return unprojectv(point3(pt.x(), pt.y(), 0)); } point3 localToWorldV(const point3& v) const { diff --git a/src/render/KvRdPlot.cpp b/src/render/KvRdPlot.cpp index d05fb04..5221b98 100644 --- a/src/render/KvRdPlot.cpp +++ b/src/render/KvRdPlot.cpp @@ -368,13 +368,15 @@ void KvRdPlot::showCoordProperty_() namespace kPrivate { - void tickContext(KcAxis::KpTickContext& cxt, bool showSide) + void tickContext(KcAxis::KpTickContext& cxt, bool subtick) { ImGuiX::pen(&cxt, false); // no style. tickʼʹsolid ImGui::PushID(&cxt); - if (showSide) { + ImGui::SliderFloat("Length", &cxt.length, 0, 25, "%.1f px"); + + if (!subtick) { const static char* side[] = { "inside", "outside", "bothside" }; if (ImGui::BeginCombo("Side", side[cxt.side])) { for (unsigned i = 0; i < std::size(side); i++) @@ -382,17 +384,15 @@ namespace kPrivate cxt.side = KcAxis::KeTickSide(i); ImGui::EndCombo(); } - } - ImGui::SliderFloat("Length", &cxt.length, 0, 25, "%.1f px"); - - float yaw = KtuMath::rad2Deg(cxt.yaw); - if (ImGui::SliderFloat("Yaw", &yaw, -90, 90, "%.f deg")) - cxt.yaw = KtuMath::deg2Rad(yaw); + float yaw = KtuMath::rad2Deg(cxt.yaw); + if (ImGui::SliderFloat("Yaw", &yaw, -90, 90, "%.f deg")) + cxt.yaw = KtuMath::deg2Rad(yaw); - float pitch = KtuMath::rad2Deg(cxt.pitch); - if (ImGui::SliderFloat("Pitch", &pitch, -90, 90, "%.f deg")) - cxt.pitch = KtuMath::deg2Rad(pitch); + float pitch = KtuMath::rad2Deg(cxt.pitch); + if (ImGui::SliderFloat("Pitch", &pitch, -90, 90, "%.f deg")) + cxt.pitch = KtuMath::deg2Rad(pitch); + } ImGui::PopID(); } @@ -479,14 +479,14 @@ void KvRdPlot::showAxisProperty_(KcAxis& axis) open = false; ImGuiX::cbTreePush("Tick", &axis.showTick(), &open); if (open) { - kPrivate::tickContext(axis.tickContext(), true); + kPrivate::tickContext(axis.tickContext(), false); ImGuiX::cbTreePop(); } open = false; ImGuiX::cbTreePush("Subtick", &axis.showSubtick(), &open); if (open) { - kPrivate::tickContext(axis.subtickContext(), false); + kPrivate::tickContext(axis.subtickContext(), true); ImGuiX::cbTreePop(); } -- Gitee From 34f4fb19f643b0c8e85f5ac984c84651134ac5a5 Mon Sep 17 00:00:00 2001 From: koala999 Date: Thu, 5 Jan 2023 14:49:12 +0800 Subject: [PATCH 68/68] update TODO.md --- TODO.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TODO.md b/TODO.md index 8c127d2..e68d119 100644 --- a/TODO.md +++ b/TODO.md @@ -10,8 +10,8 @@ 5. plot3d的legend布局 --> ok 6. colorbar --> ok 7. axis的反向设置 --> ok -8. 中文字体显示 --> 暂时使用imgui的中文字体支持 -9. opengl加速 +8. 中文字体显示 --> ok(暂时使用imgui的中文字体支持 ) +9. opengl加速 --> ok 10. 导出图片 11. 导出矢量图 12. auto-fold layout @@ -32,5 +32,5 @@ 2. 三维坐标系下,虚线的绘制(ImGui)在旋转到特定方向时会出现错位 --> 使用opengl绘制后,该问题没再出现,估计由于计算误差引起 3. 加载大的text数据文件很慢 4. 坐标轴刻度旋转时出现突变 -5. 3d透视投影模式下,坐标轴的刻度线和文字全部消失 --> 须同步修改opengl的投影方式 -6. plot3d在交换坐标轴后,鼠标操控坐标系姿态出现问题 \ No newline at end of file +5. 3d透视投影模式下,坐标轴的刻度线和文字全部消失 --> ok(一是矢量投影算法问题,二是逆变换未作归一化) +6. plot3d在交换坐标轴后,或者在透视投影模式下,鼠标操控坐标系姿态出现问题 \ No newline at end of file -- Gitee