Last active
January 25, 2022 11:36
-
-
Save futurepastori/5db4b11f72a84a6aedf57e015779571d to your computer and use it in GitHub Desktop.
phong
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "application.h" | |
#include "utils.h" | |
#include "mesh.h" | |
#include "texture.h" | |
#include "light.h" | |
#include "volume.h" | |
#include "fbo.h" | |
#include "shader.h" | |
#include "input.h" | |
#include "animation.h" | |
#include "extra/hdre.h" | |
#include "extra/imgui/imgui.h" | |
#include "extra/imgui/imgui_impl_sdl.h" | |
#include "extra/imgui/imgui_impl_opengl3.h" | |
#include <cmath> | |
Application* Application::instance = NULL; | |
Camera* Application::camera = nullptr; | |
float cam_speed = 10; | |
bool render_wireframe = false; | |
Application::Application(int window_width, int window_height, SDL_Window* window) | |
{ | |
this->window_width = window_width; | |
this->window_height = window_height; | |
this->window = window; | |
instance = this; | |
must_exit = false; | |
render_debug = true; | |
fps = 0; | |
frame = 0; | |
time = 0.0f; | |
elapsed_time = 0.0f; | |
mouse_locked = false; | |
// OpenGL flags | |
glEnable( GL_CULL_FACE ); //render both sides of every triangle | |
glEnable( GL_DEPTH_TEST ); //check the occlusions using the Z buffer | |
// Create camera | |
camera = new Camera(); | |
camera->lookAt(Vector3(-5.f, 1.5f, 10.f), Vector3(0.f, 0.0f, 0.f), Vector3(0.f, 1.f, 0.f)); | |
camera->setPerspective(45.f,window_width/(float)window_height,0.1f,10000.f); //set the projection, we want to be perspective | |
// Create node and add it to the scene | |
SceneNode * node = new SceneNode("Scene node"); | |
node_list.push_back(node); | |
// Set mesh to node | |
Mesh* mesh = new Mesh(); | |
mesh->createCube(); | |
node->mesh = mesh; | |
// Set texture | |
Texture* cubemap = new Texture(); | |
cubemap->cubemapFromImages("data/environments/city"); | |
// Set material | |
StandardMaterial* material = new StandardMaterial(); | |
material->shader = Shader::Get("data/shaders/phong.vs", "data/shaders/phong.fs"); | |
Light* light = new Light(); | |
material->light = light; | |
node->material = material; | |
//hide the cursor | |
SDL_ShowCursor(!mouse_locked); //hide or show the mouse | |
} | |
//what to do when the image has to be draw | |
void Application::render(void) | |
{ | |
//set the clear color (the background color) | |
glClearColor(0, 0, 0, 1); | |
// Clear the window and the depth buffer | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
//set the camera as default | |
camera->enable(); | |
for (int i = 0; i < node_list.size(); i++) { | |
node_list[i]->render(camera); | |
if(render_wireframe) | |
node_list[i]->renderWireframe(camera); | |
} | |
//Draw the floor grid | |
if(render_debug) | |
drawGrid(); | |
} | |
void Application::update(double seconds_elapsed) | |
{ | |
mouse_locked = false; | |
float speed = seconds_elapsed * cam_speed; //the speed is defined by the seconds_elapsed so it goes constant | |
float orbit_speed = seconds_elapsed * 0.5f; | |
//camera speed modifier | |
if (Input::isKeyPressed(SDL_SCANCODE_LSHIFT)) speed *= 10; //move faster with left shift | |
float pan_speed = speed * 0.5f; | |
//async input to move the camera around | |
if (Input::isKeyPressed(SDL_SCANCODE_W) || Input::isKeyPressed(SDL_SCANCODE_UP)) camera->move(Vector3( 0.0f, 0.0f, 1.0f) * speed); | |
if (Input::isKeyPressed(SDL_SCANCODE_S) || Input::isKeyPressed(SDL_SCANCODE_DOWN)) camera->move(Vector3( 0.0f, 0.0f, -1.0f) * speed); | |
if (Input::isKeyPressed(SDL_SCANCODE_A) || Input::isKeyPressed(SDL_SCANCODE_LEFT)) camera->move(Vector3( 1.0f, 0.0f, 0.0f) * speed); | |
if (Input::isKeyPressed(SDL_SCANCODE_D) || Input::isKeyPressed(SDL_SCANCODE_RIGHT)) camera->move(Vector3(-1.0f, 0.0f, 0.0f) * speed); | |
if (!HoveringImGui()) | |
{ | |
//move in first person view | |
if (mouse_locked || Input::mouse_state & SDL_BUTTON(SDL_BUTTON_RIGHT)) | |
{ | |
mouse_locked = true; | |
camera->rotate(-Input::mouse_delta.x * orbit_speed * 0.5, Vector3(0, 1, 0)); | |
Vector3 right = camera->getLocalVector(Vector3(1, 0, 0)); | |
camera->rotate(-Input::mouse_delta.y * orbit_speed * 0.5, right); | |
} | |
//orbit around center | |
else if (Input::mouse_state & SDL_BUTTON(SDL_BUTTON_LEFT)) //is left button pressed? | |
{ | |
mouse_locked = true; | |
camera->orbit(-Input::mouse_delta.x * orbit_speed, Input::mouse_delta.y * orbit_speed); | |
} | |
//camera panning | |
else if(Input::mouse_state& SDL_BUTTON(SDL_BUTTON_MIDDLE)) | |
{ | |
mouse_locked = true; | |
camera->move(Vector3(-Input::mouse_delta.x * pan_speed, 0.f, 0.f)); | |
camera->move(Vector3(0.f, Input::mouse_delta.y * pan_speed, 0.f)); | |
} | |
} | |
//move up or down the camera using Q and E keys | |
if (Input::isKeyPressed(SDL_SCANCODE_Q) || Input::isKeyPressed(SDL_SCANCODE_SPACE)) camera->moveGlobal(Vector3(0.0f, -1.0f, 0.0f) * speed); | |
if (Input::isKeyPressed(SDL_SCANCODE_E) || Input::isKeyPressed(SDL_SCANCODE_LCTRL)) camera->moveGlobal(Vector3(0.0f, 1.0f, 0.0f) * speed); | |
//to navigate with the mouse fixed in the middle | |
if (mouse_locked) | |
Input::centerMouse(); | |
SDL_ShowCursor(!mouse_locked); | |
ImGui::SetMouseCursor(mouse_locked ? ImGuiMouseCursor_None : ImGuiMouseCursor_Arrow); | |
} | |
void Application::renderInMenu() | |
{ | |
// Show and edit your global variables on the fly here | |
} | |
//Keyboard event handler (sync input) | |
void Application::onKeyDown( SDL_KeyboardEvent event ) | |
{ | |
switch(event.keysym.sym) | |
{ | |
case SDLK_ESCAPE: must_exit = true; break; //ESC key, kill the app | |
case SDLK_F1: render_debug = !render_debug; break; | |
case SDLK_F2: render_wireframe = !render_wireframe; break; | |
case SDLK_F5: Shader::ReloadAll(); break; | |
} | |
} | |
void Application::onKeyUp(SDL_KeyboardEvent event) | |
{ | |
} | |
void Application::onGamepadButtonDown(SDL_JoyButtonEvent event) | |
{ | |
} | |
void Application::onGamepadButtonUp(SDL_JoyButtonEvent event) | |
{ | |
} | |
void Application::onMouseButtonDown( SDL_MouseButtonEvent event ) | |
{ | |
} | |
void Application::onMouseButtonUp(SDL_MouseButtonEvent event) | |
{ | |
} | |
void Application::onMouseWheel(SDL_MouseWheelEvent event) | |
{ | |
bool mouse_blocked = false; | |
ImGuiIO& io = ImGui::GetIO(); | |
if (!mouse_locked) | |
switch (event.type) | |
{ | |
case SDL_MOUSEWHEEL: | |
{ | |
if (event.x > 0) io.MouseWheelH += 1; | |
if (event.x < 0) io.MouseWheelH -= 1; | |
if (event.y > 0) io.MouseWheel += 1; | |
if (event.y < 0) io.MouseWheel -= 1; | |
} | |
} | |
mouse_blocked = ImGui::IsAnyWindowHovered(); | |
if (!mouse_blocked && event.y) | |
{ | |
if (mouse_locked) | |
cam_speed *= 1 + (event.y * 0.1); | |
else | |
camera->changeDistance(event.y * 0.5); | |
} | |
} | |
void Application::onResize(int width, int height) | |
{ | |
std::cout << "window resized: " << width << "," << height << std::endl; | |
glViewport( 0,0, width, height ); | |
camera->aspect = width / (float)height; | |
window_width = width; | |
window_height = height; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "material.h" | |
#include "texture.h" | |
#include "application.h" | |
StandardMaterial::StandardMaterial() | |
{ | |
color = Vector4(1.f, 1.f, 1.f, 1.f); | |
// No canvia res independentment dels valors que posem aquí, | |
// en tot cas agafarà el color de la línia anterior | |
diffuse_k = Vector3(1.0, 1.0, 1.0); | |
ambient_k = Vector3(1.0, 1.0, 1.0); | |
ambient_k = Vector3(1.0, 1.0, 1.0); | |
alpha = 30.0; | |
} | |
StandardMaterial::~StandardMaterial() | |
{ | |
} | |
void StandardMaterial::setUniforms(Camera* camera, Matrix44 model) | |
{ | |
//upload node uniforms | |
shader->setUniform("u_viewprojection", camera->viewprojection_matrix); | |
shader->setUniform("u_camera_position", camera->eye); | |
shader->setUniform("u_model", model); | |
shader->setUniform("u_time", Application::instance->time); | |
shader->setUniform("u_color", color); | |
if (texture) | |
shader->setUniform("u_texture", texture); | |
if (light) { | |
shader->setUniform("light_position", light->position); | |
shader->setUniform("diffuse_i", light->diffuse_color); | |
shader->setUniform("specular_i", light->specular_color); | |
shader->setUniform("ambient_i", light->ambient_color); | |
shader->setUniform("diffuse_k", diffuse_k); | |
shader->setUniform("specular_k", specular_k); | |
shader->setUniform("ambient_k", ambient_k); | |
shader->setFloat("alpha", alpha); | |
} | |
} | |
void StandardMaterial::render(Mesh* mesh, Matrix44 model, Camera* camera) | |
{ | |
//set flags | |
glEnable(GL_DEPTH_TEST); | |
glDisable(GL_CULL_FACE); | |
if (mesh && shader) | |
{ | |
//enable shader | |
shader->enable(); | |
//upload uniforms | |
setUniforms(camera, model); | |
//do the draw call | |
mesh->render(GL_TRIANGLES); | |
//disable shader | |
shader->disable(); | |
} | |
} | |
void StandardMaterial::renderInMenu() | |
{ | |
ImGui::ColorEdit3("Color", (float*)&color); // Edit 3 floats representing a color | |
} | |
WireframeMaterial::WireframeMaterial() | |
{ | |
color = vec4(1.f, 1.f, 1.f, 1.f); | |
shader = Shader::Get("data/shaders/basic.vs", "data/shaders/flat.fs"); | |
} | |
WireframeMaterial::~WireframeMaterial() | |
{ | |
} | |
void WireframeMaterial::render(Mesh* mesh, Matrix44 model, Camera * camera) | |
{ | |
if (shader && mesh) | |
{ | |
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | |
//enable shader | |
shader->enable(); | |
//upload material specific uniforms | |
setUniforms(camera, model); | |
//do the draw call | |
mesh->render(GL_TRIANGLES); | |
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
varying vec3 v_position; | |
varying vec3 v_world_position; | |
varying vec3 v_normal; | |
varying vec2 v_uv; | |
varying vec4 v_color; | |
// uniforms | |
uniform vec3 diffuse_k; | |
uniform vec3 diffuse_i; | |
uniform float alpha; | |
uniform vec3 specular_k; | |
uniform vec3 specular_i; | |
uniform vec3 ambient_k; | |
uniform vec3 ambient_i; | |
uniform vec3 light_position; | |
uniform vec3 u_camera_position; | |
uniform vec4 u_color; | |
void main() | |
{ | |
//here we set up the normal as a color to see them as a debug | |
//here write the computations for PHONG. | |
//for GOURAUD you dont need to do anything here, just pass the color from the vertex shader | |
vec3 N = normalize(v_normal); | |
vec3 L = normalize( light_position - v_world_position); | |
vec3 E = normalize( u_camera_position - v_world_position); | |
vec3 R = normalize(reflect(E, N)); | |
float NdotL = max(0.0, dot(N,L)); | |
float RdotL = pow(max(0.0, dot(-R,L)), alpha); | |
vec3 color = ambient_k * ambient_i + diffuse_k * diffuse_i * NdotL + specular_k * specular_i * RdotL; | |
//set the ouput color por the pixel | |
gl_FragColor = vec4( color, 1.0 )*u_color; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
attribute vec3 a_vertex; | |
attribute vec3 a_normal; | |
attribute vec2 a_uv; | |
attribute vec4 a_color; | |
uniform vec3 u_camera_pos; | |
uniform mat4 u_model; | |
uniform mat4 u_viewprojection; | |
//this will store the color for the pixel shader | |
varying vec3 v_position; | |
varying vec3 v_world_position; | |
varying vec3 v_world_normal; | |
varying vec3 v_normal; | |
varying vec2 v_uv; | |
varying vec4 v_color; | |
void main() | |
{ | |
//calcule the normal in camera space (the NormalMatrix is like ViewMatrix but without traslation) | |
v_normal = (u_model * vec4( a_normal, 0.0) ).xyz; | |
v_world_normal = (u_model * vec4( gl_Normal.xyz, 0.0)).xyz; | |
//calcule the vertex in object space | |
v_position = a_vertex; | |
v_world_position = (u_model * vec4( v_position, 1.0) ).xyz; | |
//store the color in the varying var to use it from the pixel shader | |
v_color = a_color; | |
//store the texture coordinates | |
v_uv = a_uv; | |
//calcule the position of the vertex using the matrices | |
gl_Position = u_viewprojection * vec4( v_world_position, 1.0 ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment