src/gl/compiler.h

Sat, 02 Jul 2022 19:03:57 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Sat, 02 Jul 2022 19:03:57 +0300
changeset 315
23b47902d857
parent 309
d862721d19a3
child 333
07e65a4c6611
permissions
-rw-r--r--

Improve preview of cylinder extrusion

/*
 *  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 <GL/glew.h>
#include <glm/gtc/type_ptr.hpp>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>
#include "src/basics.h"
#include "src/types/boundingbox.h"
#include "src/model.h"
#include "src/gl/common.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::vec3 pickcolor;
			glm::int32 id;
			float selected = 0.0f;
		};
		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<ElementId>& ids);
	std::size_t vertexCount(const ModelShaders *shaders, gl::ArrayClass arrayClass);
	ElementId idFromUcharColor(const std::array<GLubyte, 3>& data);

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

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

	inline void setShaderUniformVector(
		gl::ModelShaders* shaders,
		const char* uniformName,
		const glm::vec4& value)
	{
		setShaderUniform(shaders, uniformName, value.x, value.y, value.z, value.w);
	}

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

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

mercurial