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 "basicshaderprogram.h" |
19 #include "basicshaderprogram.h" |
20 |
20 |
21 AbstractBasicShaderProgram::AbstractBasicShaderProgram(QObject* parent) : |
21 BasicShader::BasicShader() : |
22 QObject{parent}, |
|
23 buffer{QOpenGLBuffer::VertexBuffer}, |
22 buffer{QOpenGLBuffer::VertexBuffer}, |
24 vertexShader{QOpenGLShader::Vertex}, |
23 vertexShader{QOpenGLShader::Vertex}, |
25 fragmentShader{QOpenGLShader::Fragment} |
24 fragmentShader{QOpenGLShader::Fragment} |
26 { |
25 { |
27 } |
26 } |
28 |
27 |
29 void AbstractBasicShaderProgram::initialize() |
28 BasicShader::~BasicShader() |
30 { |
29 { |
31 if (not isInitialized) |
30 if (this->isInitialized) { |
|
31 this->teardown(); |
|
32 } |
|
33 } |
|
34 |
|
35 void BasicShader::initialize( |
|
36 const char* vertexShaderSource, |
|
37 const char* fragmentShaderSource, |
|
38 QOpenGLBuffer::UsagePattern usagePattern, |
|
39 const std::vector<GLAttributeSpec>& attributeSpecs) |
|
40 { |
|
41 if (not this->isInitialized) |
32 { |
42 { |
33 this->initializeOpenGLFunctions(); |
43 this->initializeOpenGLFunctions(); |
34 this->isInitialized = true; |
44 this->isInitialized = true; |
35 this->program.emplace(this); |
45 this->program = std::make_unique<gl::ShaderProgram>(); |
36 gl::buildShaders(&*this->program, this->vertexShaderSource(), this->fragmentShaderSource()); |
46 gl::buildShaders(&*this->program, vertexShaderSource, fragmentShaderSource); |
37 this->program->bind(); |
47 this->program->bind(); |
38 this->buffer.create(); |
48 this->buffer.create(); |
39 this->buffer.bind(); |
49 this->buffer.bind(); |
40 const QOpenGLBuffer::UsagePattern pattern = this->usagePattern(); |
50 this->buffer.setUsagePattern(usagePattern); |
41 this->buffer.setUsagePattern(pattern); |
|
42 if (pattern == QOpenGLBuffer::StaticDraw) |
|
43 { |
|
44 this->buffer.allocate(this->vertexData(), this->vertexCount() * this->vertexSize()); |
|
45 } |
|
46 this->vertexArrayObject.create(); |
51 this->vertexArrayObject.create(); |
47 this->vertexArrayObject.bind(); |
52 this->vertexArrayObject.bind(); |
48 this->setupVertexArrays(); |
53 for (std::size_t i = 0; i < attributeSpecs.size(); ++i) { |
|
54 const auto& spec = attributeSpecs[i]; |
|
55 this->program->enableAttributeArray(i); |
|
56 this->program->setAttributeBuffer(i, spec.type, spec.offset, spec.tuplesize, spec.stride); |
|
57 } |
49 this->vertexArrayObject.release(); |
58 this->vertexArrayObject.release(); |
50 this->buffer.release(); |
59 this->buffer.release(); |
51 this->program->release(); |
60 this->program->release(); |
52 this->checkForGLErrors(); |
61 gl::checkForGLErrors(nullptr); |
53 } |
62 } |
54 } |
63 } |
55 |
64 |
56 void AbstractBasicShaderProgram::setViewMatrix(const glm::mat4& newViewMatrix) |
65 void BasicShader::setMvpMatrix(const glm::mat4& newMvpMatrix) |
57 { |
|
58 this->setMatrix("view", newViewMatrix); |
|
59 } |
|
60 |
|
61 void AbstractBasicShaderProgram::setProjectionMatrix(const glm::mat4& newProjectionMatrix) |
|
62 { |
|
63 this->setMatrix("projection", newProjectionMatrix); |
|
64 } |
|
65 |
|
66 void AbstractBasicShaderProgram::setModelMatrix(const glm::mat4& newModelMatrix) |
|
67 { |
|
68 this->setMatrix("model", newModelMatrix); |
|
69 } |
|
70 |
|
71 void AbstractBasicShaderProgram::setMatrix(const char* name, const glm::mat4& matrix) |
|
72 { |
66 { |
73 Q_ASSERT(this->isInitialized); |
67 Q_ASSERT(this->isInitialized); |
74 this->program->bind(); |
68 this->program->bind(); |
75 this->program->setUniformMatrix(name, matrix); |
69 this->program->setUniformMatrix("mvp", newMvpMatrix); |
76 this->program->release(); |
70 this->program->release(); |
77 this->checkForGLErrors(); |
71 gl::checkForGLErrors(nullptr); |
78 } |
72 } |
79 |
73 |
80 void AbstractBasicShaderProgram::draw() |
74 void BasicShader::bufferData(const void* data, std::size_t count, std::size_t size) |
|
75 { |
|
76 this->buffer.bind(); |
|
77 this->buffer.allocate(data, count * size); |
|
78 this->buffer.release(); |
|
79 this->vertexCount = count; |
|
80 } |
|
81 |
|
82 void BasicShader::draw(GLenum drawMode) |
81 { |
83 { |
82 this->program->bind(); |
84 this->program->bind(); |
83 this->vertexArrayObject.bind(); |
85 this->vertexArrayObject.bind(); |
84 glDrawArrays(this->drawMode(), 0, this->vertexCount()); |
86 glDrawArrays(drawMode, 0, this->vertexCount); |
85 this->vertexArrayObject.release(); |
87 this->vertexArrayObject.release(); |
86 this->program->release(); |
88 this->program->release(); |
87 this->checkForGLErrors(); |
89 gl::checkForGLErrors(nullptr); |
88 } |
90 } |
89 |
91 |
90 void AbstractBasicShaderProgram::teardown() |
92 void BasicShader::teardown() |
91 { |
93 { |
92 this->vertexArrayObject.destroy(); |
94 this->vertexArrayObject.destroy(); |
93 this->buffer.destroy(); |
95 this->buffer.destroy(); |
94 this->program.reset(); |
96 this->program.reset(); |
95 } |
97 } |
96 |
|
97 void AbstractBasicShaderProgram::checkForGLErrors() |
|
98 { |
|
99 gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent())); |
|
100 } |
|