Rewrote VertexArray to support multiple VBOs; Minor fixes and organization

This commit is contained in:
Grayson Riffe (Desktop) 2021-08-24 01:26:10 -05:00
parent f75f98d9db
commit e17d2e283a
18 changed files with 129 additions and 86 deletions

View File

@ -94,7 +94,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NFENGINE;GLEW_STATIC;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)src\include\;$(ProjectDir)dep\include\</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)obj\</ObjectFileName>
@ -119,7 +119,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NFENGINE;GLEW_STATIC;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)src\include\;$(ProjectDir)dep\include\</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)obj\</ObjectFileName>
@ -144,7 +144,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NFENGINE;GLEW_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)src\include\;$(ProjectDir)dep\include\</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)obj\</ObjectFileName>
@ -169,7 +169,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NFENGINE;GLEW_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)src\include\;$(ProjectDir)dep\include\</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)obj\</ObjectFileName>

View File

@ -1,8 +1,10 @@
#include "Application.h"
#ifdef NFENGINE
#include <thread>
#include "GL\glew.h"
#include "GL\wglew.h"
#endif
#include "Utility.h"
namespace nf {
DEBUGINIT;
@ -41,7 +43,7 @@ namespace nf {
m_states[stateName] = state;
}
else {
Error(("State \"" + (std::string)stateName + (std::string)"\" already exists!").c_str());
Error("State \"" + (std::string)stateName + (std::string)"\" already exists!");
}
}
@ -52,7 +54,7 @@ namespace nf {
m_defaultStateAdded = true;
}
else {
Error(("State \"" + (std::string)stateName + (std::string)"\" doesn't exist!").c_str());
Error("State \"" + (std::string)stateName + (std::string)"\" doesn't exist!");
}
}
else {
@ -93,7 +95,7 @@ namespace nf {
m_currentState->onEnter(this);
}
else {
Error(("State \"" + (std::string)stateName + (std::string)"\" doesn't exist!").c_str());
Error("State \"" + (std::string)stateName + (std::string)"\" doesn't exist!");
}
}
@ -157,6 +159,7 @@ namespace nf {
m_frames = 0;
Log("FPS: " + std::to_string(m_FPS));
m_fpsClock1 = std::chrono::steady_clock::now();
//TODO: Rework calculating FPS
}
std::this_thread::sleep_until(next_time);
m_deltaTime = (double)(std::chrono::steady_clock::now() - start_time).count();

View File

