Start work on lighting

This commit is contained in:
Dane Johnson 2021-01-21 15:26:39 -06:00
parent 43996eb2e6
commit 8fb29d389a
24 changed files with 203 additions and 14 deletions

21
core/Light.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "Light.h"
Name Light::GetType() const {return "Light";}
Name DirectionalLight::GetType() const {return "DirectionalLight";}
DirectionalLight::DirectionalLight() {
this->direction = Vector3(0.0f);
this->color = Vector3(0.0f);
this->ambient = 0.0f;
this->diffuse = 0.0f;
this->specular = 0.0f;
}
DirectionalLight::DirectionalLight(Vector3 direction, Vector3 color, cfloat ambient, cfloat diffuse, cfloat specular) {
this->direction = direction;
this->color = color;
this->ambient = ambient;
this->diffuse = diffuse;
this->specular = specular;
}

22
core/Light.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef LIGHT_H
#define LIGHT_H
#include "types.h"
#include "Spatial.h"
class Light : public Spatial {
public:
Vector3 color;
cfloat ambient, diffuse, specular;
virtual Name GetType() const;
};
class DirectionalLight : public Light {
public:
Vector3 direction;
DirectionalLight();
DirectionalLight(Vector3 direction, Vector3 color, cfloat ambient, cfloat diffuse, cfloat specular);
virtual Name GetType() const;
};
#endif /* LIGHT_H */

View File

@ -42,4 +42,5 @@ Material::Material() {
usesColor = false;
usesTex = false;
alphaScissor = 0.0f;
unshaded = false;
}

View File

@ -27,6 +27,7 @@ struct Material {
Texture tex;
bool usesTex;
cfloat alphaScissor;
bool unshaded;
Material();
};

View File

@ -24,10 +24,12 @@ void SubMesh::SetupSubMesh() {
// Vertex positions
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) 0);
// Vertex UV
// Vertex normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(3 * sizeof(float)));
// TODO normals
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) (3 * sizeof(float)));
// Vertex UV
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) (6 * sizeof(float)));
glBindVertexArray(0);
}
@ -36,11 +38,14 @@ void SubMesh::Draw(Shader *shader) {
shader->UpdateColor(material.usesColor, material.color);
shader->UpdateTex(material.usesTex, material.tex);
shader->UpdateAlphaScissor(material.alphaScissor);
shader->UpdateUnshaded(material.unshaded);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, indices.size() * 3, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
Name Mesh::GetType() const {return "Mesh";}
Mesh::Mesh() {}
Mesh::~Mesh() {
@ -94,8 +99,11 @@ SubMesh *Mesh::aiMesh2SubMesh(aiMesh *aimesh){
SubMesh *sub = new SubMesh();
for (int i = 0; i < aimesh->mNumVertices; i++) {
aiVector3D aiPosition = aimesh->mVertices[i];
aiVector3D aiNormal = aimesh->mNormals[i];
aiVector3D aiUV = aimesh->mTextureCoords[0][i]; // TODO get ALL texture coords
Vertex vertex(aiPosition.x, aiPosition.y, aiPosition.z, aiUV.x, aiUV.y);
Vertex vertex(aiPosition.x, aiPosition.y, aiPosition.z,
aiNormal.x, aiNormal.y, aiNormal.z,
aiUV.x, aiUV.y);
sub->vertices.push_back(vertex);
}
for (int i = 0; i < aimesh->mNumFaces; i++) {

View File

@ -43,6 +43,7 @@ public:
static Mesh *FromFile(const char *filename);
virtual bool IsDrawable() const {return true;}
virtual void Draw(Shader *shader);
virtual Name GetType() const;
protected:
SubMeshList submeshes;
virtual void SetupMesh();

View File

@ -1,5 +1,7 @@
#include "Node.h"
Name Node::GetType() const {return "Node";}
Node *Node::root = {new Node()};
Node *Node::GetRoot() {
return root;

View File

@ -3,6 +3,8 @@
#include <vector>
#include "types.h"
class Node; // Forwards declare
class NodeList : public std::vector<Node*> {
public:
@ -16,6 +18,7 @@ public:
virtual bool IsDrawable() const;
virtual void Draw(){};
virtual bool IsTransformable() const;
virtual Name GetType() const;
private:
static Node *root;
};

View File

@ -23,9 +23,12 @@ Screen::Screen() {
// Vertex positions
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) 0);
//Vertex UV
// Vertex Normals
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) (3 * sizeof(float)));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) (3 * sizeof(float)));
//Vertex UV
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) (6 * sizeof(float)));
glBindVertexArray(0);

View File

