| 1 #include "vertexprogram.h" |
|
| 2 #include "document.h" |
|
| 3 |
|
| 4 static const char vertexShaderSource[] = R"( |
|
| 5 #version 330 core |
|
| 6 const int FRAGSTYLE_Normal = 0; |
|
| 7 const int FRAGSTYLE_Id = 1; |
|
| 8 layout (location = 0) in vec3 in_position; |
|
| 9 layout (location = 1) in vec3 in_color; |
|
| 10 uniform mat4 view; |
|
| 11 uniform mat4 projection; |
|
| 12 uniform mat4 model; |
|
| 13 smooth out vec3 ex_color; |
|
| 14 |
|
| 15 void main() |
|
| 16 { |
|
| 17 gl_Position = projection * view * model * vec4(in_position, 1.0); |
|
| 18 ex_color = in_color; |
|
| 19 } |
|
| 20 )"; |
|
| 21 |
|
| 22 static const char fragmentShaderSource[] = R"( |
|
| 23 #version 330 core |
|
| 24 |
|
| 25 out vec4 color; |
|
| 26 smooth in vec3 ex_color; |
|
| 27 |
|
| 28 void main(void) |
|
| 29 { |
|
| 30 color = vec4(ex_color, 1); |
|
| 31 } |
|
| 32 )"; |
|
| 33 |
|
| 34 std::vector<glm::vec3> sphere(const int d2) |
|
| 35 { |
|
| 36 std::vector<glm::vec3> result; |
|
| 37 result.reserve(12 * d2 * d2); |
|
| 38 for (int i = 0; i < d2; ++i) |
|
| 39 { |
|
| 40 const float alpha = i * pi<> / d2; |
|
| 41 const float alpha_2 = (i + 1) * pi<> / d2; |
|
| 42 for (int j = -d2; j < d2; ++j) |
|
| 43 { |
|
| 44 const float beta = j * pi<> / d2; |
|
| 45 const float beta_2 = (j + 1) * pi<> / d2; |
|
| 46 const float x1 = cos(beta) * sin(alpha); |
|
| 47 const float x2 = cos(beta) * sin(alpha_2); |
|
| 48 const float x3 = cos(beta_2) * sin(alpha_2); |
|
| 49 const float x4 = cos(beta_2) * sin(alpha); |
|
| 50 const float z1 = sin(beta) * sin(alpha); |
|
| 51 const float z2 = sin(beta) * sin(alpha_2); |
|
| 52 const float z3 = sin(beta_2) * sin(alpha_2); |
|
| 53 const float z4 = sin(beta_2) * sin(alpha); |
|
| 54 const float y1 = cos(alpha); |
|
| 55 const float y2 = cos(alpha_2); |
|
| 56 result.push_back({x1, y1, z1}); |
|
| 57 result.push_back({x2, y2, z2}); |
|
| 58 result.push_back({x3, y2, z3}); |
|
| 59 result.push_back({x1, y1, z1}); |
|
| 60 result.push_back({x3, y2, z3}); |
|
| 61 result.push_back({x4, y1, z4}); |
|
| 62 } |
|
| 63 } |
|
| 64 return result; |
|
| 65 } |
|
| 66 |
|
| 67 VertexProgram::VertexProgram(QObject *parent) : |
|
| 68 AbstractBasicShaderProgram{parent} |
|
| 69 { |
|
| 70 } |
|
| 71 |
|
| 72 const char *VertexProgram::vertexShaderSource() const |
|
| 73 { |
|
| 74 return ::vertexShaderSource; |
|
| 75 } |
|
| 76 |
|
| 77 const char *VertexProgram::fragmentShaderSource() const |
|
| 78 { |
|
| 79 return ::fragmentShaderSource; |
|
| 80 } |
|
| 81 |
|
| 82 const void *VertexProgram::vertexData() const |
|
| 83 { |
|
| 84 return this->data.data(); |
|
| 85 } |
|
| 86 |
|
| 87 int VertexProgram::vertexSize() const |
|
| 88 { |
|
| 89 return sizeof(Vertex); |
|
| 90 } |
|
| 91 |
|
| 92 int VertexProgram::vertexCount() const |
|
| 93 { |
|
| 94 return this->data.size(); |
|
| 95 } |
|
| 96 |
|
| 97 void VertexProgram::setupVertexArrays() |
|
| 98 { |
|
| 99 for (int i : {0, 1}) |
|
| 100 { |
|
| 101 this->program->enableAttributeArray(i); |
|
| 102 } |
|
| 103 const int stride = this->vertexSize(); |
|
| 104 this->program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride); |
|
| 105 this->program->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, color), 3, stride); |
|
| 106 } |
|
| 107 |
|
| 108 GLenum VertexProgram::drawMode() const |
|
| 109 { |
|
| 110 return GL_TRIANGLES; |
|
| 111 } |
|
| 112 |
|
| 113 QOpenGLBuffer::UsagePattern VertexProgram::usagePattern() const |
|
| 114 { |
|
| 115 return QOpenGLBuffer::DynamicDraw; |
|
| 116 } |
|
| 117 |
|
| 118 void VertexProgram::setFragmentStyle(const FragmentStyle newFragmentStyle) |
|
| 119 { |
|
| 120 this->fragmentStyle = newFragmentStyle; |
|
| 121 } |
|
| 122 |
|
| 123 void VertexProgram::build(const VertexMap* vertexMap) |
|
| 124 { |
|
| 125 constexpr glm::vec3 color = {0.0, 1.0, 1.0}; |
|
| 126 this->data.clear(); |
|
| 127 const std::vector<glm::vec3> sphere = ::sphere(8 / 2); |
|
| 128 vertexMap->apply([&](const glm::vec3&, const VertexMap::VertexInfo& info) |
|
| 129 { |
|
| 130 reserveMore(this->data, sphere.size()); |
|
| 131 for (const glm::vec3& point : sphere) |
|
| 132 { |
|
| 133 const glm::vec3 transformed = glm::scale(info.transform, glm::vec3{0.5, 0.5, 0.5}) * glm::vec4{point, 1}; |
|
| 134 this->data.push_back({transformed, color}); |
|
| 135 } |
|
| 136 }); |
|
| 137 this->buffer.bind(); |
|
| 138 this->buffer.allocate(this->vertexData(), this->vertexCount() * this->vertexSize()); |
|
| 139 this->buffer.release(); |
|
| 140 } |
|