Wed, 17 Feb 2021 16:49:35 +0200
stuff
/* * LDForge: LDraw parts authoring CAD * Copyright (C) 2020 Teemu Piippo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "abstractshaderprogram.h" AbstractShaderProgram::AbstractBasicShaderProgram(const QVector<ArraySpecification>& arraySpecifications, QObject* parent) : QObject{parent}, buffer{QOpenGLBuffer::VertexBuffer}, vertexShader{QOpenGLShader::Vertex}, fragmentShader{QOpenGLShader::Fragment} { this->arrays.reserve(arraySpecifications.size()); for (const ArraySpecification& arraySpecification : arraySpecifications) { this->arrays.emplace_back({arraySpecification}); } } void AbstractShaderProgram::initialize() { if (not this->isInitialized) { this->initializeOpenGLFunctions(); this->isInitialized = true; this->program.emplace(this); gl::buildShaders(&*this->program, this->vertexShaderSource(), this->fragmentShaderSource()); this->program->bind(); for (auto& array : this->arrays) { array.buffer.create(); array.buffer.bind(); array.buffer.setUsagePattern(array.specification.bufferUsagePattern); array.vertexArrayObject.create(); array.vertexArrayObject.bind(); } this->setupVertexArrays(); this->vertexArrayObject.release(); this->releaseBuffers(); this->buffer.release(); this->program->release(); this->checkForGLErrors(); } } void AbstractShaderProgram::setViewMatrix(const glm::mat4& newViewMatrix) { this->setMatrix("view", newViewMatrix); } void AbstractShaderProgram::setProjectionMatrix(const glm::mat4& newProjectionMatrix) { this->setMatrix("projection", newProjectionMatrix); } void AbstractShaderProgram::setModelMatrix(const glm::mat4& newModelMatrix) { this->setMatrix("model", newModelMatrix); } void AbstractShaderProgram::setMatrix(const char* name, const glm::mat4& matrix) { Q_ASSERT(this->isInitialized); this->program->bind(); this->program->setUniformMatrix(name, matrix); this->program->release(); this->checkForGLErrors(); } void AbstractShaderProgram::draw() { this->program->bind(); for (Array& array : this->arrays) { array.vertexArrayObject.bind(); glDrawArrays(array.specification.drawMode, 0, array.count); this->vertexArrayObject.release(); } this->program->release(); this->checkForGLErrors(); } void AbstractShaderProgram::teardown() { this->vertexArrayObject.destroy(); this->buffer.destroy(); this->program.reset(); } void AbstractShaderProgram::checkForGLErrors() { gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent())); } void AbstractShaderProgram::upload(Array* array, const void* data, int count) { array->count = count; array->buffer->buffer.allocate(data, count * array->specification.vertexSize); }