Wed, 25 May 2022 20:36:34 +0300
Fix pick() picking from weird places on the screen with high DPI scaling
glReadPixels reads data from the frame buffer, which contains data after
high DPI scaling, so any reads to that need to take this scaling into account
118 | 1 | #include "vertexprogram.h" |
2 | #include "document.h" | |
3 | ||
4 | static const char vertexShaderSource[] = R"( | |
5 | #version 330 core | |
119 | 6 | const int FRAGSTYLE_Normal = 0; |
7 | const int FRAGSTYLE_Id = 1; | |
118 | 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 | ||
172
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
34 | std::vector<glm::vec3> sphere(const int d2) |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
35 | { |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
36 | std::vector<glm::vec3> result; |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
37 | result.reserve(12 * d2 * d2); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
38 | for (int i = 0; i < d2; ++i) |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
39 | { |
196 | 40 | const float alpha = i * pi<> / d2; |
41 | const float alpha_2 = (i + 1) * pi<> / d2; | |
172
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
42 | for (int j = -d2; j < d2; ++j) |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
43 | { |
196 | 44 | const float beta = j * pi<> / d2; |
45 | const float beta_2 = (j + 1) * pi<> / d2; | |
172
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
46 | const float x1 = cos(beta) * sin(alpha); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
47 | const float x2 = cos(beta) * sin(alpha_2); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
48 | const float x3 = cos(beta_2) * sin(alpha_2); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
49 | const float x4 = cos(beta_2) * sin(alpha); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
50 | const float z1 = sin(beta) * sin(alpha); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
51 | const float z2 = sin(beta) * sin(alpha_2); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
52 | const float z3 = sin(beta_2) * sin(alpha_2); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
53 | const float z4 = sin(beta_2) * sin(alpha); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
54 | const float y1 = cos(alpha); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
55 | const float y2 = cos(alpha_2); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
56 | result.push_back({x1, y1, z1}); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
57 | result.push_back({x2, y2, z2}); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
58 | result.push_back({x3, y2, z3}); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
59 | result.push_back({x1, y1, z1}); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
60 | result.push_back({x3, y2, z3}); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
61 | result.push_back({x4, y1, z4}); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
62 | } |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
63 | } |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
64 | return result; |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
65 | } |
118 | 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 | { | |
119 | 110 | return GL_TRIANGLES; |
118 | 111 | } |
112 | ||
113 | QOpenGLBuffer::UsagePattern VertexProgram::usagePattern() const | |
114 | { | |
115 | return QOpenGLBuffer::DynamicDraw; | |
116 | } | |
117 | ||
119 | 118 | void VertexProgram::setFragmentStyle(const FragmentStyle newFragmentStyle) |
119 | { | |
120 | this->fragmentStyle = newFragmentStyle; | |
121 | } | |
122 | ||
118 | 123 | void VertexProgram::build(const Document *document) |
124 | { | |
125 | constexpr glm::vec3 color = {0.0, 1.0, 1.0}; | |
126 | this->data.clear(); | |
172
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
127 | const std::vector<glm::vec3> sphere = ::sphere(8 / 2); |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
128 | document->applyToVertices([&](const glm::vec3&, const VertexMap::VertexInfo& info) |
118 | 129 | { |
172
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
130 | reserveMore(this->data, sphere.size()); |
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
131 | for (const glm::vec3& point : sphere) |
119 | 132 | { |
172
50f055543ff6
Render vertices as spheres
Teemu Piippo <teemu@hecknology.net>
parents:
120
diff
changeset
|
133 | const glm::vec3 transformed = glm::scale(info.transform, glm::vec3{0.5, 0.5, 0.5}) * glm::vec4{point, 1}; |
120
8c9fff699241
rework rendering of vertices
Teemu Piippo <teemu@hecknology.net>
parents:
119
diff
changeset
|
134 | this->data.push_back({transformed, color}); |
119 | 135 | } |
118 | 136 | }); |
137 | this->buffer.bind(); | |
138 | this->buffer.allocate(this->vertexData(), this->vertexCount() * this->vertexSize()); | |
139 | this->buffer.release(); | |
140 | } |