src/gl/basicshaderprogram.cpp

Sat, 08 Apr 2023 12:55:11 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Sat, 08 Apr 2023 12:55:11 +0300
changeset 343
4a82990affd5
parent 264
76a025db4948
child 377
e1c5e4310f8b
permissions
-rw-r--r--

Fix BFC formatting not working due to being evaluated after comment format

/*
 *  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 "src/gl/basicshaderprogram.h"

BasicShader::BasicShader() :
	buffer{QOpenGLBuffer::VertexBuffer},
	vertexShader{QOpenGLShader::Vertex},
	fragmentShader{QOpenGLShader::Fragment}
{
}

BasicShader::~BasicShader()
{
	if (this->isInitialized) {
		this->teardown();
	}
}

void BasicShader::initialize(
	const char* vertexShaderSource,
	const char* fragmentShaderSource,
	QOpenGLBuffer::UsagePattern usagePattern,
	const std::vector<GLAttributeSpec>& attributeSpecs)
{
	if (not this->isInitialized)
	{
		this->isInitialized = true;
		this->program = std::make_unique<gl::ShaderProgram>();
		gl::buildShaders(this->program.get(), 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];
			const int attr = narrow<int>(signed_cast(i));
			this->program->enableAttributeArray(attr);
			this->program->setAttributeBuffer(attr, spec.type, spec.offset, spec.tuplesize, spec.stride);
		}
		this->vertexArrayObject.release();
		this->buffer.release();
		this->program->release();
		gl::checkForGLErrors(nullptr);
	}
}

void BasicShader::setMvpMatrix(const glm::mat4& newMvpMatrix)
{
	this->setUniformMatrix("mvp", newMvpMatrix);
}

void BasicShader::setUniformMatrix(const char* name, const glm::mat4& value)
{
	Q_ASSERT(this->isInitialized);
	this->program->bind();
	this->program->setUniformMatrix(name, value);
	this->program->release();
	gl::checkForGLErrors(nullptr);
}

void BasicShader::setUniformVector(const char* name, const glm::vec4& value)
{
	Q_ASSERT(this->isInitialized);
	this->program->bind();
	this->program->setUniformVector(name, value);
	this->program->release();
	gl::checkForGLErrors(nullptr);
}

void BasicShader::bufferData(const void* data, std::size_t count, std::size_t size)
{
	this->buffer.bind();
	this->buffer.allocate(data, narrow<int>(signed_cast(count * size)));
	this->buffer.release();
	this->vertexCount = narrow<int>(signed_cast(count));
}

void BasicShader::draw(GLenum drawMode)
{
	this->program->bind();
	this->vertexArrayObject.bind();
	glDrawArrays(drawMode, 0, this->vertexCount);
	this->vertexArrayObject.release();
	this->program->release();
	gl::checkForGLErrors(nullptr);
}

void BasicShader::teardown()
{
	this->vertexArrayObject.destroy();
	this->buffer.destroy();
	this->program.reset();
}

mercurial