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