Improve lighting, Keep track of frame time

This commit is contained in:
MrLetsplay 2022-10-15 19:56:44 +02:00
parent 296b667268
commit e71ffe3f2a
11 changed files with 188 additions and 78 deletions

View File

@ -14,9 +14,9 @@ if(WIN32)
#set(BUILD_SHARED_LIBS OFF) #set(BUILD_SHARED_LIBS OFF)
endif() endif()
message("Build shared libs: ${BUILD_SHARED_LIBS}")
message("Debug: ${KEKENGINE_DEBUG}") message("Debug: ${KEKENGINE_DEBUG}")
message("Build kekgame: ${KEKENGINE_BUILD_KEKGAME}") message("Build kekgame: ${KEKENGINE_BUILD_KEKGAME}")
message("Build with VR support: ${KEKENGINE_VR}")
message("Target platform: ${KEKENGINE_TARGET_PLATFORM}") message("Target platform: ${KEKENGINE_TARGET_PLATFORM}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
@ -118,6 +118,11 @@ if(${KEKENGINE_BUILD_KEKGAME})
add_executable(kekgame ${KEKGAME_SOURCE_FILES}) add_executable(kekgame ${KEKGAME_SOURCE_FILES})
add_dependencies(kekgame kekgame_res) add_dependencies(kekgame kekgame_res)
if(WIN32)
target_link_options(kekgame PUBLIC -static-libgcc -static-libstdc++ -static)
endif()
target_link_libraries(kekgame PUBLIC kekengine_static) target_link_libraries(kekgame PUBLIC kekengine_static)
target_include_directories(kekgame PRIVATE "src/kekengine/include") target_include_directories(kekgame PRIVATE "src/kekengine/include")
endif() endif()

View File

@ -152,12 +152,13 @@ int init() {
glfwSetInputMode(kekData.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(kekData.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glClearColor(0.1f, 0.3f, 0.1f, 0.0f); glClearColor(0.1f, 0.3f, 0.1f, 0.0f);
// glfwSwapInterval(0); glfwSwapInterval(0);
stbi_set_flip_vertically_on_load(true); stbi_set_flip_vertically_on_load(true);
kekData.activeCamera = new Camera(); kekData.activeCamera = new Camera();
kekData.shader = new Shader("shader/mesh/vertex.glsl", "shader/mesh/fragment.glsl"); kekData.shader = new Shader("shader/mesh/vertex.glsl", "shader/mesh/fragment.glsl");
kekData.shader->initLighting();
return KEK_SUCCESS; return KEK_SUCCESS;
} }
@ -175,29 +176,29 @@ int start() {
} }
if(glfwGetKey(kekData.window, GLFW_KEY_W) == GLFW_PRESS) { if(glfwGetKey(kekData.window, GLFW_KEY_W) == GLFW_PRESS) {
kekData.activeCamera->translate(kekData.activeCamera->direction * 0.1f); kekData.activeCamera->translate(kekData.activeCamera->direction * KEK_NOCLIP_SPEED * kekData.lastFrameTime);
} }
if(glfwGetKey(kekData.window, GLFW_KEY_S) == GLFW_PRESS) { if(glfwGetKey(kekData.window, GLFW_KEY_S) == GLFW_PRESS) {
kekData.activeCamera->translate(kekData.activeCamera->direction * -0.1f); kekData.activeCamera->translate(kekData.activeCamera->direction * -KEK_NOCLIP_SPEED * kekData.lastFrameTime);
} }
if(glfwGetKey(kekData.window, GLFW_KEY_A) == GLFW_PRESS) { if(glfwGetKey(kekData.window, GLFW_KEY_A) == GLFW_PRESS) {
glm::vec3 camRight = glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f))); glm::vec3 camRight = glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f)));
kekData.activeCamera->translate(-camRight * 0.1f); kekData.activeCamera->translate(-camRight * KEK_NOCLIP_SPEED * kekData.lastFrameTime);
} }
if(glfwGetKey(kekData.window, GLFW_KEY_D) == GLFW_PRESS) { if(glfwGetKey(kekData.window, GLFW_KEY_D) == GLFW_PRESS) {
glm::vec3 camRight = glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f))); glm::vec3 camRight = glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f)));
kekData.activeCamera->translate(camRight * 0.1f); kekData.activeCamera->translate(camRight * KEK_NOCLIP_SPEED * kekData.lastFrameTime);
} }
if(glfwGetKey(kekData.window, GLFW_KEY_SPACE) == GLFW_PRESS) { if(glfwGetKey(kekData.window, GLFW_KEY_SPACE) == GLFW_PRESS) {
kekData.activeCamera->translateY(0.1f); kekData.activeCamera->translateY(KEK_NOCLIP_SPEED * kekData.lastFrameTime);
} }
if(glfwGetKey(kekData.window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) { if(glfwGetKey(kekData.window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) {
kekData.activeCamera->translateY(-0.1f); kekData.activeCamera->translateY(-KEK_NOCLIP_SPEED * kekData.lastFrameTime);
} }
if(glfwGetKey(kekData.window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { if(glfwGetKey(kekData.window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
@ -217,6 +218,7 @@ int start() {
glUniformMatrix4fv(glGetUniformLocation(kekData.shader->id, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); glUniformMatrix4fv(glGetUniformLocation(kekData.shader->id, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniform3fv(glGetUniformLocation(kekData.shader->id, "cameraPos"), 1, glm::value_ptr(position)); glUniform3fv(glGetUniformLocation(kekData.shader->id, "cameraPos"), 1, glm::value_ptr(position));
if(kekData.shader->lighting) {
LightList *lights = kekData.activeScene->lights; LightList *lights = kekData.activeScene->lights;
std::vector<Light *> shaderLights; // TODO: Maybe don't compute on every frame std::vector<Light *> shaderLights; // TODO: Maybe don't compute on every frame
@ -241,7 +243,7 @@ int start() {
int numPointLights = 0, numDirectionalLights = 0, numSpotLights = 0; int numPointLights = 0, numDirectionalLights = 0, numSpotLights = 0;
for(Light *light : shaderLights) { for(Light *light : shaderLights) {
std::string prefix = "lights[" + std::to_string(i) + "]."; /*std::string prefix = "lights[" + std::to_string(i) + "].";
switch(light->getType()) { switch(light->getType()) {
case LightType::POINT: case LightType::POINT:
@ -272,14 +274,50 @@ int start() {
numSpotLights++; numSpotLights++;
break; break;
} }
} }*/
ShaderLight shLight;
//shLight.color = light->color;
memcpy(shLight.color, glm::value_ptr(light->color), sizeof(shLight.color));
switch(light->getType()) {
case LightType::POINT:
{
PointLight *l = (PointLight *) light;
memcpy(&shLight.position, glm::value_ptr(l->getPosition()), sizeof(shLight.position));
memcpy(&shLight.attenuation, glm::value_ptr(glm::vec3(l->constant, l->linear, l->quadratic)), sizeof(shLight.attenuation));
numPointLights++;
break;
}
case LightType::DIRECTIONAL:
{
DirectionalLight *l = (DirectionalLight *) light;
memcpy(&shLight.direction, glm::value_ptr(l->direction), sizeof(shLight.direction));
numDirectionalLights++;
break;
}
case LightType::SPOT:
{
SpotLight *l = (SpotLight *) light;
memcpy(&shLight.position, glm::value_ptr(l->getPosition()), sizeof(shLight.position));
memcpy(&shLight.direction, glm::value_ptr(l->direction), sizeof(shLight.direction));
memcpy(&shLight.attenuation, glm::value_ptr(glm::vec3(l->constant, l->linear, l->quadratic)), sizeof(shLight.attenuation));
memcpy(&shLight.cutoff, glm::value_ptr(glm::vec2(glm::cos(l->innerCutoff), glm::cos(l->outerCutoff))), sizeof(shLight.cutoff));
numSpotLights++;
break;
}
}
kekData.shader->lighting->buffer[i] = shLight;
i++; i++;
} }
// TODO: Fix broken lights
glNamedBufferData(kekData.shader->lighting->ubo, kekData.shader->lighting->blockSize, &kekData.shader->lighting->buffer, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, KEK_UNIFORM_LIGHTS_BINDING, kekData.shader->lighting->ubo);
glUniform1i(glGetUniformLocation(kekData.shader->id, "numPointLights"), numPointLights); glUniform1i(glGetUniformLocation(kekData.shader->id, "numPointLights"), numPointLights);
glUniform1i(glGetUniformLocation(kekData.shader->id, "numDirectionalLights"), numDirectionalLights); glUniform1i(glGetUniformLocation(kekData.shader->id, "numDirectionalLights"), numDirectionalLights);
glUniform1i(glGetUniformLocation(kekData.shader->id, "numSpotLights"), numSpotLights); glUniform1i(glGetUniformLocation(kekData.shader->id, "numSpotLights"), numSpotLights);
}
if(kekData.activeScene) kekData.activeScene->draw(kekData.shader); if(kekData.activeScene) kekData.activeScene->draw(kekData.shader);
@ -289,8 +327,9 @@ int start() {
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<float> secsTaken = end - start; std::chrono::duration<float> secsTaken = end - start;
// std::cout << "FT: " << secsTaken.count() * 1000 << std::endl; kekData.lastFrameTime = secsTaken.count();
// std::cout << "FR: " << (1.0f / secsTaken.count()) << std::endl; std::cout << "FT: " << kekData.lastFrameTime << std::endl;
std::cout << "FR: " << (1.0f / kekData.lastFrameTime) << std::endl;
} }
return KEK_SUCCESS; return KEK_SUCCESS;

View File

@ -33,19 +33,19 @@ Mesh::Mesh(std::vector<Vertex> vertices, std::vector<uint32_t> indices, Material
glNamedBufferData(vbo, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); glNamedBufferData(vbo, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glNamedBufferData(ebo, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); glNamedBufferData(ebo, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(Vertex)); glVertexArrayVertexBuffer(vao, KEK_MESH_VERTEX_BUFFER_BINDING, vbo, 0, sizeof(Vertex));
glEnableVertexArrayAttrib(vao, KEK_VERTEX_SHADER_IN_POSITION); glEnableVertexArrayAttrib(vao, KEK_VERTEX_SHADER_IN_POSITION);
glVertexArrayAttribFormat(vao, KEK_VERTEX_SHADER_IN_POSITION, sizeof(float), GL_FLOAT, GL_FALSE, 0); glVertexArrayAttribFormat(vao, KEK_VERTEX_SHADER_IN_POSITION, sizeof(float), GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribBinding(vao, KEK_VERTEX_SHADER_IN_POSITION, 0); glVertexArrayAttribBinding(vao, KEK_VERTEX_SHADER_IN_POSITION, KEK_MESH_VERTEX_BUFFER_BINDING);
glEnableVertexArrayAttrib(vao, KEK_VERTEX_SHADER_IN_NORMAL); glEnableVertexArrayAttrib(vao, KEK_VERTEX_SHADER_IN_NORMAL);
glVertexArrayAttribFormat(vao, KEK_VERTEX_SHADER_IN_NORMAL, sizeof(float), GL_FLOAT, GL_FALSE, offsetof(Vertex, normal)); glVertexArrayAttribFormat(vao, KEK_VERTEX_SHADER_IN_NORMAL, sizeof(float), GL_FLOAT, GL_FALSE, offsetof(Vertex, normal));
glVertexArrayAttribBinding(vao, KEK_VERTEX_SHADER_IN_NORMAL, 0); glVertexArrayAttribBinding(vao, KEK_VERTEX_SHADER_IN_NORMAL, KEK_MESH_VERTEX_BUFFER_BINDING);
glEnableVertexArrayAttrib(vao, KEK_VERTEX_SHADER_IN_TEXCOORD); glEnableVertexArrayAttrib(vao, KEK_VERTEX_SHADER_IN_TEXCOORD);
glVertexArrayAttribFormat(vao, KEK_VERTEX_SHADER_IN_TEXCOORD, sizeof(float), GL_FLOAT, GL_FALSE, offsetof(Vertex, texCoords)); glVertexArrayAttribFormat(vao, KEK_VERTEX_SHADER_IN_TEXCOORD, sizeof(float), GL_FLOAT, GL_FALSE, offsetof(Vertex, texCoords));
glVertexArrayAttribBinding(vao, KEK_VERTEX_SHADER_IN_TEXCOORD, 0); glVertexArrayAttribBinding(vao, KEK_VERTEX_SHADER_IN_TEXCOORD, KEK_MESH_VERTEX_BUFFER_BINDING);
glVertexArrayElementBuffer(vao, ebo); glVertexArrayElementBuffer(vao, ebo);

View File

@ -1,6 +1,7 @@
#include "shader.h" #include "shader.h"
#include "types.h" #include "types.h"
#include "resource.h" #include "resource.h"
#include "constants.h"
#include <GL/glew.h> #include <GL/glew.h>
@ -117,6 +118,27 @@ Shader::~Shader() {
glDeleteProgram(id); glDeleteProgram(id);
} }
void Shader::initLighting() {
lighting = (LightingData *) calloc(1, sizeof(LightingData));
lighting->blockID = glGetUniformBlockIndex(id, "LightInfo");
glUniformBlockBinding(id, lighting->blockID, KEK_UNIFORM_LIGHTS_BINDING);
glCreateBuffers(1, &lighting->ubo);
GLenum err = glGetError();
if(err != GL_NO_ERROR) {
std::cout << "OpenGL error while init lighting: " << err << std::endl;
exit(1);
}
glGetActiveUniformBlockiv(id, lighting->blockID, GL_UNIFORM_BLOCK_DATA_SIZE, &lighting->blockSize);
std::cout << "Lighting block size: " << lighting->blockSize << std::endl;
std::cout << "Light size: " << sizeof(ShaderLight) << std::endl;
if(lighting->blockSize != KEK_LIGHT_LIMIT * sizeof(ShaderLight)) {
std::cerr << "Lighting block size doesn't match (is " << lighting->blockSize << ", should be " << KEK_LIGHT_LIMIT * sizeof(ShaderLight) << "). Improper padding?" << std::endl;
exit(1);
}
}
void Shader::use() { void Shader::use() {
glUseProgram(id); glUseProgram(id);
} }

View File

@ -7,11 +7,17 @@
#define KEK_VERTEX_SHADER_IN_NORMAL 1 #define KEK_VERTEX_SHADER_IN_NORMAL 1
#define KEK_VERTEX_SHADER_IN_TEXCOORD 2 #define KEK_VERTEX_SHADER_IN_TEXCOORD 2
#define KEK_MESH_VERTEX_BUFFER_BINDING 0
#define KEK_UNIFORM_LIGHTS_BINDING 0
#define KEK_LIGHT_LIMIT 64 // Also in shader/mesh/fragment.glsl
#define KEK_NOCLIP_SPEED 10.0f
#define KEK_CAMERA_NEAR 0.1f #define KEK_CAMERA_NEAR 0.1f
#define KEK_CAMERA_FAR 100.0f #define KEK_CAMERA_FAR 100.0f
#define KEK_LIGHT_LIMIT 8 // Also in shader/mesh/fragment.glsl
#define KEK_LIGHT_DEFAULT_AMBIENT_STRENGTH 0.05f #define KEK_LIGHT_DEFAULT_AMBIENT_STRENGTH 0.05f
#define KEK_LIGHT_DEFAULT_SPECULAR_STRENGTH 0.1f #define KEK_LIGHT_DEFAULT_SPECULAR_STRENGTH 0.1f

View File

@ -25,6 +25,8 @@ struct KekData {
int screenWidth; int screenWidth;
int screenHeight; int screenHeight;
float lastFrameTime;
std::map<std::string, std::weak_ptr<Texture>> loadedTextures; std::map<std::string, std::weak_ptr<Texture>> loadedTextures;
}; };

View File

@ -1,13 +1,41 @@
#pragma once #pragma once
#include <string> #include <string>
#include <glm/glm.hpp>
#include "constants.h"
namespace kek { namespace kek {
#pragma pack(1)
struct ShaderLight {
float color[3];
float pad;
float position[3];
float pad2;
float direction[3];
float pad3;
float attenuation[3]; // constant, linear, quadratic
float pad4;
float cutoff[2]; // inner, outer
//float lightSpaceMatrix[16]; // mat4
float padding[2];
};
#pragma pack(0)
// Lighting data for shader
struct LightingData {
unsigned int blockID;
int blockSize;
unsigned int ubo;
ShaderLight buffer[KEK_LIGHT_LIMIT];
};
class Shader { class Shader {
public: public:
unsigned int id; unsigned int id;
LightingData *lighting;
Shader(std::string vertexPath, std::string fragmentPath); Shader(std::string vertexPath, std::string fragmentPath);
@ -15,6 +43,8 @@ public:
~Shader(); ~Shader();
void initLighting();
void use(); void use();
}; };

View File

@ -0,0 +1 @@
#define MAX_LIGHTS 64

View File

@ -7,9 +7,14 @@ struct Material {
struct Light { struct Light {
vec3 color; vec3 color;
float pad;
vec3 position; vec3 position;
float pad2;
vec3 direction; vec3 direction;
float pad3;
vec3 attenuation; // constant, linear, quadratic vec3 attenuation; // constant, linear, quadratic
float pad4;
vec2 cutoff; // inner, outer vec2 cutoff; // inner, outer
mat4 lightSpaceMatrix; //mat4 lightSpaceMatrix;
vec2 padding;
}; };

View File

@ -7,8 +7,12 @@ in VS_OUT {
} fs_in; } fs_in;
!include types.glsl !include types.glsl
!include constants.glsl
layout(std140) uniform LightInfo {
Light lights[MAX_LIGHTS];
};
uniform Light lights[8];
uniform int numPointLights; uniform int numPointLights;
uniform int numDirectionalLights; uniform int numDirectionalLights;
uniform int numSpotLights; uniform int numSpotLights;
@ -26,10 +30,6 @@ const float gamma = 2.2;
void main() { void main() {
vec3 normal = normalize(fs_in.normal); vec3 normal = normalize(fs_in.normal);
vec3 viewDir = normalize(cameraPos - fs_in.fragmentPosition); vec3 viewDir = normalize(cameraPos - fs_in.fragmentPosition);
//color = length(fs_in.fragmentPosition) / 2 * vec4(1.0);
//color = vec4(norm, 1.0);
color = texture(material.diffuse, fs_in.textureCoordinate);
vec3 result = vec3(0.0); vec3 result = vec3(0.0);

View File

@ -29,8 +29,8 @@ int main(int argc, char **argv) {
PointLight *light = new PointLight(glm::vec3(1), 1, 0, 1); PointLight *light = new PointLight(glm::vec3(1), 1, 0, 1);
scene->lights->add(light); scene->lights->add(light);
DirectionalLight *l = new DirectionalLight(glm::vec3(1), glm::vec3(1, -1, 1)); //DirectionalLight *l = new DirectionalLight(glm::vec3(1), glm::vec3(1, -1, 1));
scene->lights->add(l); //scene->lights->add(l);
//SpotLight *spot = new SpotLight(glm::vec3(1), glm::vec3(0, 0, -1), 1, 0, 1, glm::radians(8.0f), glm::radians(15.0f)); //SpotLight *spot = new SpotLight(glm::vec3(1), glm::vec3(0, 0, -1), 1, 0, 1, glm::radians(8.0f), glm::radians(15.0f));
//spot->moveTo(glm::vec3(0, 0, 5)); //spot->moveTo(glm::vec3(0, 0, 5));