src/gl/basicshaderprogram.cpp

changeset 215
34c6e7bc4ee1
parent 118
8e1c9f18ae15
child 216
c7241f504117
--- a/src/gl/basicshaderprogram.cpp	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/gl/basicshaderprogram.cpp	Sun Jun 12 23:59:37 2022 +0300
@@ -18,83 +18,80 @@
 
 #include "basicshaderprogram.h"
 
-AbstractBasicShaderProgram::AbstractBasicShaderProgram(QObject* parent) :
-	QObject{parent},
+BasicShader::BasicShader() :
 	buffer{QOpenGLBuffer::VertexBuffer},
 	vertexShader{QOpenGLShader::Vertex},
 	fragmentShader{QOpenGLShader::Fragment}
 {
 }
 
-void AbstractBasicShaderProgram::initialize()
+BasicShader::~BasicShader()
 {
-	if (not isInitialized)
-	{
-		this->initializeOpenGLFunctions();
-		this->isInitialized = true;
-		this->program.emplace(this);
-		gl::buildShaders(&*this->program, this->vertexShaderSource(), this->fragmentShaderSource());
-		this->program->bind();
-		this->buffer.create();
-		this->buffer.bind();
-		const QOpenGLBuffer::UsagePattern pattern = this->usagePattern();
-		this->buffer.setUsagePattern(pattern);
-		if (pattern == QOpenGLBuffer::StaticDraw)
-		{
-			this->buffer.allocate(this->vertexData(), this->vertexCount() * this->vertexSize());
-		}
-		this->vertexArrayObject.create();
-		this->vertexArrayObject.bind();
-		this->setupVertexArrays();
-		this->vertexArrayObject.release();
-		this->buffer.release();
-		this->program->release();
-		this->checkForGLErrors();
+	if (this->isInitialized) {
+		this->teardown();
 	}
 }
 
-void AbstractBasicShaderProgram::setViewMatrix(const glm::mat4& newViewMatrix)
+void BasicShader::initialize(
+	const char* vertexShaderSource,
+	const char* fragmentShaderSource,
+	QOpenGLBuffer::UsagePattern usagePattern,
+	const std::vector<GLAttributeSpec>& attributeSpecs)
 {
-	this->setMatrix("view", newViewMatrix);
+	if (not this->isInitialized)
+	{
+		this->initializeOpenGLFunctions();
+		this->isInitialized = true;
+		this->program = std::make_unique<gl::ShaderProgram>();
+		gl::buildShaders(&*this->program, 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 AbstractBasicShaderProgram::setProjectionMatrix(const glm::mat4& newProjectionMatrix)
-{
-	this->setMatrix("projection", newProjectionMatrix);
-}
-
-void AbstractBasicShaderProgram::setModelMatrix(const glm::mat4& newModelMatrix)
-{
-	this->setMatrix("model", newModelMatrix);
-}
-
-void AbstractBasicShaderProgram::setMatrix(const char* name, const glm::mat4& matrix)
+void BasicShader::setMvpMatrix(const glm::mat4& newMvpMatrix)
 {
 	Q_ASSERT(this->isInitialized);
 	this->program->bind();
-	this->program->setUniformMatrix(name, matrix);
+	this->program->setUniformMatrix("mvp", newMvpMatrix);
 	this->program->release();
-	this->checkForGLErrors();
+	gl::checkForGLErrors(nullptr);
 }
 
-void AbstractBasicShaderProgram::draw()
+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(this->drawMode(), 0, this->vertexCount());
+	glDrawArrays(drawMode, 0, this->vertexCount);
 	this->vertexArrayObject.release();
 	this->program->release();
-	this->checkForGLErrors();
+	gl::checkForGLErrors(nullptr);
 }
 
-void AbstractBasicShaderProgram::teardown()
+void BasicShader::teardown()
 {
 	this->vertexArrayObject.destroy();
 	this->buffer.destroy();
 	this->program.reset();
 }
-
-void AbstractBasicShaderProgram::checkForGLErrors()
-{
-	gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent()));
-}

mercurial