src/gl/compiler.h

Wed, 15 Jun 2022 12:32:40 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Wed, 15 Jun 2022 12:32:40 +0300
changeset 224
54fd83d4db9c
parent 217
6d95c1a41e6e
child 259
c27612f0eac0
permissions
-rw-r--r--

GCC doesn't like me using QStringLiteral here

/*
 *  LDForge: LDraw parts authoring CAD
 *  Copyright (C) 2013 - 2018 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/>.
 */

#pragma once
#include "basics.h"
#include "gl/common.h"
#include "types/boundingbox.h"
#include <glm/gtc/type_ptr.hpp>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>
#include <QOpenGLExtraFunctions>
#include "model.h"

class Model;
class DocumentManager;

namespace gl
{
	// VAO names
	enum class ArrayClass : std::uint8_t
	{
		Lines,
		Triangles,
		Quads,
		ConditionalLines
	};
	
	constexpr ArrayClass ARRAY_CLASSES[] = {
		ArrayClass::Lines,
		ArrayClass::Triangles,
		ArrayClass::Quads,
		ArrayClass::ConditionalLines,
	};
	constexpr int NUM_ARRAY_CLASSES = countof(ARRAY_CLASSES);

	struct ModelShaders
	{
		struct Vertex
		{
			glm::vec3 position;
			glm::vec4 color;
			glm::vec3 normal;
			glm::int32 id;
			glm::int32 selected = 0;
		};
		bool initialized = false;
		struct ShaderObject
		{
			std::unique_ptr<QOpenGLShaderProgram> program = nullptr;
			QOpenGLShaderProgram* pickSceneProgram = nullptr;
			QOpenGLBuffer buffer{QOpenGLBuffer::VertexBuffer};
			QOpenGLVertexArrayObject vertexArray;
			std::vector<Vertex> cachedData;
			std::size_t vertexCount;
		} shaderObjects[gl::NUM_ARRAY_CLASSES];
	};

	void build(ModelShaders* shaders,
		Model* model,
		const ColorTable& colorTable,
		DocumentManager* context,
		const RenderPreferences& preferences);
	void initializeModelShaders(ModelShaders* modelShaders);
	void bindModelShaderVertexArray(gl::ModelShaders* shaders, gl::ArrayClass arrayClass);
	void releaseModelShaderVertexArray(gl::ModelShaders* shaders, gl::ArrayClass arrayClass);
	void setModelShaderSelectedObjects(gl::ModelShaders* shaders, const QSet<ModelId>& ids);
	std::size_t vertexCount(const ModelShaders *shaders, gl::ArrayClass arrayClass);
	ModelId idFromColor(const std::array<GLubyte, 3>& data);

	template<typename T>
	void setShaderUniform(gl::ModelShaders* shaders, const char* uniformName, T&& value)
	{
		for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects)
		{
			shader.program->bind();
			const int location = glfunc.glGetUniformLocation(shader.program->programId(), uniformName);
			Q_ASSERT(location != -1);
			shader.program->setUniformValue(location, std::forward<T>(value));
			shader.program->release();
		}
	}

	template<typename Float, glm::qualifier Prec>
	void setShaderUniformMatrix(
		gl::ModelShaders* shaders,
		const char* uniformName,
		const glm::mat<4, 4, Float, Prec>& value)
	{
		const float (*array)[4][4] = reinterpret_cast<const float(*)[4][4]>(glm::value_ptr(value));
		setShaderUniform(shaders, uniformName, *array);
	}

	BoundingBox boundingBoxForModel(Model* model, DocumentManager* context);
}

#define CHECK_GL_ERROR() { checkGLError(__FILE__, __LINE__); }
void checkGLError (QString file, int line);

mercurial