--- a/src/gl/basicshaderprogram.cpp Sun Jun 12 20:47:04 2022 +0300 +++ b/src/gl/basicshaderprogram.cpp Sun Jun 12 23:59:37 2022 +0300 @@ -18,83 +18,80 @@ #include "basicshaderprogram.h" -AbstractBasicShaderProgram::AbstractBasicShaderProgram(QObject* parent) : - QObject{parent}, +BasicShader::BasicShader() : buffer{QOpenGLBuffer::VertexBuffer}, vertexShader{QOpenGLShader::Vertex}, fragmentShader{QOpenGLShader::Fragment} { } -void AbstractBasicShaderProgram::initialize() +BasicShader::~BasicShader() { - if (not isInitialized) - { - this->initializeOpenGLFunctions(); - this->isInitialized = true; - this->program.emplace(this); - gl::buildShaders(&*this->program, this->vertexShaderSource(), this->fragmentShaderSource()); - this->program->bind(); - this->buffer.create(); - this->buffer.bind(); - const QOpenGLBuffer::UsagePattern pattern = this->usagePattern(); - this->buffer.setUsagePattern(pattern); - if (pattern == QOpenGLBuffer::StaticDraw) - { - this->buffer.allocate(this->vertexData(), this->vertexCount() * this->vertexSize()); - } - this->vertexArrayObject.create(); - this->vertexArrayObject.bind(); - this->setupVertexArrays(); - this->vertexArrayObject.release(); - this->buffer.release(); - this->program->release(); - this->checkForGLErrors(); + if (this->isInitialized) { + this->teardown(); } } -void AbstractBasicShaderProgram::setViewMatrix(const glm::mat4& newViewMatrix) +void BasicShader::initialize( + const char* vertexShaderSource, + const char* fragmentShaderSource, + QOpenGLBuffer::UsagePattern usagePattern, + const std::vector<GLAttributeSpec>& attributeSpecs) { - this->setMatrix("view", newViewMatrix); + if (not this->isInitialized) + { + this->initializeOpenGLFunctions(); + this->isInitialized = true; + this->program = std::make_unique<gl::ShaderProgram>(); + gl::buildShaders(&*this->program, vertexShaderSource, fragmentShaderSource); + this->program->bind(); + this->buffer.create(); + this->buffer.bind(); + this->buffer.setUsagePattern(usagePattern); + this->vertexArrayObject.create(); + this->vertexArrayObject.bind(); + for (std::size_t i = 0; i < attributeSpecs.size(); ++i) { + const auto& spec = attributeSpecs[i]; + this->program->enableAttributeArray(i); + this->program->setAttributeBuffer(i, spec.type, spec.offset, spec.tuplesize, spec.stride); + } + this->vertexArrayObject.release(); + this->buffer.release(); + this->program->release(); + gl::checkForGLErrors(nullptr); + } } -void AbstractBasicShaderProgram::setProjectionMatrix(const glm::mat4& newProjectionMatrix) -{ - this->setMatrix("projection", newProjectionMatrix); -} - -void AbstractBasicShaderProgram::setModelMatrix(const glm::mat4& newModelMatrix) -{ - this->setMatrix("model", newModelMatrix); -} - -void AbstractBasicShaderProgram::setMatrix(const char* name, const glm::mat4& matrix) +void BasicShader::setMvpMatrix(const glm::mat4& newMvpMatrix) { Q_ASSERT(this->isInitialized); this->program->bind(); - this->program->setUniformMatrix(name, matrix); + this->program->setUniformMatrix("mvp", newMvpMatrix); this->program->release(); - this->checkForGLErrors(); + gl::checkForGLErrors(nullptr); } -void AbstractBasicShaderProgram::draw() +void BasicShader::bufferData(const void* data, std::size_t count, std::size_t size) +{ + this->buffer.bind(); + this->buffer.allocate(data, count * size); + this->buffer.release(); + this->vertexCount = count; +} + +void BasicShader::draw(GLenum drawMode) { this->program->bind(); this->vertexArrayObject.bind(); - glDrawArrays(this->drawMode(), 0, this->vertexCount()); + glDrawArrays(drawMode, 0, this->vertexCount); this->vertexArrayObject.release(); this->program->release(); - this->checkForGLErrors(); + gl::checkForGLErrors(nullptr); } -void AbstractBasicShaderProgram::teardown() +void BasicShader::teardown() { this->vertexArrayObject.destroy(); this->buffer.destroy(); this->program.reset(); } - -void AbstractBasicShaderProgram::checkForGLErrors() -{ - gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent())); -}