src/gl/basicshaderprogram.cpp

Tue, 14 Jun 2022 17:55:50 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Tue, 14 Jun 2022 17:55:50 +0300
changeset 217
6d95c1a41e6e
parent 216
c7241f504117
child 250
2837b549e616
permissions
-rw-r--r--

reimplement EditTools as a render layer

/*
 *  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 "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->initializeOpenGLFunctions();
		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];
			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 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, count * size);
	this->buffer.release();
	this->vertexCount = 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