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 } |
|