Improve lighting, Keep track of frame time
This commit is contained in:
parent
296b667268
commit
e71ffe3f2a
@ -14,9 +14,9 @@ if(WIN32)
|
||||
#set(BUILD_SHARED_LIBS OFF)
|
||||
endif()
|
||||
|
||||
message("Build shared libs: ${BUILD_SHARED_LIBS}")
|
||||
message("Debug: ${KEKENGINE_DEBUG}")
|
||||
message("Build kekgame: ${KEKENGINE_BUILD_KEKGAME}")
|
||||
message("Build with VR support: ${KEKENGINE_VR}")
|
||||
message("Target platform: ${KEKENGINE_TARGET_PLATFORM}")
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
@ -118,6 +118,11 @@ if(${KEKENGINE_BUILD_KEKGAME})
|
||||
add_executable(kekgame ${KEKGAME_SOURCE_FILES})
|
||||
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_include_directories(kekgame PRIVATE "src/kekengine/include")
|
||||
endif()
|
||||
|
@ -152,12 +152,13 @@ int init() {
|
||||
glfwSetInputMode(kekData.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
|
||||
glClearColor(0.1f, 0.3f, 0.1f, 0.0f);
|
||||
// glfwSwapInterval(0);
|
||||
glfwSwapInterval(0);
|
||||
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
|
||||
kekData.activeCamera = new Camera();
|
||||
kekData.shader = new Shader("shader/mesh/vertex.glsl", "shader/mesh/fragment.glsl");
|
||||
kekData.shader->initLighting();
|
||||
|
||||
return KEK_SUCCESS;
|
||||
}
|
||||
@ -175,29 +176,29 @@ int start() {
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
kekData.activeCamera->translateY(0.1f);
|
||||
kekData.activeCamera->translateY(KEK_NOCLIP_SPEED * kekData.lastFrameTime);
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -217,6 +218,7 @@ int start() {
|
||||
glUniformMatrix4fv(glGetUniformLocation(kekData.shader->id, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||
glUniform3fv(glGetUniformLocation(kekData.shader->id, "cameraPos"), 1, glm::value_ptr(position));
|
||||
|
||||
if(kekData.shader->lighting) {
|
||||
LightList *lights = kekData.activeScene->lights;
|
||||
|
||||
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;
|
||||
|
||||
for(Light *light : shaderLights) {
|
||||
std::string prefix = "lights[" + std::to_string(i) + "].";
|
||||
/*std::string prefix = "lights[" + std::to_string(i) + "].";
|
||||
|
||||
switch(light->getType()) {
|
||||
case LightType::POINT:
|
||||
@ -272,14 +274,50 @@ int start() {
|
||||
numSpotLights++;
|
||||
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++;
|
||||
}
|
||||
|
||||
// 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, "numDirectionalLights"), numDirectionalLights);
|
||||
glUniform1i(glGetUniformLocation(kekData.shader->id, "numSpotLights"), numSpotLights);
|
||||
}
|
||||
|
||||
if(kekData.activeScene) kekData.activeScene->draw(kekData.shader);
|
||||
|
||||
@ -289,8 +327,9 @@ int start() {
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<float> secsTaken = end - start;
|
||||
// std::cout << "FT: " << secsTaken.count() * 1000 << std::endl;
|
||||
// std::cout << "FR: " << (1.0f / secsTaken.count()) << std::endl;
|
||||
kekData.lastFrameTime = secsTaken.count();
|
||||
std::cout << "FT: " << kekData.lastFrameTime << std::endl;
|
||||
std::cout << "FR: " << (1.0f / kekData.lastFrameTime) << std::endl;
|
||||
}
|
||||
|
||||
return KEK_SUCCESS;
|
||||
|
@ -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(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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "shader.h"
|
||||
#include "types.h"
|
||||
#include "resource.h"
|
||||
#include "constants.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
@ -117,6 +118,27 @@ Shader::~Shader() {
|
||||
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() {
|
||||
glUseProgram(id);
|
||||
}
|
||||
|
@ -7,11 +7,17 @@
|
||||
#define KEK_VERTEX_SHADER_IN_NORMAL 1
|
||||
#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_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_SPECULAR_STRENGTH 0.1f
|
||||
|
||||
|
@ -25,6 +25,8 @@ struct KekData {
|
||||
int screenWidth;
|
||||
int screenHeight;
|
||||
|
||||
float lastFrameTime;
|
||||
|
||||
std::map<std::string, std::weak_ptr<Texture>> loadedTextures;
|
||||
};
|
||||
|
||||
|
@ -1,13 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
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 {
|
||||
|
||||
public:
|
||||
unsigned int id;
|
||||
LightingData *lighting;
|
||||
|
||||
Shader(std::string vertexPath, std::string fragmentPath);
|
||||
|
||||
@ -15,6 +43,8 @@ public:
|
||||
|
||||
~Shader();
|
||||
|
||||
void initLighting();
|
||||
|
||||
void use();
|
||||
|
||||
};
|
||||
|
1
src/kekengine/res/shader/include/constants.glsl
Normal file
1
src/kekengine/res/shader/include/constants.glsl
Normal file
@ -0,0 +1 @@
|
||||
#define MAX_LIGHTS 64
|
@ -7,9 +7,14 @@ struct Material {
|
||||
|
||||
struct Light {
|
||||
vec3 color;
|
||||
float pad;
|
||||
vec3 position;
|
||||
float pad2;
|
||||
vec3 direction;
|
||||
float pad3;
|
||||
vec3 attenuation; // constant, linear, quadratic
|
||||
float pad4;
|
||||
vec2 cutoff; // inner, outer
|
||||
mat4 lightSpaceMatrix;
|
||||
//mat4 lightSpaceMatrix;
|
||||
vec2 padding;
|
||||
};
|
||||
|
@ -7,8 +7,12 @@ in VS_OUT {
|
||||
} fs_in;
|
||||
|
||||
!include types.glsl
|
||||
!include constants.glsl
|
||||
|
||||
layout(std140) uniform LightInfo {
|
||||
Light lights[MAX_LIGHTS];
|
||||
};
|
||||
|
||||
uniform Light lights[8];
|
||||
uniform int numPointLights;
|
||||
uniform int numDirectionalLights;
|
||||
uniform int numSpotLights;
|
||||
@ -26,10 +30,6 @@ const float gamma = 2.2;
|
||||
void main() {
|
||||
vec3 normal = normalize(fs_in.normal);
|
||||
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);
|
||||
|
||||
|
@ -29,8 +29,8 @@ int main(int argc, char **argv) {
|
||||
PointLight *light = new PointLight(glm::vec3(1), 1, 0, 1);
|
||||
scene->lights->add(light);
|
||||
|
||||
DirectionalLight *l = new DirectionalLight(glm::vec3(1), glm::vec3(1, -1, 1));
|
||||
scene->lights->add(l);
|
||||
//DirectionalLight *l = new DirectionalLight(glm::vec3(1), glm::vec3(1, -1, 1));
|
||||
//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));
|
||||
//spot->moveTo(glm::vec3(0, 0, 5));
|
||||
|
Loading…
Reference in New Issue
Block a user