src/gl/geometrypreview.cpp

Wed, 17 Feb 2021 16:49:35 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 17 Feb 2021 16:49:35 +0200
changeset 102
9f435f66bd0c
permissions
-rw-r--r--

stuff

#include "geometrypreview.h"

const char vertexShaderSource[] = R"(
#version 330 core

layout (location = 0) in vec3 in_position;
layout (location = 1) in vec3 in_color;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 model;
smooth out vec3 ex_color;

void main()
{
	gl_Position = projection * view * model * vec4(in_position, 1.0);
	ex_color = in_color;
}
)";

const char fragmentShaderSource[] = R"(
#version 330 core

out vec4 color;
smooth in vec3 ex_color;

void main(void)
{
	color = vec4(ex_color, 1);
}
)";

constexpr std::size_t vertexSize = sizeof(GeometryPreview::Vertex);

GeometryPreview::GeometryPreview(QObject *parent) :
	AbstractShaderProgram{{
		{GL_LINES, vertexSize, QOpenGLBuffer::DynamicDraw}, 
		{GL_TRIANGLES, vertexSize, QOpenGLBuffer::DynamicDraw}
	}, parent}
{
}

GeometryPreview::~GeometryPreview()
{
}

QVector<GeometryPreview::Vertex>& GeometryPreview::modifyLinesBuffer()
{
	this->needRebuild = true;
	return this->lines;
}

QVector<GeometryPreview::Vertex>& GeometryPreview::modifyTrianglesBuffer()
{
	this->needRebuild = true;
	return this->triangles;
}

void GeometryPreview::initialize()
{
	if (not this->isInitialized)
	{
		this->isInitialized = true;
		this->program.emplace(this);
		gl::buildShaders(&*this->program, ::vertexShaderSource, ::fragmentShaderSource);
		this->program->bind();
		for (QOpenGLBuffer* buffer : {&this->linesBuffer, &this->trianglesBuffer})
		{
			buffer->create();
			buffer->bind();
			buffer->setUsagePattern(QOpenGLBuffer::DynamicDraw);
		}
		this->vertexArrayObject.create();
		this->vertexArrayObject.bind();
		this->setupVertexArrays();
		this->vertexArrayObject.release();
		for (auto& buffer : {this->linesBuffer, this->trianglesBuffer})
		{
			buffer->release();
		}
		this->program->release();
		this->checkForGLErrors();
	}
}

void GeometryPreview::rebuildIfNecessary()
{
	if (this->needRebuild)
	{
		this->buffer.allocate(this->vertexData(), this->vertexCount() * this->vertexSize());
		this->needRebuild = false;
	}
}

void GeometryPreview::checkForGLErrors()
{
	gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent()));
}

void GeometryPreview::setupVertexArrays()
{
	for (int i : {0, 1})
	{
		this->program->enableAttributeArray(i);
	}
	const int stride = this->vertexSize();
	this->program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride);
	this->program->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, color), 4, stride);
}

mercurial