Window Class, Shader Class, Read Shaders from file

master
aurailus 2018-11-26 17:52:44 -08:00
parent 22224ee367
commit 5f4751a27e
10 changed files with 350 additions and 209 deletions

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -13,7 +13,7 @@ find_package(glfw3 REQUIRED)
link_directories(GlProject/Libraries/glew/lib)
add_executable(GlProject
GlProject/Main.cpp GlProject/Mesh.cpp GlProject/Mesh.h GlProject/Entity.cpp GlProject/Entity.h)
GlProject/Main.cpp GlProject/Mesh.cpp GlProject/Mesh.h GlProject/Entity.cpp GlProject/Entity.h GlProject/Shader.cpp GlProject/Shader.h GlProject/Window.cpp GlProject/Window.h)
target_link_libraries(GlProject
${OPENGL_gl_LIBRARY}

View File

@ -9,128 +9,21 @@
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
#include "Window.h"
#include "Mesh.h"
#include "Entity.h"
#include "Shader.h"
//Window dimensions
const GLint width = 800;
const GLint height = 600;
Window mainWindow;
std::vector<Entity*> entities;
Entity* triangle;
//Conversion therapy
const float toRadians = 3.14159265f / 180.0f;
GLuint shader;
GLint uModel, uProjection;
Shader* shader;
bool triDirection = true; //Right
float triOffset = 0;
float triMaxOffset = 0.7;
float triMoveStep = 0.01;
float triAngle = 0;
float triAngleStep = 1.0f;
bool triScaleDir = true;
float triScaleMin = 0.1f;
float triScaleMax = 0.8f;
float triScaleCur = 0.4f;
float triScaleStep = 0.01f;
//Vertex Shader
static const char* vShader = "\n\
#version 330 \n\
\n\
layout (location = 0) in vec3 pos; \n\
\n\
uniform mat4 model; \n\
uniform mat4 projection; \n\
\n\
out vec4 color; \n\
\n\
void main() { \n\
gl_Position = projection * model * vec4(pos, 1.0); \n\
color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f); \n\
} \n\
";
//Fragment Shader
static const char* fShader = "\n\
#version 330 \n\
\n\
in vec4 color; \n\
\n\
out vec4 fragColor; \n\
\n\
void main() { \n\
fragColor = color; \n\
} \n\
";
void addShader(GLuint program, const char* shaderCode, GLenum shaderType) {
GLuint shader = glCreateShader(shaderType);
const GLchar* code;
code = shaderCode;
GLint codeLength;
codeLength = static_cast<GLint>(strlen(shaderCode));
glShaderSource(shader, 1, &code, &codeLength);
glCompileShader(shader);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
if (!result) {
const char* shaderTypeString = (shaderType == GL_VERTEX_SHADER) ? "vertex" : "fragment";
glGetShaderInfoLog(shader, sizeof(eLog), nullptr, eLog);
printf("Error compiling the %s shader:\n'%s'\n", shaderTypeString, eLog);
return;
}
glAttachShader(program, shader);
}
void compileShaders() {
shader = glCreateProgram();
if (!shader) {
printf("Error creating the shader program.");
return;
}
addShader(shader, vShader, GL_VERTEX_SHADER);
addShader(shader, fShader, GL_FRAGMENT_SHADER);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glLinkProgram(shader);
glGetProgramiv(shader, GL_LINK_STATUS, &result);
if (!result) {
glGetProgramInfoLog(shader, sizeof(eLog), nullptr, eLog);
printf("Error linking program: '%s'\n", eLog);
return;
}
glValidateProgram(shader);
glGetProgramiv(shader, GL_VALIDATE_STATUS, &result);
if (!result) {
glGetProgramInfoLog(shader, sizeof(eLog), nullptr, eLog);
printf("Error validating program: '%s'\n", eLog);
return;
}
uModel = glGetUniformLocation(shader, "model");
uProjection = glGetUniformLocation(shader, "projection");
}
void createTriangle() {
void makeEntities() {
unsigned int indices[] {
0, 3, 1,
1, 3, 2,
@ -148,90 +41,37 @@ void createTriangle() {
Mesh* mesh = new Mesh();
mesh->create(vertices, indices, (sizeof(vertices)/sizeof(*vertices)), (sizeof(indices)/sizeof(*indices)));
auto tri = new Entity();
tri->create(mesh);
tri->setPosition(glm::vec3(0, 0, -2.5f));
tri->setScale(0.4);
for (auto y = -1; y < 1; y++) {
for (auto i = -1; i < 2; i++) {
for (auto j = -4; j < -2; j++) {
triangle = tri;
auto *tri = new Entity();
tri->create(mesh);
tri->setPosition(glm::vec3(i, y + 0.25, j));
tri->setScale(0.3);
entities.push_back(triangle);
auto tri2 = new Entity();
tri2->create(mesh);
tri2->setPosition(glm::vec3(1, -0.5, -2.5f));
tri2->setScale(0.4);
entities.push_back(tri2);
auto tri3 = new Entity();
tri3->create(mesh);
tri3->setPosition(glm::vec3(-0.5, 0.5, -2.5f));
tri3->setScale(0.4);
entities.push_back(tri3);
entities.push_back(tri);
}
}
}
}
int main() {
//Initialize GLFW
if (!glfwInit()) {
printf("GLFW init failed");
glfwTerminate();
return 1;
}
//Window
mainWindow = Window(800, 600);
mainWindow.initialize();
//Set up GLFW window properties
//Create entities
makeEntities();
//Version 3.2
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//Create shader
shader = new Shader();
shader->createFromFile("../GlProject/Shaders/world.vs", "../GlProject/Shaders/world.fs");
//Compatibility - No Backwards compat, only forwards
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
//Create the window
GLFWwindow *window = glfwCreateWindow(width, height, "OpenGL Learning", nullptr, nullptr);
if (!window) {
printf("GLFW window failed");
glfwTerminate();
return 1;
}
//Get buffer size information (inner window array size)
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(window, &bufferWidth, &bufferHeight);
//Set context for GLEW to our window
glfwMakeContextCurrent(window);
//Allow modern extension features
glewExperimental = GL_TRUE;
//Initialize GLEW
GLenum error;
if ((error = glewInit()) != GLEW_OK) {
printf("GLEW init failed.");
fprintf(stderr, "Error: %s\n", glewGetErrorString(error));
glfwDestroyWindow(window);
glfwTerminate();
return 1;
}
//Setup viewport (draw) size
glViewport(0, 0, bufferWidth, bufferHeight);
glEnable(GL_DEPTH_TEST);
//Create triangle
createTriangle();
compileShaders();
glm::mat4 projectionMatrix = glm::perspective(45.0f, (GLfloat)bufferWidth / (GLfloat)bufferHeight, 0.1f, 100.0f);
glm::mat4 projectionMatrix = glm::perspective(45.0f, mainWindow.getBufferWidth() / mainWindow.getBufferHeight(), 0.1f, 100.0f);
//Game Loop
while (!glfwWindowShouldClose(window)) {
while (!mainWindow.getShouldClose()) {
//Get & Handle Input
glfwPollEvents();
@ -244,41 +84,28 @@ int main() {
if (std::abs(triOffset) >= triMaxOffset) triDirection = !triDirection;
triAngle += triAngleStep;
if (triAngle >= 360) {
triAngle -= 360;
}
if (triScaleDir /*Increasing*/) {
triScaleCur += triScaleStep;
}
else /*Decreasing*/ {
triScaleCur -= triScaleStep;
}
if (triScaleCur > triScaleMax || triScaleCur < triScaleMin) triScaleDir = !triScaleDir;
// triangle->setScale(triScaleCur);
triangle->setPosition(glm::vec3(triOffset, 0, -2.5f));
triangle->setScale(glm::vec3(0.4, 0.4, 1));
// triangle->setPosition(glm::vec3(triOffset, 0, -2.5f));
// triangle->setScale(glm::vec3(0.4, 0.4, 1));
//Clear Window
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader);
shader->useShader();
glUniformMatrix4fv(uProjection, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glUniformMatrix4fv(shader->getProjectionLocation(), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
for (auto &entity : entities) {
glUniformMatrix4fv(uModel, 1, GL_FALSE, glm::value_ptr(entity->getModelMatrix()));
glUniformMatrix4fv(shader->getModelLocation(), 1, GL_FALSE, glm::value_ptr(entity->getModelMatrix()));
entity->getPosition()->x += triMoveStep * (triDirection ? 1 : -1);
entity->draw();
}
glUseProgram(0);
Shader::clearShader();
//Finish Drawing - Swap buffers
glfwSwapBuffers(window);
mainWindow.swapBuffers();
}
return 0;

131
GlProject/Shader.cpp Normal file
View File

@ -0,0 +1,131 @@
//
// Created by aurailus on 26/11/18.
//
#include <cstring>
#include "Shader.h"
Shader::Shader() {
shaderID = 0;
uModel = 0;
uProj = 0;
}
void Shader::createFromString(const char *vertexSource, const char *fragmentSource) {
compileShader(vertexSource, fragmentSource);
}
void Shader::createFromFile(const char *vertexFile, const char *fragmentFile) {
std::string vertexSource = readFile(vertexFile);
std::string fragmentSource = readFile(fragmentFile);
compileShader(vertexSource.c_str(), fragmentSource.c_str());
}
std::string Shader::readFile(const char* fileLocation) {
std::string contents;
std::ifstream fileStream(fileLocation, std::ios::in);
if (!fileStream.is_open()) {
printf("Failed to open shader file! %s", fileLocation);
return "";
}
std::string line = "";
while (!fileStream.eof()) {
std::getline(fileStream, line);
contents.append(line + "\n");
}
fileStream.close();
return contents;
}
void Shader::compileShader(const char *vertexSource, const char *fragmentSource) {
shaderID = glCreateProgram();
if (!shaderID) {
printf("Error creating the shader program.");
return;
}
addShader(shaderID, vertexSource, GL_VERTEX_SHADER);
addShader(shaderID, fragmentSource, GL_FRAGMENT_SHADER);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glLinkProgram(shaderID);
glGetProgramiv(shaderID, GL_LINK_STATUS, &result);
if (!result) {
glGetProgramInfoLog(shaderID, sizeof(eLog), nullptr, eLog);
printf("Error linking program: '%s'\n", eLog);
return;
}
glValidateProgram(shaderID);
glGetProgramiv(shaderID, GL_VALIDATE_STATUS, &result);
if (!result) {
glGetProgramInfoLog(shaderID, sizeof(eLog), nullptr, eLog);
printf("Error validating program: '%s'\n", eLog);
return;
}
uModel = glGetUniformLocation(shaderID, "model");
uProj = glGetUniformLocation(shaderID, "projection");
}
void Shader::useShader() {
glUseProgram(shaderID);
}
GLint Shader::getModelLocation() {
return uModel;
}
GLint Shader::getProjectionLocation() {
return uProj;
}
void Shader::cleanup() {
if (shaderID != 0) {
glDeleteProgram(shaderID);
}
uModel = 0;
uProj = 0;
}
void Shader::addShader(GLuint program, const char *shaderCode, GLenum shaderType) {
GLuint shader = glCreateShader(shaderType);
const GLchar* code;
code = shaderCode;
GLint codeLength;
codeLength = static_cast<GLint>(strlen(shaderCode));
glShaderSource(shader, 1, &code, &codeLength);
glCompileShader(shader);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
if (!result) {
const char* shaderTypeString = (shaderType == GL_VERTEX_SHADER) ? "vertex" : "fragment";
glGetShaderInfoLog(shader, sizeof(eLog), nullptr, eLog);
printf("Error compiling the %s shader:\n'%s'\n", shaderTypeString, eLog);
return;
}
glAttachShader(program, shader);
}
Shader::~Shader() {
cleanup();
}

45
GlProject/Shader.h Normal file
View File

@ -0,0 +1,45 @@
//
// Created by aurailus on 26/11/18.
//
#ifndef GLPROJECT_SHADER_H
#define GLPROJECT_SHADER_H
#include <stdio.h>
#include <string>
#include <iostream>
#include <fstream>
#include <GL/glew.h>
class Shader {
public:
Shader();
void createFromString(const char* vertexSource, const char* fragmentSource);
void createFromFile(const char* vertexFile, const char* fragmentFile);
std::string readFile(const char* fileLocation);
GLint getProjectionLocation();
GLint getModelLocation();
void useShader();
static void clearShader() {
glUseProgram(0);
}
void cleanup();
~Shader();
private:
GLuint shaderID;
GLint uProj, uModel;
void compileShader(const char* vertexSource, const char* fragmentSource);
void addShader(GLuint program, const char* shaderCode, GLenum shaderType);
};
#endif //GLPROJECT_SHADER_H

View File

@ -0,0 +1,8 @@
#version 330
in vec4 color;
out vec4 fragColor;
void main() {
fragColor = color;
}

View File

@ -0,0 +1,13 @@
#version 330
layout (location = 0) in vec3 pos;
uniform mat4 model;
uniform mat4 projection;
out vec4 color;
void main() {
gl_Position = projection * model * vec4(pos, 1.0);
color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
}

75
GlProject/Window.cpp Normal file
View File

@ -0,0 +1,75 @@
//
// Created by aurailus on 26/11/18.
//
#include "Window.h"
Window::Window() {
width = 800;
height = 600;
}
Window::Window(GLint windowWidth, GLint windowHeight) {
width = windowWidth;
height = windowHeight;
}
int Window::initialize() {
//Initialize GLFW
if (!glfwInit()) {
printf("GLFW init failed");
glfwTerminate();
return 1;
}
//Version 3.2
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//Compatibility - No Backwards compat, only forwards
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
//MSAA
glfwWindowHint(GLFW_SAMPLES, 16);
glEnable(GL_MULTISAMPLE);
//Create the window
mainWindow = glfwCreateWindow(width, height, "OpenGL Learning", nullptr, nullptr);
if (!mainWindow) {
printf("GLFW window failed");
glfwTerminate();
return 1;
}
glfwGetFramebufferSize(mainWindow, &bufferWidth, &bufferHeight);
//Set context for GLEW to our window
glfwMakeContextCurrent(mainWindow);
//Allow modern extension features
glewExperimental = GL_TRUE;
//Initialize GLEW
GLenum error;
if ((error = glewInit()) != GLEW_OK) {
printf("GLEW init failed.");
fprintf(stderr, "Error: %s\n", glewGetErrorString(error));
glfwDestroyWindow(mainWindow);
glfwTerminate();
return 1;
}
//Setup viewport (draw) size
glViewport(0, 0, bufferWidth, bufferHeight);
glEnable(GL_DEPTH_TEST);
return 0;
}
Window::~Window() {
glfwDestroyWindow(mainWindow);
glfwTerminate();
}

36
GlProject/Window.h Normal file
View File

@ -0,0 +1,36 @@
//
// Created by aurailus on 26/11/18.
//
#ifndef GLPROJECT_WINDOW_H
#define GLPROJECT_WINDOW_H
#include <stdio.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
class Window {
public:
Window();
Window(GLint windowWidth, GLint windowHeight);
int initialize();
GLfloat getBufferWidth() { return bufferWidth; }
GLfloat getBufferHeight() { return bufferHeight; }
bool getShouldClose() { return (bool)glfwWindowShouldClose(mainWindow); }
void swapBuffers() { glfwSwapBuffers(mainWindow); }
~Window();
private:
GLFWwindow *mainWindow;
GLint width, height;
GLint bufferWidth, bufferHeight;
};
#endif //GLPROJECT_WINDOW_H

Binary file not shown.