Basic project setup

the example from https://learnopengl.com/Advanced-OpenGL/Geometry-Shader is functional; built with SCons.
This commit is contained in:
karl 2021-03-16 19:53:16 +01:00
parent c11e2d3dfe
commit 9ab7f3eed0
9 changed files with 9729 additions and 4 deletions

View File

@ -1,7 +1,12 @@
#!python
# Create the environment and create a Compilation Database for use in VSCodium
env = DefaultEnvironment(tools=['default', 'compilation_db'])
env = Environment(
CCFLAGS=['-std=c++17', '-Wall', '-O0', '-g'],
tools=['default', 'compilation_db'])
env.CompilationDatabase()
Program('program.out', Glob('*.cpp'))
env.Append(LIBS=['glfw', 'dl'])
env.Program('program.out', [Glob('*.cpp', 'Util/*.cpp'), 'Util/glad.c'])

170
Shader.h Normal file
View File

@ -0,0 +1,170 @@
// Adapted from LearnOpenGL
#ifndef SHADER_H
#define SHADER_H
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
class Shader {
public:
unsigned int ID;
// constructor generates the shader on the fly
// ------------------------------------------------------------------------
Shader(const char *vertexPath, const char *fragmentPath, const char *geometryPath = nullptr) {
// 1. retrieve the vertex/fragment source code from filePath
std::string vertexCode;
std::string fragmentCode;
std::string geometryCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
std::ifstream gShaderFile;
// ensure ifstream objects can throw exceptions:
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
gShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
// open files
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
// read file's buffer contents into streams
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
// close file handlers
vShaderFile.close();
fShaderFile.close();
// convert stream into string
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
// if geometry shader path is present, also load a geometry shader
if (geometryPath != nullptr) {
gShaderFile.open(geometryPath);
std::stringstream gShaderStream;
gShaderStream << gShaderFile.rdbuf();
gShaderFile.close();
geometryCode = gShaderStream.str();
}
} catch (std::ifstream::failure &e) {
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
const char *vShaderCode = vertexCode.c_str();
const char *fShaderCode = fragmentCode.c_str();
// 2. compile shaders
unsigned int vertex, fragment;
// vertex shader
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
checkCompileErrors(vertex, "VERTEX");
// fragment Shader
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
checkCompileErrors(fragment, "FRAGMENT");
// if geometry shader is given, compile geometry shader
unsigned int geometry;
if (geometryPath != nullptr) {
const char *gShaderCode = geometryCode.c_str();
geometry = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(geometry, 1, &gShaderCode, NULL);
glCompileShader(geometry);
checkCompileErrors(geometry, "GEOMETRY");
}
// shader Program
ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
if (geometryPath != nullptr) glAttachShader(ID, geometry);
glLinkProgram(ID);
checkCompileErrors(ID, "PROGRAM");
// delete the shaders as they're linked into our program now and no longer necessery
glDeleteShader(vertex);
glDeleteShader(fragment);
if (geometryPath != nullptr) glDeleteShader(geometry);
}
// activate the shader
// ------------------------------------------------------------------------
void use() {
glUseProgram(ID);
}
// utility uniform functions
// ------------------------------------------------------------------------
void setBool(const std::string &name, bool value) const {
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
}
// ------------------------------------------------------------------------
void setInt(const std::string &name, int value) const {
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setFloat(const std::string &name, float value) const {
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setVec2(const std::string &name, const glm::vec2 &value) const {
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setVec2(const std::string &name, float x, float y) const {
glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
}
// ------------------------------------------------------------------------
void setVec3(const std::string &name, const glm::vec3 &value) const {
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setVec3(const std::string &name, float x, float y, float z) const {
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
}
// ------------------------------------------------------------------------
void setVec4(const std::string &name, const glm::vec4 &value) const {
glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setVec4(const std::string &name, float x, float y, float z, float w) {
glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
}
// ------------------------------------------------------------------------
void setMat2(const std::string &name, const glm::mat2 &mat) const {
glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat3(const std::string &name, const glm::mat3 &mat) const {
glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat4(const std::string &name, const glm::mat4 &mat) const {
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
private:
// utility function for checking shader compilation/linking errors.
// ------------------------------------------------------------------------
void checkCompileErrors(GLuint shader, std::string type) {
GLint success;
GLchar infoLog[1024];
if (type != "PROGRAM") {
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n"
<< infoLog
<< "\n -- --------------------------------------------------- -- "
<< std::endl;
}
} else {
glGetProgramiv(shader, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n"
<< infoLog
<< "\n -- --------------------------------------------------- -- "
<< std::endl;
}
}
}
};
#endif

10
Shader/mc.fs Normal file
View File

@ -0,0 +1,10 @@
#version 330 core
out vec4 FragColor;
in vec3 fColor;
void main()
{
FragColor = vec4(fColor, 1.0);
}

31
Shader/mc.gs Normal file
View File

@ -0,0 +1,31 @@
#version 330 core
layout (points) in;
layout (triangle_strip, max_vertices = 5) out;
in VS_OUT {
vec3 color;
} gs_in[];
out vec3 fColor;
void build_house(vec4 position)
{
fColor = gs_in[0].color; // gs_in[0] since there's only one input vertex
gl_Position = position + vec4(-0.2, -0.2, 0.0, 0.0); // 1:bottom-left
EmitVertex();
gl_Position = position + vec4( 0.2, -0.2, 0.0, 0.0); // 2:bottom-right
EmitVertex();
gl_Position = position + vec4(-0.2, 0.2, 0.0, 0.0); // 3:top-left
EmitVertex();
gl_Position = position + vec4( 0.2, 0.2, 0.0, 0.0); // 4:top-right
EmitVertex();
gl_Position = position + vec4( 0.0, 0.4, 0.0, 0.0); // 5:top
fColor = vec3(1.0, 1.0, 1.0);
EmitVertex();
EndPrimitive();
}
void main() {
build_house(gl_in[0].gl_Position);
}

14
Shader/mc.vs Normal file
View File

@ -0,0 +1,14 @@
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec3 aColor;
out VS_OUT {
vec3 color;
} vs_out;
void main()
{
vs_out.color = aColor;
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
}

1833
Util/glad.c Normal file

File diff suppressed because it is too large Load Diff

7559
Util/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

2
Util/stb_setup.cpp Normal file
View File

@ -0,0 +1,2 @@
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

105
main.cpp
View File

@ -1,7 +1,108 @@
#include <glad/glad.h>
// Needs to be second
#include <GLFW/glfw3.h>
#include "Shader.h"
#include <iostream>
int main() {
std::cout << "Hello World!" << std::endl;
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
int main() {
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// glfw window creation
// --------------------
GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// configure global opengl state
// -----------------------------
glEnable(GL_DEPTH_TEST);
// build and compile shaders
// -------------------------
Shader shader("Shader/mc.vs", "Shader/mc.fs", "Shader/mc.gs");
// set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
float points[] = {
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 0.0f // bottom-left
};
unsigned int VBO, VAO;
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), &points, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(2 * sizeof(float)));
glBindVertexArray(0);
// render loop
// -----------
while (!glfwWindowShouldClose(window)) {
// render
// ------
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw points
shader.use();
glBindVertexArray(VAO);
glDrawArrays(GL_POINTS, 0, 4);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}