Added basic shading and support for up to 100 lights of any color; By default now, states with no lights are dark

This commit is contained in:
grayson committed 2021-09-04 15:51:03 -05:00
1 parent dff0d86558
commit 5c10fdc1a4
35 files changed
+4037 -2664

No files matched your search

+12 -7
View File
@@ -8,7 +8,7 @@
namespace nf {
Camera::Camera(Application* app) :
m_app(app),
m_type(Type::NF_CAMERA_UI),
m_type(Type::UI),
m_position(0.0),
m_front(0.0, 0.0, -1.0),
m_yaw(-90.0f),
@@ -20,7 +20,7 @@ namespace nf {
void Camera::setType(Type cameraType) {
if (cameraType != m_type) {
m_type = cameraType;
if (m_type == Type::NF_CAMERA_FIRST_PERSON || m_type == Type::NF_CAMERA_ORBIT)
if (m_type == Type::FIRST_PERSON || m_type == Type::ORBIT)
m_app->trackMouse(true);
else
m_app->trackMouse(false);
@@ -63,15 +63,19 @@ namespace nf {
m_position = position;
}
const Vec3& Camera::getPosition() {
return m_position;
}
void Camera::bind(Shader* shader) {
glm::mat4 view;
switch (m_type) {
case Type::NF_CAMERA_UI: {
case Type::UI: {
view = glm::mat4(1.0);
break;
}
case Type::NF_CAMERA_FIRST_PERSON: {
case Type::FIRST_PERSON: {
int mouseDiffx = 0;
int mouseDiffy = 0;
m_app->getMouseDiff(mouseDiffx, mouseDiffy);
@@ -94,16 +98,17 @@ namespace nf {
view = glm::lookAt(position, position + rotation, up);
break;
}
case Type::NF_CAMERA_ORBIT: {
case Type::ORBIT: {
break;
}
case Type::NF_CAMERA_FIXED: {
case Type::FIXED: {
break;
}
}
glm::vec3 pos(m_position.x, m_position.y, m_position.z);
shader->setUniform("camera.pos", pos);
shader->setUniform("view", view);
}
+3 -2
View File
@@ -29,8 +29,9 @@ namespace nf {
std::vector<unsigned int> ib;
size_t ibCount = 0;
std::vector<float> tc;
parseOBJ(obj, vb, ib, ibCount, tc);
m_model->create(&vb[0], vb.size() * sizeof(float), &ib[0], ibCount, &tc[0], tc.size() * sizeof(float), &texture);
std::vector<float> vn;
parseOBJ(obj, vb, ib, ibCount, tc, vn);
m_model->create(&vb[0], vb.size() * sizeof(float), &ib[0], ibCount, &vn[0], vn.size() * sizeof(float), &tc[0], tc.size() * sizeof(float), &texture);
model.alreadyLoaded = true;
model.loadedModel = m_model;
}
@@ -0,0 +1,87 @@
#include "Light.h"
#include "Shader.h"
namespace nf {
Light::Light() :
m_type(Type::POINT),
m_constructed(false),
m_strength(1.0f)
{
}
void Light::create(const Vec3& position, const Vec3& color, Type type, float strength) {
m_constructed = true;
m_position = position;
m_color = color;
m_type = type;
m_strength = strength;
}
bool Light::isConstructed() {
return m_constructed;
}
void Light::setPosition(const Vec3& position) {
m_position = position;
}
void Light::setColor(const Vec3& color) {
m_color = color;
}
void Light::bind(Shader* shader, unsigned int lightNumber) {
glm::vec3 pos(m_position.x, m_position.y, m_position.z);
glm::vec3 color(m_color.x, m_color.y, m_color.z);
std::string stringPos = "light[";
std::string stringLocation = std::to_string(lightNumber);
stringPos += stringLocation;
stringPos += "].";
std::string lightPos = stringPos + (std::string)"pos";
std::string lightColor = stringPos + (std::string)"color";
shader->setUniform(lightPos, pos);
shader->setUniform(lightColor, color);
//switch (m_type) {
// case Type::DIRECTIONAL: {
// shader->setUniform(lightType.c_str(), 1);
// std::string lightConsant = light + (std::string)"falloffConstant";
// std::string lightLinear = light + (std::string)"falloffLinear";
// std::string lightQuad = light + (std::string)"falloffQuad";
// shader->setUniform(lightConsant.c_str(), 1.0f);
// shader->setUniform(lightLinear.c_str(), 0.7f);
// shader->setUniform(lightQuad.c_str(), 1.8f);
// break;
// }
// case Type::POINT: {
// //shader->setUniform(lightType.c_str(), 2);
// break;
// }
// case Type::SPOTLIGHT: {
// shader->setUniform(lightType.c_str(), 3);
// break;
// }
//}
}
Light::Type Light::getType() {
return m_type;
}
const Vec3& Light::getPosition() {
return m_position;
}
const Vec3& Light::getColor() {
return m_color;
}
const float Light::getStrength() {
return m_strength;
}
Light::~Light() {
}
}
+4 -1
View File
@@ -13,7 +13,7 @@ namespace nf {
}
void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, ATexture* texture) {
void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* normalsBufferData, size_t normalsBufferSize, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, ATexture* texture) {
m_vao = new VertexArray;
m_vao->addBuffer(vertexBufferData, vertexBufferSize);
m_vao->push<float>(3);
@@ -21,6 +21,9 @@ namespace nf {
m_vao->addBuffer(textureCoordinatesBufferData, textureCoordinatesBufferSize);
m_vao->push<float>(2);
m_vao->finishBufferLayout();
m_vao->addBuffer(normalsBufferData, normalsBufferSize);
m_vao->push<float>(3);
m_vao->finishBufferLayout();
if (texture->alreadyLoaded) {
m_texture = texture->loadedTexture;
}
@@ -13,6 +13,7 @@ namespace nf {
}
void Text::create(const std::string& string, const Vec2& position, const Vec3& color, unsigned int size, Asset* font) {
m_constructed = true;
m_string = string;
m_position = position;
m_color = color;
@@ -24,6 +24,10 @@ namespace nf {
m_centeredY = y;
}
bool UIElement::isConstructed() {
return m_constructed;
}
void UIElement::render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight) {
}
@@ -13,6 +13,7 @@ namespace nf {
}
void UITexture::create(Asset* texture, const Vec2& position, double scale) {
m_constructed = true;
ATexture* tex = (ATexture*)texture;
m_position = position;
m_scale = (float)scale;
+37 -20
View File
@@ -6,7 +6,10 @@
#include "Application.h"
#include "Shader.h"
#include "Light.h"
#include "Entity.h"
#include "UIElement.h"
#include "Camera.h"
#include "Utility.h"
namespace nf {
@@ -56,55 +59,68 @@ namespace nf {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
baseAP.load("base.nfpack");
const char* entityVertex = baseAP["entityVertex.shader"]->data;
const char* entityFragment = baseAP["entityFragment.shader"]->data;
m_baseAP.load("base.nfpack");
const char* entityVertex = m_baseAP["entityVertex.shader"]->data;
const char* entityFragment = m_baseAP["entityFragment.shader"]->data;
m_entityShader = new Shader(entityVertex, entityFragment);
const char* textVertex = baseAP["textVertex.shader"]->data;
const char* textFragment = baseAP["textFragment.shader"]->data;
const char* textVertex = m_baseAP["textVertex.shader"]->data;
const char* textFragment = m_baseAP["textFragment.shader"]->data;
m_textShader = new Shader(textVertex, textFragment);
const char* uiTextureVertex = baseAP["uiTextureVertex.shader"]->data;
const char* uiTextureFragment = baseAP["uiTextureFragment.shader"]->data;
const char* uiTextureVertex = m_baseAP["uiTextureVertex.shader"]->data;
const char* uiTextureFragment = m_baseAP["uiTextureFragment.shader"]->data;
m_uiTextureShader = new Shader(uiTextureVertex, uiTextureFragment);
BaseAssets::cube = (AModel*)baseAP["cube.obj"];
BaseAssets::plane = (AModel*)baseAP["plane.obj"];
BaseAssets::sphere = (AModel*)baseAP["sphere.obj"];
BaseAssets::cone = (AModel*)baseAP["cone.obj"];
BaseAssets::cylinder = (AModel*)baseAP["cylinder.obj"];
BaseAssets::torus = (AModel*)baseAP["torus.obj"];
BaseAssets::defaultFont = (AFont*)baseAP["default.ttf"];
BaseAssets::cube = (AModel*)m_baseAP["cube.obj"];
BaseAssets::plane = (AModel*)m_baseAP["plane.obj"];
BaseAssets::sphere = (AModel*)m_baseAP["sphere.obj"];
BaseAssets::cone = (AModel*)m_baseAP["cone.obj"];
BaseAssets::cylinder = (AModel*)m_baseAP["cylinder.obj"];
BaseAssets::torus = (AModel*)m_baseAP["torus.obj"];
BaseAssets::defaultFont = (AFont*)m_baseAP["default.ttf"];
}
void Renderer::render(Entity& in) {
if (&in == nullptr)
if (in.getModel() == nullptr)
Error("Tried to render Entity before being created!");
m_lGame.push_back(&in);
//TODO: Sort transparent objects by distance; Farthest first
}
void Renderer::render(UIElement& in) {
if (&in == nullptr)
Error("Tried to render Entity before being created!");
if (in.isConstructed() == false)
Error("Tried to render a UI element before being created!");
m_lUI.push_back(&in);
//TODO: Sort transparent objects by distance; Farthest first
}
void Renderer::render(Light& in) {
if (in.isConstructed() == false)
Error("Tried to render a light before being created!");
m_lights.push_back(&in);
}
void Renderer::doFrame(Camera* camera) {
glViewport(0, 0, m_app->getConfig().width, m_app->getConfig().height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//Draw Entities (3D models)
glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)m_app->getConfig().width / (float)m_app->getConfig().height, 0.1f, 100000.0f);
m_entityShader->bind();
m_entityShader->setUniform("proj", proj);
for (Entity* draw : m_lGame) {
Entity& curr = *draw;
curr.bind(m_entityShader);
m_entityShader->setUniform("proj", proj);
camera->bind(m_entityShader);
//TODO: Clean this up a bit
m_entityShader->setUniform("numberOfLights", (int)m_lights.size() + 1);
for (unsigned int i = 0; i < m_lights.size(); i++) {
m_lights[i]->bind(m_entityShader, i);
}
//TODO: Bind and draw every material here
m_entityShader->setUniform("material.shininess", 1.0f);
glDrawElements(GL_TRIANGLES, curr.getModel()->getIndexCount(), GL_UNSIGNED_INT, nullptr);
}
m_lGame.clear();
m_lights.clear();
//Draw UI elements
glDisable(GL_DEPTH_TEST);
proj = glm::ortho(0.0f, (float)m_app->getConfig().width, 0.0f, (float)m_app->getConfig().height);
for (UIElement* draw : m_lUI) {
@@ -122,6 +138,7 @@ namespace nf {
}
}
m_lUI.clear();
glEnable(GL_DEPTH_TEST);
SwapBuffers(m_hdc);
+14 -4
View File
@@ -47,19 +47,29 @@ namespace nf {
glUseProgram(m_id);
}
void Shader::setUniform(const char* name, glm::mat4& data) {
void Shader::setUniform(const std::string& name, glm::mat4& data) {
if (m_uniformLocations.find(name) == m_uniformLocations.end())
getUniformLocation(name);
glUniformMatrix4fv(m_uniformLocations[name], 1, GL_FALSE, glm::value_ptr(data));
}
void Shader::setUniform(const char* name, glm::vec3& data) {
void Shader::setUniform(const std::string& name, glm::vec3& data) {
if (m_uniformLocations.find(name) == m_uniformLocations.end())
getUniformLocation(name);
glUniform3fv(m_uniformLocations[name], 1, glm::value_ptr(data));
}
void Shader::setUniform(const std::string& name, int data) {
if (m_uniformLocations.find(name) == m_uniformLocations.end())
getUniformLocation(name);
glUniform1i(m_uniformLocations[name], data);
}
void Shader::setUniform(const std::string& name, float data) {
if (m_uniformLocations.find(name) == m_uniformLocations.end())
getUniformLocation(name);
glUniform1f(m_uniformLocations[name], data);
}
void Shader::getUniformLocation(const char* uniformName) {
unsigned int loc = glGetUniformLocation(m_id, uniformName);
void Shader::getUniformLocation(const std::string& uniformName) {
unsigned int loc = glGetUniformLocation(m_id, uniformName.c_str());
if (loc == -1)
Error("Uniform \"" + (std::string)uniformName + "\" does not exist!");
m_uniformLocations[uniformName] = loc;
+1 -1
View File
@@ -20,7 +20,7 @@ namespace nf {
glBindTexture(GL_TEXTURE_2D, m_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_x, m_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
glTexImage2D(GL_TEXTURE_2D, 0, nChannels == 3 ? GL_RGB : GL_RGBA, m_x, m_y, 0, nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, texture);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(texture);
}