Mesh Class, Entity Class, Render loop that allows for multiple entities to be rendered at once.

master
aurailus 2018-11-26 11:41:02 -08:00
commit 22224ee367
7 changed files with 507 additions and 0 deletions

21
CMakeLists.txt Normal file
View File

@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.12)
project(GlProject)
set(CMAKE_CXX_STANDARD 14)
include_directories(GlProject/Libraries/glew/include/GL)
include_directories(GlProject/Libraries/glfw_linux/include)
include_directories(GlProject/Libraries/glm)
find_package(OpenGL REQUIRED)
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)
target_link_libraries(GlProject
${OPENGL_gl_LIBRARY}
glfw
libGLEW.so)

58
GlProject/Entity.cpp Normal file
View File

@ -0,0 +1,58 @@
//
// Created by aurailus on 25/11/18.
//
#include <iostream>
#include "Entity.h"
Entity::Entity() {
position = glm::vec3(0, 0, 0);
rotation = glm::vec3(0, 0, 0);
scale = glm::vec3(1, 1, 1);
}
void Entity::create(Mesh* myMesh) {
this->mesh = myMesh;
}
void Entity::draw() {
mesh->draw();
}
void Entity::cleanup() {
this->mesh->cleanup();
}
void Entity::setPosition(glm::vec3 position) {
this->position = position;
}
glm::vec3* Entity::getPosition() {
return &position;
}
void Entity::setScale(float scale) {
setScale(glm::vec3(scale, scale, scale));
}
void Entity::setScale(glm::vec3 scale) {
this->scale = scale;
}
glm::vec3* Entity::getScale() {
return &scale;
}
glm::mat4 Entity::getModelMatrix() {
glm::mat4 model = glm::mat4(1.0);
model = glm::translate(model, position);
// model = glm::rotate(model, triAngle * toRadians, glm::vec3(0.0f, 1.0f, 0.0f));
model = glm::scale(model, scale);
return model;
}
Entity::~Entity() {
cleanup();
};

43
GlProject/Entity.h Normal file
View File

@ -0,0 +1,43 @@
//
// Created by aurailus on 25/11/18.
//
#ifndef GLPROJECT_ENTITY_H
#define GLPROJECT_ENTITY_H
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include "Mesh.h"
class Entity {
public:
Entity();
void create(Mesh* mesh);
void draw();
void cleanup();
void setPosition(glm::vec3 position);
glm::vec3* getPosition();
//void setRotation(glm::vec3 rotation);
//glm::vec3* getRotation();
void setScale(float scale);
void setScale(glm::vec3 scale);
glm::vec3* getScale();
glm::mat4 getModelMatrix();
~Entity();
private:
Mesh* mesh;
glm::vec3 position;
glm::vec3 rotation;
glm::vec3 scale;
};
#endif //GLPROJECT_ENTITY_H

285
GlProject/Main.cpp Normal file
View File

@ -0,0 +1,285 @@
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <glew.h>
#include <glfw3.h>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
#include "Mesh.h"
#include "Entity.h"
//Window dimensions
const GLint width = 800;
const GLint height = 600;
std::vector<Entity*> entities;
Entity* triangle;
//Conversion therapy
const float toRadians = 3.14159265f / 180.0f;
GLuint shader;
GLint uModel, uProjection;
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() {
unsigned int indices[] {
0, 3, 1,
1, 3, 2,
2, 3, 0,
0, 1, 2
};
GLfloat vertices[] = {
-1.0f, -1.0f, -0.5f,
0.0f, -1.0f, 1.0f,
1.0f, -1.0f, -0.5f,
0.0f, 1.0f, 0.0f
};
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);
triangle = tri;
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);
}
int main() {
//Initialize GLFW
if (!glfwInit()) {
printf("GLFW init failed");
glfwTerminate();
return 1;
}
//Set up GLFW window properties
//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);
//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);
//Game Loop
while (!glfwWindowShouldClose(window)) {
//Get & Handle Input
glfwPollEvents();
if (triDirection /*Right*/) {
triOffset += triMoveStep;
}
else /*Left*/ {
triOffset -= triMoveStep;
}
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));
//Clear Window
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader);
glUniformMatrix4fv(uProjection, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
for (auto &entity : entities) {
glUniformMatrix4fv(uModel, 1, GL_FALSE, glm::value_ptr(entity->getModelMatrix()));
entity->draw();
}
glUseProgram(0);
//Finish Drawing - Swap buffers
glfwSwapBuffers(window);
}
return 0;
}

74
GlProject/Mesh.cpp Normal file
View File

@ -0,0 +1,74 @@
//
// Created by aurailus on 25/11/18.
//
#include "Mesh.h"
#include <iostream>
Mesh::Mesh() {
VAO = 0;
VBO = 0;
IBO = 0;
indCount = 0;
}
void Mesh::create(GLfloat *vertices, unsigned int *indices, unsigned int vertCount, unsigned int indCount) {
this->indCount = indCount;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
//Have to multiply by indCount because indices is a pointer to *one* number, not the entire array.
//Could also be sizeof(unsigned int) * indCount
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indCount, indices, GL_STATIC_DRAW);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertCount, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void Mesh::draw() {
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glDrawElements(GL_TRIANGLES, indCount, GL_UNSIGNED_INT, nullptr);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void Mesh::cleanup() {
if (IBO != 0) {
glDeleteBuffers(1, &IBO);
IBO = 0;
}
if (VBO != 0) {
glDeleteBuffers(1, &VBO);
VBO = 0;
}
if (VAO != 0) {
glDeleteVertexArrays(1, &VAO);
VAO = 0;
}
indCount = 0;
}
Mesh::~Mesh() {
cleanup();
}

26
GlProject/Mesh.h Normal file
View File

@ -0,0 +1,26 @@
//
// Created by aurailus on 25/11/18.
//
#ifndef GLPROJECT_MESH_H
#define GLPROJECT_MESH_H
#include <GL/glew.h>
class Mesh {
public:
Mesh();
void create(GLfloat *vertices, unsigned int *indices, unsigned int vertCount, unsigned int indCount);
void draw();
void cleanup();
~Mesh();
private:
GLuint VAO, VBO, IBO;
GLsizei indCount;
};
#endif //GLPROJECT_MESH_H

BIN
GlProject/glew32.dll Normal file

Binary file not shown.