@ -1,5 +1,7 @@
#include "IntroGamestate.h"
#include "Application.h"
#include "Utility.h"
namespace nf {
void IntroGamestate::onEnter(Application* app) {

View File

@ -1,5 +1,7 @@
#include "IndexBuffer.h"
#include "GL/glew.h"
namespace nf {
IndexBuffer::IndexBuffer(const void* data, size_t count) {
m_count = count;

View File

@ -1,6 +1,10 @@
#include "Renderer.h"
#include "GL/glew.h"
#include "GL\wglew.h"
#include "Application.h"
#include "Utility.h"
namespace nf {
Renderer::Renderer(Application* app) {
@ -54,7 +58,7 @@ namespace nf {
GLenum err = glGetError();
if (err != GL_NO_ERROR) {
Error(("OpenGL error " + std::to_string(err)).c_str());
Error("OpenGL error " + std::to_string(err));
}
}

View File

@ -1,5 +1,9 @@
#include "Shader.h"
#include "GL/glew.h"
#include "Utility.h"
namespace nf {
Shader::Shader(const char* vertexSource, const char* fragmentSource) {
m_id = glCreateProgram();
@ -19,7 +23,7 @@ namespace nf {
char* message = new char[length];
glGetShaderInfoLog(curr, length, &length, message);
message[length - 2] = 0;
Error(("OpenGL Error: " + (std::string)message).c_str());
Error("OpenGL Error: " + (std::string)message);
}
}
glAttachShader(m_id, vs);
@ -33,7 +37,7 @@ namespace nf {
glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &length);
char* message = new char[length];
glGetProgramInfoLog(m_id, length, &length, message);
Error(("OpenGL Error: " + (std::string)message).c_str());
Error("OpenGL Error: " + (std::string)message);
}
glDeleteShader(vs);
glDeleteShader(fs);
@ -42,6 +46,14 @@ namespace nf {
void Shader::bind() {
glUseProgram(m_id);
}
//TODO: Create overloaded setUniform function
void Shader::getUniformLocation(const char* uniformName) {
unsigned int loc = glGetUniformLocation(m_id, uniformName);
if (loc == -1) {
Error("Uniform \"" + (std::string)uniformName + "\" does not exist!");
}
m_uniformLocations[uniformName] = loc;
}
Shader::~Shader() {
glDeleteProgram(m_id);

View File

@ -1,50 +1,63 @@
#include "VertexArray.h"
#include "GL/glew.h"
#include "Utility.h"
namespace nf {
unsigned int VertexBufferElement::getSizeOfType(unsigned int type) {
switch (type)
{
case GL_FLOAT:
return sizeof(type);
default:
return 0;
}
}
VertexArray::VertexArray(const void* bufferData, size_t bufferSize) :
m_id(0),
m_vb(bufferData, bufferSize),
m_hasLayout(false),
m_vertexStride(0)
{
VertexArray::VertexArray() {
glGenVertexArrays(1, &m_id);
glBindVertexArray(m_id);
m_lastBufferHasLayout = true;
m_attribute = 0;
m_lastStride = 0;
}
void VertexArray::bind() {
glBindVertexArray(m_id);
m_vb.bind();
if (!m_hasLayout && m_vertexStride > 0) {
unsigned int offset = 0;
for (unsigned int i = 0; i < m_layoutElements.size(); i++) {
const VertexBufferElement& element = m_layoutElements[i];
glEnableVertexAttribArray(i);
glVertexAttribPointer(i, element.count, element.type, element.normalized, m_vertexStride, (const void*)offset);
offset += element.count * VertexBufferElement::getSizeOfType(element.type);
}
m_hasLayout = true;
}
else if(!m_hasLayout) {
Error("No layout specified for vertex buffer!");
void VertexArray::addBuffer(const void* data, const size_t size) {
if (!m_lastBufferHasLayout) {
Error("Buffer added to vertex array has no layout!");
}
m_buffers.push_back(new VertexBuffer(data, size));
m_buffers.back()->bind();
m_lastBufferHasLayout = false;
m_lastStride = 0;
}
template<>
void VertexArray::push<float>(unsigned int count) {
m_layoutElements.push_back({ GL_FLOAT, count, GL_FALSE });
m_vertexStride += VertexBufferElement::getSizeOfType(GL_FLOAT) * count;
if (m_lastBufferHasLayout) {
Error("Tried to modify a vertex array's buffer after the layout was final!");
}
m_lastBufferLayout.push_back({ GL_FLOAT, count, GL_FALSE });
m_lastStride += count * sizeof(GL_FLOAT);
}
void VertexArray::finishBufferLayout() {
unsigned int offset = 0;
for (; m_attribute < m_lastBufferLayout.size(); m_attribute++) {
const VertexBufferElement& curr = m_lastBufferLayout[m_attribute];
glEnableVertexAttribArray(m_attribute);
glVertexAttribPointer(m_attribute, curr.count, curr.type, curr.normalized, m_lastStride, (const void*)offset);
offset += sizeof(curr.type) * curr.count;
}
m_lastBufferHasLayout = true;
m_lastStride = 0;
}
void VertexArray::bind(unsigned int buffer) {
if (m_buffers.empty()) {
Error("No buffers and layouts added to vertex array before being bound!");
}
if (!m_lastBufferHasLayout) {
Error("Buffer added to vertex array has no layout!");
}
glBindVertexArray(m_id);
}
VertexArray::~VertexArray() {
for (VertexBuffer* curr : m_buffers) {
delete curr;
}
glDeleteVertexArrays(1, &m_id);
}
}

View File

@ -1,5 +1,9 @@
#include "VertexBuffer.h"
#include "GL/glew.h"
#include "Utility.h"
namespace nf {
VertexBuffer::VertexBuffer(const void* data, const size_t size) {
glGenBuffers(1, &m_id);

View File

@ -1,6 +1,10 @@
#include "Utility.h"
#include <thread>
#include <iostream>
#include <sstream>
#include <fstream>
#include <Windows.h>
#include "Utility.h"
#include "Config.h"
namespace nf {
@ -35,6 +39,16 @@ namespace nf {
CloseHandle(cmd);
}
void Debug::ErrorImp(const std::string& in, const char* filename, int line) {
std::chrono::duration<float> time = getCurrentTime();
HANDLE cmd = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(cmd, FOREGROUND_RED);
std::printf("[%.4f] Error (%s, %i): ", time.count(), filename, line);
std::cout << in << "\n";
SetConsoleTextAttribute(cmd, 7);
CloseHandle(cmd);
}
std::chrono::duration<float> Debug::getCurrentTime() {
std::chrono::steady_clock::time_point now = std::chrono::high_resolution_clock::now();
return now - m_initTime;
@ -47,6 +61,13 @@ namespace nf {
MultiByteToWideChar(CP_ACP, NULL, in, -1, out, length);
return out;
}
const wchar_t* toWide(const std::string& in) {
const char* cstr = in.c_str();
int length = std::strlen(cstr) + 1;
wchar_t* out = new wchar_t[length];
MultiByteToWideChar(CP_ACP, NULL, cstr, -1, out, length);
return out;
}
//TODO: File encryption
bool writeFile(const char* filename, const std::string& in) {
std::string file(filename);
@ -65,7 +86,7 @@ namespace nf {
std::ofstream out;
out.open(filename);
if (!out) {
Error(("File \"" + (std::string)filename + (std::string)"\" could not be written!").c_str());
Error("File \"" + (std::string)filename + (std::string)"\" could not be written!");
return false;
}
out << in;
@ -77,7 +98,7 @@ namespace nf {
std::ifstream in;
in.open(filename);
if (!in) {
Error(("File \"" + (std::string)filename + (std::string)"\" could not be read!").c_str());
Error("File \"" + (std::string)filename + (std::string)"\" could not be read!");
return NULL;
}
std::stringstream ss;

View File

@ -1,15 +1,11 @@
#pragma once
#include <Windows.h>
#include <chrono>
#include <unordered_map>
#include <vector>
#include <Windows.h>
#include "Config.h"
#include "Utility.h"
#include "IntroGamestate.h"
#include "Renderer.h"
//TODO: Check #include consistency
//TODO: Separate #includes between headers and implementations
//TODO: Document ALL frontend functions
namespace nf {

View File

@ -1,5 +1,4 @@
#pragma once
#include "GL/glew.h"
namespace nf {
class IndexBuffer {

View File

@ -1,6 +1,5 @@
#pragma once
#include "IGamestate.h"
#include "Utility.h"
namespace nf {
class IntroGamestate : public IGamestate {
@ -12,5 +11,6 @@ namespace nf {
void render() override;
private:
int counter;
//TODO: Flesh out intro gamestate
};
}

View File

@ -1,6 +1,7 @@
//Master engine include (Is this even useful?)
//TODO: Rework this file to only contain functions the frontend will need to access
#include "Application.h"
#include "Input.h"
#include "Utility.h"
using namespace nf;

View File

@ -1,8 +1,5 @@
#pragma once
#ifdef NFENGINE
#include "GL/glew.h"
#include "GL\wglew.h"
#endif
#include <Windows.h>
namespace nf {
class Application;

View File

@ -1,9 +1,5 @@
#pragma once
#ifdef NFENGINE
#include "GL/glew.h"
#endif
#include "Utility.h"
#include <unordered_map>
namespace nf {
class Shader {
@ -11,10 +7,12 @@ namespace nf {
Shader(const char* vertexSource, const char* fragmentSource);
void bind();
void getUniformLocation(const char* uniformName);
~Shader();
private:
unsigned int m_id;
//Associated resource?
std::unordered_map<const char*, unsigned int> m_uniformLocations;
//TODO: Load from resource
};
}

View File

@ -1,11 +1,6 @@
#pragma once
#include <chrono>
#include <thread>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <Windows.h>
namespace nf {
#ifdef _DEBUG
@ -33,6 +28,7 @@ __debugbreak();
static void LogImp(int in);
static void LogImp(double in);
static void ErrorImp(const char* in, const char* filename, int line);
static void ErrorImp(const std::string& in, const char* filename, int line);
};
#else
#define DEBUGINIT
@ -42,6 +38,7 @@ std::exit(-1)
#endif
const wchar_t* toWide(const char* in);
const wchar_t* toWide(const std::string& in);
bool writeFile(const char* filename, const std::string& in);
std::string readFile(const char* filename);
}

View File

@ -1,35 +1,32 @@
#pragma once
#ifdef NFENGINE
#include "GL/glew.h"
#endif
#include <vector>
#include "VertexBuffer.h"
#include "Utility.h"
namespace nf {
struct VertexBufferElement {
unsigned int type;
unsigned int count;
unsigned char normalized;
static unsigned int getSizeOfType(unsigned int type);
};
class VertexArray {
public:
VertexArray(const void* bufferData, size_t bufferSize);
VertexArray();
void bind();
void addBuffer(const void* data, const size_t size);
template<typename T>
void push(unsigned int count);
void finishBufferLayout();
void bind(unsigned int buffer = 1);
~VertexArray();
private:
unsigned int m_id;
VertexBuffer m_vb;
bool m_hasLayout;
std::vector<VertexBufferElement> m_layoutElements;
unsigned int m_vertexStride;
bool m_lastBufferHasLayout;
std::vector<VertexBuffer*> m_buffers;
std::vector<VertexBufferElement> m_lastBufferLayout;
unsigned int m_attribute;
unsigned int m_lastStride;
};
}

View File

@ -1,7 +1,4 @@
#pragma once
#ifdef NFENGINE
#include "GL/glew.h"
#endif
namespace nf {
class VertexBuffer {