@ -72,6 +72,18 @@ void Shader::UpdateTex(bool usesTex, Texture tex) {
void Shader::UpdateAlphaScissor(cfloat alphaScissor) {
glUniform1f(glGetUniformLocation(id, "material.alphaScissor"), alphaScissor);
}
void Shader::UpdateUnshaded(bool unshaded) {
glUniform1i(glGetUniformLocation(id, "material.unshaded"), (int) unshaded);
}
void Shader::UpdateDirectionalLight(DirectionalLight directionalLight) {
glUniform3fv(glGetUniformLocation(id, "directionalLight.direction"), 1, glm::value_ptr(directionalLight.direction));
glUniform3fv(glGetUniformLocation(id, "directionalLight.color"), 1, glm::value_ptr(directionalLight.color));
glUniform1f(glGetUniformLocation(id, "directionalLight.ambient"), directionalLight.ambient);
glUniform1f(glGetUniformLocation(id, "directionalLight.diffuse"), directionalLight.diffuse);
glUniform1f(glGetUniformLocation(id, "directionalLight.specular"), directionalLight.specular);
}
Name Shader::GetName() const {
return "Unnamed Shader";

View File

@ -5,6 +5,7 @@
#include "types.h"
#include "Material.h"
#include "Light.h"
class Shader {
public:
@ -20,6 +21,9 @@ public:
void UpdateTex(bool usesTex);
void UpdateTex(bool usesTex, Texture tex);
void UpdateAlphaScissor(cfloat alphaScissor);
void UpdateUnshaded(bool unshaded);
void UpdateDirectionalLight(DirectionalLight directionalLight);
virtual Name GetName() const;
};

3
core/Spatial.cpp Normal file
View File

@ -0,0 +1,3 @@
#include "Spatial.h"
Name Spatial::GetType() const {return "Spatial";}

View File

@ -8,6 +8,7 @@ class Spatial : public Node {
public:
Transform transform;
virtual bool IsTransformable() const { return true;}
virtual Name GetType() const;
};
#endif /* SPATIAL_H */

View File

@ -5,10 +5,28 @@
#include <string>
#include <stdlib.h>
#include "types.h"
#include "Node.h"
namespace Util {
void Die(const char *msg);
void Die(const char * msg, const char * more);
void Die(std::string msg);
template<class T>
T* FindNodeByType(Node *&root, const Name &type) {
if (root->GetType() == type) {
return dynamic_cast<T*>(root);
}
for (Node *child : root->children) {
T* res = FindNodeByType<T>(child, type);
if (res) {
return res;
}
}
return nullptr;
}
}
#endif /* UTIL_H */

View File

@ -4,6 +4,9 @@ Vertex::Vertex() {
x = 0.0f;
y = 0.0f;
z = 0.0f;
nx = 0.0f;
ny = 0.0f;
nz = 0.0f;
u = 0.0f;
v = 0.0f;
}
@ -12,6 +15,9 @@ Vertex::Vertex(cfloat x, cfloat y, cfloat z) {
this->x = x;
this->y = y;
this->z = z;
this->nz = 0.0f;
this->ny = 0.0f;
this->nz = 0.0f;
this->u = 0.0f;
this->v = 0.0f;
}
@ -20,6 +26,22 @@ Vertex::Vertex(cfloat x, cfloat y, cfloat z, cfloat u, cfloat v) {
this->x = x;
this->y = y;
this->z = z;
this->nx = 0.0f;
this->ny = 0.0f;
this->nz = 0.0f;
this->u = u;
this->v = v;
}
Vertex::Vertex(cfloat x, cfloat y, cfloat z,
cfloat nx, float ny, cfloat nz,
cfloat u, cfloat v) {
this->x = x;
this->y = y;
this->z = z;
this->nx = nx;
this->ny = ny;
this->nz = nz;
this->u = u;
this->v = v;
}

View File

@ -9,7 +9,11 @@ struct Vertex {
Vertex();
Vertex(cfloat x, cfloat y, cfloat z);
Vertex(cfloat x, cfloat y, cfloat z, cfloat u, cfloat v);
Vertex(cfloat x, cfloat y, cfloat z,
cfloat nx, float ny, cfloat nz,
cfloat u, cfloat v);
cfloat x, y, z;
cfloat nx, ny, nz;
cfloat u, v;
};

View File

@ -8,6 +8,8 @@
#include "types.h"
#include "Util.h"
#include "Shaders/FlatShader.h"
#include "Shaders/ScreenShader.h"
@ -17,6 +19,7 @@
#include "Input.h"
#include "Node.h"
#include "Mesh.h"
#include "Light.h"
#include "Scripting/Lua.h"
// Thirdparty Includes
@ -49,7 +52,6 @@ void render(Node *curr, Shader *shader, Matrix model) {
}
}
int main() {
int err;
@ -113,6 +115,15 @@ int main() {
view = glm::translate(view, -camera->transform.position);
shader->UpdateView(view);
// Find the lights
DirectionalLight *dirLight = Util::FindNodeByType<DirectionalLight>(root, "DirectionalLight");
if (dirLight) {
shader->UpdateDirectionalLight(*dirLight);
} else {
// No light in scene
shader->UpdateDirectionalLight(DirectionalLight());
}
// Render the scene tree
render(root, shader, Matrix(1.0f));

View File

@ -1,8 +1,8 @@
#ifndef TYPES_H
#define TYPES_H
#include <vector>
#include <string>
#include <vector>
#include <GL/glew.h>
#include <GLFW/glfw3.h>

View File

@ -17,12 +17,21 @@ local SPEED = 30
local RED = couch.Color(1.0, 0.0, 0.0)
local BLUE = couch.Color(0.0, 0.0, 1.0)
local light
function init()
local material
camera = couch.Camera()
camera:MakeCurrent()
camera.transform:Translate(0.0, 0.0, 10.0)
light = couch.DirectionalLight.new()
light.direction = couch.Vector3(0.0, 0.0, -1.0)
light.color = couch.Vector3(1.0, 1.0, 1.0)
light.ambient = 0.4
light.diffuse = 1.0
couch.Node.GetRoot().children:Append(light)
ball = couch.Mesh.FromFile("cube.glb")
material = couch.Material()
@ -101,6 +110,12 @@ function onkey(key, code, action, mod)
elseif (key == couch.KEY_D or key == couch.KEY_A) and action == couch.ACTION_RELEASE then
vx = 0.0
end
if key == couch.KEY_DOWN and action == couch.ACTION_PRESS then
light.ambient = light.ambient - 0.1
elseif key == couch.KEY_UP and action == couch.ACTION_PRESS then
light.ambient = light.ambient + 0.1
end
end
function onmousemotion(_, _, relx, rely)

View File

@ -48,7 +48,13 @@ swig files and customizing the interface by hand. I also want to add a whole mes
so that I don't have to test for keypresses. Lastly, I want to test if a function exists before
calling it from the lua file, so stubs aren't necessary to prevent a crash
- [ ] Combine files
- [ ] Better interface
- [ ] Constants for keys and the like
- [ ] No crash on calling non-existant scripting hooks
- [X] Combine files
- [X] Better interface
- [X] Constants for keys and the like
- [X] No crash on calling non-existant scripting hooks
## Lighting
I'm a bit happier with the system now, I think it's time I started the lighting.
We're going to use a pretty basic Phong lighting system, with
Flat and Garourd shaders available (This was all that was available on the PSX!)

View File

@ -14,6 +14,7 @@
#include "Mesh.h"
#include "Material.h"
#include "Camera.h"
#include "Light.h"
%}
%rename("%(strip:[script_])s") "";
@ -24,6 +25,7 @@ typedef float cfloat;
class Vector3 {
public:
Vector3();
Vector3(cfloat x, cfloat y, cfloat z);
cfloat x, y, z;
};
@ -37,6 +39,13 @@ public:
}
%ignore "Vector3";
%extend DirectionalLight {
static DirectionalLight* script_new() {
return new DirectionalLight();
}
}
%include "types.h"
%include "constants.h"
%include "Node.h"
@ -45,4 +54,5 @@ public:
%include "Transform.h"
%include "Material.h"
%include "Camera.h"
%include "Light.h"

View File

@ -1,6 +1,7 @@
#version 330 core
in vec3 UV;
in vec3 NORMAL;
out vec4 FragColor;
@ -10,9 +11,19 @@ struct Material {
sampler2D tex;
bool usesTex;
float alphaScissor;
bool unshaded;
};
struct DirectionalLight {
vec3 direction;
vec3 color;
float ambient;
float diffuse;
float specular;
};
uniform Material material;
uniform DirectionalLight directionalLight;
void main() {
FragColor = vec4(0.0);
@ -25,4 +36,10 @@ void main() {
if (FragColor.w < material.alphaScissor) {
discard;
}
if (!material.unshaded) {
vec3 ambient = directionalLight.ambient * directionalLight.color;
vec3 diffuse = directionalLight.diffuse * reflect(directionalLight.direction, NORMAL) * directionalLight.color;
FragColor *= vec4(ambient, 1.0);
}
}

View File

@ -1,16 +1,19 @@
#version 330 core
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 uv;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 uv;
uniform mat4 MODEL;
uniform mat4 VIEW;
uniform mat4 PROJECTION;
out vec3 UV;
out vec3 NORMAL;
void main() {
vec4 vertex = PROJECTION * VIEW * MODEL * vec4(pos, 1.0);
gl_Position = vertex;
UV = vec3(uv * vertex.z, vertex.z);
NORMAL = normal;
}

View File

@ -1,7 +1,8 @@
#version 330 core
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 uv;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 uv;
out vec2 UV;