summaryrefslogtreecommitdiffstats
path: root/Project/HMPlane.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Project/HMPlane.cpp')
-rw-r--r--Project/HMPlane.cpp380
1 files changed, 380 insertions, 0 deletions
diff --git a/Project/HMPlane.cpp b/Project/HMPlane.cpp
new file mode 100644
index 0000000..b5032b1
--- /dev/null
+++ b/Project/HMPlane.cpp
@@ -0,0 +1,380 @@
+#include "HMPlane.h"
+
+#include "Renderer.h"
+
+#include "VertexBuffer.h"
+#include "VertexBufferLayout.h"
+#include "IndexBuffer.h"
+#include "VertexArray.h"
+#include "Shader.h"
+
+#include "OpenGLText.h"
+
+#include <wx/msgdlg.h>
+
+HMPlane::HMPlane(Shader* shader, Shader* labelShader, const float& width, const float& height, const float limits[2])
+ : m_width(width), m_height(height), m_shader(shader), m_labelShader(labelShader)
+{
+ // Fill mesh coords
+ for (auto accHeight = 0; accHeight <= m_height + m_meshSize; accHeight += m_meshSize) {
+ std::vector<BufferMeshCoords*> line;
+ for (auto accWidth = 0; accWidth <= m_width + m_meshSize; accWidth += m_meshSize) {
+ auto* bmc = new BufferMeshCoords;
+ bmc->x = accWidth;
+ bmc->y = accHeight;
+ bmc->z = 0.0f;
+ line.emplace_back(bmc);
+
+ if (accHeight < 0.1f) m_meshTickX++;
+ }
+ m_meshTickY++;
+ m_coords.emplace_back(line);
+ }
+
+ m_limits[0] = limits[0];
+ m_limits[1] = limits[1];
+
+ FillCoordsBuffer();
+ FillIndexBuffer();
+ BindOpenGLBuffers();
+
+ CreateLabel();
+}
+
+HMPlane::~HMPlane()
+{
+ delete m_ib;
+ delete m_vb;
+ delete m_layout;
+ delete m_va;
+
+ delete m_ibL;
+ delete m_vbL;
+ delete m_layoutL;
+ delete m_vaL;
+
+ for (auto glText : m_glTexts) {
+ delete glText;
+ }
+ m_glTexts.clear();
+
+ for (const auto& line : m_coords) {
+ for (auto* bmv : line) {
+ delete bmv;
+ }
+ }
+ m_coords.clear();
+}
+
+void HMPlane::Draw(const Renderer& renderer, const glm::mat4& projectionViewMatrix) const
+{
+ //const glm::mat4 mvp = projectionViewMatrix * glm::translate(glm::mat4(1.0f), glm::vec3(m_width / 2.0f, m_height / 2.0f, 0.0f));
+ const glm::mat4 mvp = projectionViewMatrix;
+
+ m_shader->Bind();
+ //m_shader->SetUniform1f("u_scale", m_scale);
+ m_shader->SetUniformMatrix4fv("u_mvpMatrix", mvp);
+
+ m_va->UpdateBuffer(*m_vb, m_bufferCoords.data(), m_bufferCoords.size() * sizeof(float));
+
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ renderer.Draw(*m_va, *m_ib, *m_shader);
+
+ // Unbind
+ m_va->Unbind();
+ m_vb->Unbind();
+ m_ib->Unbind();
+
+ m_shader->Unbind();
+}
+
+void HMPlane::DrawLabel(const Renderer& renderer, const glm::mat4& projectionViewMatrix, const float& x, const float& y) const
+{
+ const glm::mat4 mvp = projectionViewMatrix * glm::translate(glm::mat4(1.0f), glm::vec3(x, y, 0.0f));
+ //const glm::mat4 mvp = projectionViewMatrix;
+
+ m_labelShader->Bind();
+ //m_shader->SetUniform1f("u_scale", m_scale);
+ m_labelShader->SetUniformMatrix4fv("u_mvpMatrix", mvp);
+ m_labelShader->SetUniform4f("u_offset", x, y, m_width, m_height);
+
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ renderer.Draw(*m_vaL, *m_ibL, *m_labelShader);
+
+ // Unbind
+ m_vaL->Unbind();
+ m_vbL->Unbind();
+ m_ibL->Unbind();
+
+ m_labelShader->Unbind();
+
+ glColor4d(0.0, 0.0, 0.0, 1.0);
+ m_glTexts[0]->Draw(wxPoint2DDouble(x + 35.0 + m_glTexts[0]->GetWidth() / 2.0, y));
+ m_glTexts[1]->Draw(wxPoint2DDouble(x + 35.0 + m_glTexts[1]->GetWidth() / 2.0, y + 150.0));
+ m_glTexts[2]->Draw(wxPoint2DDouble(x + 35.0 + m_glTexts[2]->GetWidth() / 2.0, y + 300.0));
+}
+
+void HMPlane::SetLabelLimits(const float& min, const float& max)
+{
+ m_limits[0] = max;
+ m_limits[1] = min;
+
+ m_glTexts[0]->SetText(wxString::Format("%.2f p.u.", m_limits[0]));
+ m_glTexts[1]->SetText(wxString::Format("%.2f p.u.", (m_limits[0] + m_limits[1]) / 2.0f));
+ m_glTexts[2]->SetText(wxString::Format("%.2f p.u.", m_limits[1]));
+}
+
+void HMPlane::SetRectSlope(const wxRect2DDouble& rect, const float& angle, const float& depth)
+{
+ for (const auto& line : m_coords) {
+ for (auto* coord : line) {
+ wxPoint2DDouble pt(coord->x, coord->y);
+ if (std::abs(angle) > 0.01) {
+
+ wxPoint2DDouble rotPt;
+ rotPt.m_x = cos(angle) * (pt.m_x - rect.GetCentre().m_x) + sin(angle) * (pt.m_y - rect.GetCentre().m_y) + rect.GetCentre().m_x;
+ rotPt.m_y = sin(angle) * (pt.m_x - rect.GetCentre().m_x) - cos(angle) * (pt.m_y - rect.GetCentre().m_y) + rect.GetCentre().m_y;
+
+ pt = rotPt;
+ }
+ if (rect.Contains(pt)) {
+ coord->z += depth;
+ if (coord->z > 1.0f) coord->z = 1.0f;
+ if (coord->z < -1.0f) coord->z = -1.0f;
+ }
+
+ }
+ }
+ m_isClear = false;
+ //FillCoordsBuffer();
+ //SmoothPlane();
+}
+
+void HMPlane::Resize(const float& width, const float& height)
+{
+ //Clear();
+ m_width = width;
+ m_height = height;
+ m_meshTickX = 0;
+ m_meshTickY = 0;
+
+ for (const auto& line : m_coords) {
+ for (auto* bmv : line) {
+ delete bmv;
+ }
+ }
+ m_coords.clear();
+
+ // Fill mesh coords
+ for (auto accHeight = 0; accHeight < m_height + m_meshSize; accHeight += m_meshSize) {
+ std::vector<BufferMeshCoords*> line;
+ for (auto accWidth = 0; accWidth < m_width + m_meshSize; accWidth += m_meshSize) {
+ auto* bmc = new BufferMeshCoords;
+ bmc->x = accWidth;
+ bmc->y = accHeight;
+ bmc->z = 0.0f;
+ line.emplace_back(bmc);
+
+ if (accHeight < 0.1f) m_meshTickX++;
+ }
+ m_meshTickY++;
+ m_coords.emplace_back(line);
+ }
+ FillCoordsBuffer();
+ FillIndexBuffer();
+
+ BindOpenGLBuffers();
+
+ //m_va->Bind();
+ //m_vb->Bind();
+ //
+ //delete m_ib;
+ //m_ib = new IndexBuffer(m_indexBuffer.data(), m_indexBuffer.size());
+ //m_ib->Unbind();
+ m_isClear = false;
+}
+
+void HMPlane::SmoothPlane(const unsigned int& iterations)
+{
+ const int maxTickX = static_cast<int>(m_meshTickX);
+ const int maxTickY = static_cast<int>(m_meshTickY);
+
+ std::vector< std::vector<BufferMeshCoords> > tmpCoords;
+ for (const auto& line : m_coords) {
+ std::vector<BufferMeshCoords> tmpCoordsLine;
+ for (auto* bmv : line) {
+ tmpCoordsLine.push_back(*bmv);
+ }
+ tmpCoords.push_back(tmpCoordsLine);
+ }
+
+ //Mean Blur
+ //for (int i = 0; i < maxTick; ++i) {
+ // for (int j = 0; j < maxTick; ++j) {
+ // // Get the 8 neighbors and smooth z
+ // float mid = 0.0f;
+ // float div = 0.0f;
+ //
+ // for (int ii = i - 1; ii <= i + 1; ++ii) {
+ // for (int jj = j - 1; jj <= j + 1; ++jj) {
+ //
+ // if (ii >= 0 && ii < maxTick && jj >= 0 && jj < maxTick) {
+ // mid += tmpCoords[ii][jj].z;
+ // div += 1.0;
+ // }
+ // }
+ // }
+ // m_coords[i][j]->z = mid / div;
+ // }
+ //}
+
+ // Gaussian Blur
+ float gaussianKernel[5][5] =
+ {
+ {1.0f / 256.0f, 4.0f / 256.0f, 6 / 256.0f, 4.0f / 256, 1.0f / 256.0f},
+ {4.0f / 256.0f, 16.0f / 256.0f, 24 / 256.0f, 16.0f / 256, 4.0f / 256.0f},
+ {6.0f / 256.0f, 24.0f / 256.0f, 36 / 256.0f, 24.0f / 256, 6.0f / 256.0f},
+ {4.0f / 256.0f, 16.0f / 256.0f, 24 / 256.0f, 16.0f / 256, 4.0f / 256.0f},
+ {1.0f / 256.0f, 4.0f / 256.0f, 6 / 256.0f, 4.0f / 256, 1.0f / 256.0f}
+ };
+
+ for (unsigned int it = 0; it < iterations; ++it) {
+ for (int i = 0; i < m_meshTickY; ++i) {
+ for (int j = 0; j < m_meshTickX; ++j) {
+ // Get the 24 neighbors and smooth z
+ float value = 0.0f;
+
+ for (int ii = i - 2; ii <= i + 2; ++ii) {
+ for (int jj = j - 2; jj <= j + 2; ++jj) {
+
+ if (ii >= 0 && ii < m_meshTickY && jj >= 0 && jj < m_meshTickX) {
+ value += tmpCoords[ii][jj].z * gaussianKernel[ii - i + 2][jj - j + 2];
+ }
+ }
+ }
+ m_coords[i][j]->z = value;
+ }
+ }
+ if (it < iterations - 1) {
+ for (int i = 0; i < m_meshTickY; ++i) {
+ for (int j = 0; j < m_meshTickX; ++j) {
+ tmpCoords[i][j].z = m_coords[i][j]->z;
+ }
+ }
+ }
+ }
+
+ FillCoordsBuffer();
+ m_isClear = false;
+}
+
+void HMPlane::Clear()
+{
+ if (!m_isClear) {
+ for (const auto& line : m_coords) {
+ for (auto* bmv : line) {
+ bmv->z = 0.0f;
+ }
+ }
+ FillCoordsBuffer();
+ m_isClear = true;
+ }
+}
+
+void HMPlane::FillCoordsBuffer()
+{
+ m_bufferCoords.clear();
+
+ for (const auto& line : m_coords) {
+ for (auto* bmv : line) {
+ m_bufferCoords.push_back(bmv->x);
+ m_bufferCoords.push_back(bmv->y);
+ m_bufferCoords.push_back(bmv->z);
+ }
+ }
+}
+
+void HMPlane::FillIndexBuffer()
+{
+ m_indexBuffer.clear();
+ for (auto i = 0; i < m_meshTickY - 1; ++i) {
+ for (auto j = 0; j < m_meshTickX - 1; ++j) {
+ m_indexBuffer.push_back(i * m_meshTickX + j);
+ m_indexBuffer.push_back(i * m_meshTickX + j + 1);
+ m_indexBuffer.push_back((i + 1) * m_meshTickX + j + 1);
+ m_indexBuffer.push_back(i * m_meshTickX + j);
+ m_indexBuffer.push_back((i + 1) * m_meshTickX + j);
+ m_indexBuffer.push_back((i + 1) * m_meshTickX + j + 1);
+ }
+ }
+}
+
+void HMPlane::BindOpenGLBuffers()
+{
+ delete m_va;
+ delete m_vb;
+ delete m_ib;
+ // Generate vertex array (this will bind vertex buffer with its layout)
+ m_va = new VertexArray();
+
+ // Generate vertex buffer
+ m_vb = new VertexBuffer(m_bufferCoords.data(), m_bufferCoords.size() * sizeof(float), GL_DYNAMIC_DRAW);
+
+ m_layout = new VertexBufferLayout();
+ m_layout->Push<float>(3); // 3 = each triplet from array set the coords -> [x1, y1, z1, x2, y2, z2, ...]
+ m_va->AddBuffer(*m_vb, *m_layout); // Add buffer and bind vertex array
+
+ // Set index buffer
+ m_ib = new IndexBuffer(m_indexBuffer.data(), m_indexBuffer.size());
+
+ // Unbind
+ m_va->Unbind();
+ m_vb->Unbind();
+ m_ib->Unbind();
+}
+
+void HMPlane::CreateLabel()
+{
+ float vertexBufferLabel[4 * 3] =
+ {
+ 0.0f, 0.0f, 1.0f,
+ 30.0f, 0.0f, 1.0f,
+ 0.0f, 300.0f, -1.0f,
+ 30.0f, 300.0f, -1.0f
+ };
+ std::copy(vertexBufferLabel, vertexBufferLabel + 3 * 4, m_vertexBufferLabel);
+
+ unsigned int indexBufferLabel[6] =
+ {
+ 0, 1, 2,
+ 1, 2, 3
+ };
+ std::copy(indexBufferLabel, indexBufferLabel + 6, m_indexBufferLabel);
+
+ delete m_vaL;
+ delete m_vbL;
+ delete m_ibL;
+ // Generate vertex array (this will bind vertex buffer with its layout)
+ m_vaL = new VertexArray();
+
+ // Generate vertex buffer
+ m_vbL = new VertexBuffer(m_vertexBufferLabel, 4 * 3 * sizeof(float), GL_STATIC_DRAW);
+
+ m_layoutL = new VertexBufferLayout();
+ m_layoutL->Push<float>(3); // 3 = each triplet from array set the coords -> [x1, y1, z1, x2, y2, z2, ...]
+ m_vaL->AddBuffer(*m_vbL, *m_layoutL); // Add buffer and bind vertex array
+
+ // Set index buffer
+ m_ibL = new IndexBuffer(m_indexBufferLabel, 6);
+
+ // Unbind
+ m_vaL->Unbind();
+ m_vbL->Unbind();
+ m_ibL->Unbind();
+
+ m_glTexts.emplace_back(new OpenGLText(wxString::Format("%.2f p.u.", m_limits[0])));
+ m_glTexts.emplace_back(new OpenGLText(wxString::Format("%.2f p.u.", (m_limits[0] + m_limits[1]) / 2.0)));
+ m_glTexts.emplace_back(new OpenGLText(wxString::Format("%.2f p.u.", m_limits[1])));
+}