[libcamera-devel] [PATCH v3 2/6] pipeline: simple: Implements Shader Handling

Kunal Agarwal kunalagarwal1072002 at gmail.com
Sun Aug 14 18:07:43 CEST 2022


Shader Class which includes functions for building,
activating, deleting and compiling shaders

Signed-off-by: Kunal Agarwal <kunalagarwal1072002 at gmail.com>
---
 src/libcamera/pipeline/simple/shader.cpp | 110 +++++++++++++++++++++++
 src/libcamera/pipeline/simple/shader.h   |  34 +++++++
 2 files changed, 144 insertions(+)
 create mode 100644 src/libcamera/pipeline/simple/shader.cpp
 create mode 100644 src/libcamera/pipeline/simple/shader.h

diff --git a/src/libcamera/pipeline/simple/shader.cpp b/src/libcamera/pipeline/simple/shader.cpp
new file mode 100644
index 00000000..f0079618
--- /dev/null
+++ b/src/libcamera/pipeline/simple/shader.cpp
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Kunal Agarwal
+ *
+ * shader.cpp - Shader Handling
+ */
+
+#include "shader.h"
+
+#include <libcamera/base/file.h>
+#include <libcamera/base/log.h>
+
+#include <GLES3/gl3.h>
+
+namespace libcamera {
+
+LOG_DECLARE_CATEGORY(SimplePipeline)
+
+/* Reads a text file and outputs a string with everything in the text file */
+static std::string get_file_contents(const char *filename)
+{
+	std::string fullname = std::string("/home/pi/Desktop/compile/libcamera/src/libcamera/pipeline/simple/shader/") + filename;
+
+	File file(fullname);
+	if (!file.open(File::OpenModeFlag::ReadOnly))
+		return "";
+
+	Span<uint8_t> data = file.map();
+	return std::string(reinterpret_cast<char *>(data.data()), data.size());
+}
+
+/* Constructor that build the Shader Program from 2 different shaders */
+void ShaderProgram::callShader(const char *vertexFile, const char *fragmentFile)
+{
+	/* Read vertexFile and fragmentFile and store the strings */
+	std::string vertexCode = get_file_contents(vertexFile);
+	std::string fragmentCode = get_file_contents(fragmentFile);
+	const char *vertexSource = vertexCode.c_str();
+	const char *fragmentSource = fragmentCode.c_str();
+
+	/* Create the vertex shader, set its source code and compile it. */
+	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
+	glShaderSource(vertexShader, 1, &vertexSource, NULL);
+	glCompileShader(vertexShader);
+	compileErrors(vertexShader, "VERTEX");
+
+	/* Create the fragment shader, set its source code and compile it. */
+	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+	glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
+	glCompileShader(fragmentShader);
+	compileErrors(fragmentShader, "FRAGMENT");
+
+	/* Create Shader Program Object and get its reference */
+	id_ = glCreateProgram();
+
+	/* Attach and wrap-up/link the Vertex and Fragment Shaders to the Shader Program */
+	glAttachShader(id_, vertexShader);
+	glAttachShader(id_, fragmentShader);
+	glLinkProgram(id_);
+
+	/* Checks if Shaders linked succesfully */
+	compileErrors(id_, "PROGRAM");
+
+	/* Delete the Vertex and Fragment Shader objects. Here, they are flagged for deletion
+	   and will not be deleted until they are detached from the program object. This frees
+	   up the memory used to store the shader source. */
+	glDeleteShader(vertexShader);
+	glDeleteShader(fragmentShader);
+}
+
+/* Activates the Shader Program */
+void ShaderProgram::activate()
+{
+	glUseProgram(id_);
+}
+
+/* Deletes the Shader Program */
+void ShaderProgram::deleteProgram()
+{
+	glDeleteProgram(id_);
+}
+
+/* Checks if the different Shaders have compiled properly */
+void ShaderProgram::compileErrors(unsigned int shader, const char *type)
+{
+	/* Stores status of compilation */
+	GLint hasCompiled;
+	GLint logLength;
+	/* Character array to store error message in */
+	glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
+	char *infoLog = new char[logLength];
+	if (strcmp(type, "PROGRAM") != 0) {
+		glGetShaderiv(shader, GL_COMPILE_STATUS, &hasCompiled);
+		if (hasCompiled == GL_FALSE) {
+			glGetShaderInfoLog(shader, logLength, NULL, infoLog);
+			LOG(SimplePipeline, Error) << "SHADER_COMPILATION_ERROR for:"
+						   << type << "\t"
+						   << infoLog;
+		}
+	} else {
+		glGetProgramiv(shader, GL_LINK_STATUS, &hasCompiled);
+		if (hasCompiled == GL_FALSE) {
+			glGetProgramInfoLog(shader, logLength, NULL, infoLog);
+			LOG(SimplePipeline, Error) << "SHADER_LINKING_ERROR for:"
+						   << type << "\t"
+						   << infoLog;
+		}
+	}
+}
+} /* namespace libcamera */
diff --git a/src/libcamera/pipeline/simple/shader.h b/src/libcamera/pipeline/simple/shader.h
new file mode 100644
index 00000000..921e4040
--- /dev/null
+++ b/src/libcamera/pipeline/simple/shader.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Kunal Agarwal
+ *
+ * shader.h - Shader Handling
+ */
+
+#pragma once
+
+#include <iostream>
+#include <string.h>
+
+#include <GL/gl.h>
+
+namespace libcamera {
+
+class ShaderProgram
+{
+public:
+	void callShader(const char *vertexFile, const char *fragmentFile);
+
+	void activate();
+
+	void deleteProgram();
+
+	int id() const { return id_; };
+
+private:
+	/* Reference ID of the Shader Program */
+	GLuint id_;
+	void compileErrors(unsigned int shader, const char *type);
+};
+
+} /* namespace libcamera */
-- 
2.25.1



More information about the libcamera-devel mailing list