16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 */ |
17 */ |
18 |
18 |
19 #include "src/gl/basicshaderprogram.h" |
19 #include "src/gl/basicshaderprogram.h" |
20 |
20 |
21 BasicShader::BasicShader() : |
21 void gl::initialize_basic_shader( |
22 buffer{QOpenGLBuffer::VertexBuffer}, |
22 gl::basic_shader* shader, |
23 vertexShader{QOpenGLShader::Vertex}, |
|
24 fragmentShader{QOpenGLShader::Fragment} |
|
25 { |
|
26 } |
|
27 |
|
28 BasicShader::~BasicShader() |
|
29 { |
|
30 if (this->isInitialized) { |
|
31 this->teardown(); |
|
32 } |
|
33 } |
|
34 |
|
35 void BasicShader::initialize( |
|
36 const char* vertexShaderSource, |
23 const char* vertexShaderSource, |
37 const char* fragmentShaderSource, |
24 const char* fragmentShaderSource, |
38 QOpenGLBuffer::UsagePattern usagePattern, |
25 QOpenGLBuffer::UsagePattern usagePattern, |
39 const std::vector<GLAttributeSpec>& attributeSpecs) |
26 const std::vector<GLAttributeSpec>& attributeSpecs) |
40 { |
27 { |
41 if (not this->isInitialized) |
28 shader->program = std::make_unique<gl::ShaderProgram>(); |
42 { |
29 gl::buildShaders(shader->program.get(), vertexShaderSource, fragmentShaderSource); |
43 this->isInitialized = true; |
30 shader->program->bind(); |
44 this->program = std::make_unique<gl::ShaderProgram>(); |
31 shader->buffer.create(); |
45 gl::buildShaders(this->program.get(), vertexShaderSource, fragmentShaderSource); |
32 shader->buffer.bind(); |
46 this->program->bind(); |
33 shader->buffer.setUsagePattern(usagePattern); |
47 this->buffer.create(); |
34 shader->vertexArrayObject.create(); |
48 this->buffer.bind(); |
35 shader->vertexArrayObject.bind(); |
49 this->buffer.setUsagePattern(usagePattern); |
36 for (std::size_t i = 0; i < attributeSpecs.size(); ++i) { |
50 this->vertexArrayObject.create(); |
37 const auto& spec = attributeSpecs[i]; |
51 this->vertexArrayObject.bind(); |
38 const int attr = narrow<int>(signed_cast(i)); |
52 for (std::size_t i = 0; i < attributeSpecs.size(); ++i) { |
39 shader->program->enableAttributeArray(attr); |
53 const auto& spec = attributeSpecs[i]; |
40 shader->program->setAttributeBuffer(attr, spec.type, spec.offset, spec.tuplesize, spec.stride); |
54 const int attr = narrow<int>(signed_cast(i)); |
|
55 this->program->enableAttributeArray(attr); |
|
56 this->program->setAttributeBuffer(attr, spec.type, spec.offset, spec.tuplesize, spec.stride); |
|
57 } |
|
58 this->vertexArrayObject.release(); |
|
59 this->buffer.release(); |
|
60 this->program->release(); |
|
61 gl::checkForGLErrors(nullptr); |
|
62 } |
41 } |
63 } |
42 shader->vertexArrayObject.release(); |
64 |
43 shader->buffer.release(); |
65 void BasicShader::setMvpMatrix(const glm::mat4& newMvpMatrix) |
44 shader->program->release(); |
66 { |
|
67 this->setUniformMatrix("mvp", newMvpMatrix); |
|
68 } |
|
69 |
|
70 void BasicShader::setUniformMatrix(const char* name, const glm::mat4& value) |
|
71 { |
|
72 Q_ASSERT(this->isInitialized); |
|
73 this->program->bind(); |
|
74 this->program->setUniformMatrix(name, value); |
|
75 this->program->release(); |
|
76 gl::checkForGLErrors(nullptr); |
45 gl::checkForGLErrors(nullptr); |
77 } |
46 } |
78 |
47 |
79 void BasicShader::setUniformVector(const char* name, const glm::vec4& value) |
48 void gl::set_shader_matrix_uniform( |
|
49 gl::basic_shader* shader, |
|
50 const char* name, |
|
51 const glm::mat4& value) |
80 { |
52 { |
81 Q_ASSERT(this->isInitialized); |
53 Q_ASSERT(shader->program != nullptr); |
82 this->program->bind(); |
54 shader->program->bind(); |
83 this->program->setUniformVector(name, value); |
55 shader->program->setUniformMatrix(name, value); |
84 this->program->release(); |
56 shader->program->release(); |
85 gl::checkForGLErrors(nullptr); |
57 gl::checkForGLErrors(nullptr); |
86 } |
58 } |
87 |
59 |
88 void BasicShader::bufferData(const void* data, std::size_t count, std::size_t size) |
60 void gl::set_shader_vector_uniform( |
|
61 gl::basic_shader* shader, |
|
62 const char* name, |
|
63 const glm::vec4& value) |
89 { |
64 { |
90 this->buffer.bind(); |
65 Q_ASSERT(shader->program != nullptr); |
91 this->buffer.allocate(data, narrow<int>(signed_cast(count * size))); |
66 shader->program->bind(); |
92 this->buffer.release(); |
67 shader->program->setUniformVector(name, value); |
93 this->vertexCount = narrow<int>(signed_cast(count)); |
68 shader->program->release(); |
94 } |
|
95 |
|
96 void BasicShader::draw(GLenum drawMode) |
|
97 { |
|
98 this->program->bind(); |
|
99 this->vertexArrayObject.bind(); |
|
100 glDrawArrays(drawMode, 0, this->vertexCount); |
|
101 this->vertexArrayObject.release(); |
|
102 this->program->release(); |
|
103 gl::checkForGLErrors(nullptr); |
69 gl::checkForGLErrors(nullptr); |
104 } |
70 } |
105 |
71 |
106 void BasicShader::teardown() |
72 void gl::buffer_shader_data( |
|
73 gl::basic_shader* shader, |
|
74 const void* data, |
|
75 std::size_t count, |
|
76 std::size_t size) |
107 { |
77 { |
108 this->vertexArrayObject.destroy(); |
78 shader->buffer.bind(); |
109 this->buffer.destroy(); |
79 shader->buffer.allocate(data, narrow<int>(signed_cast(count * size))); |
110 this->program.reset(); |
80 shader->buffer.release(); |
|
81 shader->vertexCount = narrow<int>(signed_cast(count)); |
111 } |
82 } |
|
83 |
|
84 void gl::draw_shader( |
|
85 gl::basic_shader* shader, |
|
86 GLenum drawMode) |
|
87 { |
|
88 shader->program->bind(); |
|
89 shader->vertexArrayObject.bind(); |
|
90 glDrawArrays(drawMode, 0, shader->vertexCount); |
|
91 shader->vertexArrayObject.release(); |
|
92 shader->program->release(); |
|
93 gl::checkForGLErrors(nullptr); |
|
94 } |