Last active
August 20, 2019 19:46
-
-
Save AregevDev/81ddfca959cb641bff74052adf986f67 to your computer and use it in GitHub Desktop.
No normal matrix, just output the normals
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
#define GLFW_INCLUDE_NONE | |
#include <GLFW/glfw3.h> | |
#include <glad/glad.h> | |
#define STB_IMAGE_IMPLEMENTATION | |
#include <stb/stb_image.h> | |
#define NK_INCLUDE_FIXED_TYPES | |
#define NK_INCLUDE_STANDARD_IO | |
#define NK_INCLUDE_STANDARD_VARARGS | |
#define NK_INCLUDE_DEFAULT_ALLOCATOR | |
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT | |
#define NK_INCLUDE_FONT_BAKING | |
#define NK_INCLUDE_DEFAULT_FONT | |
#define NK_IMPLEMENTATION | |
#define NK_GLFW_GL3_IMPLEMENTATION | |
#include <nuklear/nuklear.h> | |
#include <nuklear/nuklear_glfw_gl3.h> | |
#include <glm/glm.hpp> | |
#include <glm/gtc/matrix_transform.hpp> | |
#include <glm/gtc/type_ptr.hpp> | |
#include <fstream> | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
#define MAX_VERTEX_MEMORY 512 * 1024 | |
#define MAX_ELEMENT_MEMORY 128 * 1024 | |
const int SCR_WIDTH = 800; | |
const int SCR_HEIGHT = 600; | |
float deltaTime = 0.0f; | |
float lastFrame = 0.0f; | |
float mix = 0.0f; | |
nk_colorf bgColor; | |
float fov = 45.0f; | |
glm::vec3 lightPos(0.0f, 0.0f, 0.0f); | |
glm::vec3 viewPos(0.0f, 0.0f, -3.0f); | |
void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { | |
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) | |
glfwSetWindowShouldClose(window, true); | |
} | |
void framebufferSizeCallback(GLFWwindow *window, int width, int height) { | |
glViewport(0, 0, width, height); | |
} | |
unsigned int generateShader(const std::string &filename, unsigned int shaderType) { | |
// load the shader file | |
std::ifstream ifs(filename); | |
if (ifs.fail()) { | |
std::cerr << "Failed to read file: " << filename << std::endl; | |
return 0; | |
} | |
std::string buffer = std::string(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>()); | |
// generate shader handle | |
unsigned int handle = glCreateShader(shaderType); | |
const char *src = buffer.data(); | |
glShaderSource(handle, 1, &src, nullptr); | |
// compile shader | |
glCompileShader(handle); | |
// check for compilation result and report errors | |
int compileStatus; | |
glGetShaderiv(handle, GL_COMPILE_STATUS, &compileStatus); | |
if (!compileStatus) { | |
// allocate the required memory for the info log | |
int logLength; | |
glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &logLength); | |
char *infoLog = static_cast<char *>(alloca(logLength)); | |
// get the info log | |
glGetShaderInfoLog(handle, logLength, nullptr, infoLog); | |
// get the info log | |
std::cerr << "Failed to compile: " << filename.substr(filename.find('/') + 1, filename.back()) << "\n" | |
<< infoLog; | |
return 0; | |
} | |
return handle; | |
} | |
unsigned int buildProgram(const std::vector<unsigned int> &shaders) { | |
// create program handle | |
unsigned int handle = glCreateProgram(); | |
for (const auto &i: shaders) { | |
// attach each provided shader | |
glAttachShader(handle, i); | |
} | |
// link the program | |
glLinkProgram(handle); | |
// check for linkage result and report errors | |
int linkStatus; | |
glGetProgramiv(handle, GL_LINK_STATUS, &linkStatus); | |
if (!linkStatus) { | |
// allocate the required memory for the info log | |
int logLength; | |
glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &logLength); | |
char *infoLog = static_cast<char *>(alloca(logLength)); | |
// get the info log | |
glGetProgramInfoLog(handle, logLength, nullptr, infoLog); | |
// get the info log | |
std::cerr << "Failed to link " << handle << "\n" << infoLog; | |
return 0; | |
} | |
return handle; | |
} | |
int main() { | |
// initialize GLFW and create window | |
glfwInit(); | |
GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "learnopengl", nullptr, nullptr); | |
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); | |
// create context | |
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |
glfwSwapInterval(1); | |
glfwSetFramebufferSizeCallback(window, framebufferSizeCallback); | |
glfwSetKeyCallback(window, keyCallback); | |
glfwMakeContextCurrent(window); | |
// load OpenGL functions | |
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); | |
stbi_set_flip_vertically_on_load(true); | |
glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); | |
// enable depth testing | |
glEnable(GL_DEPTH_TEST); | |
// gui | |
nk_context *nkContext = nk_glfw3_init(window, NK_GLFW3_INSTALL_CALLBACKS); | |
nk_font_atlas *atlas; | |
nk_glfw3_font_stash_begin(&atlas); | |
const nk_font *def = nk_font_atlas_add_default(atlas, 14, nullptr); | |
nk_glfw3_font_stash_end(); | |
nk_style_set_font(nkContext, &def->handle); | |
// load and compile shaders | |
unsigned int texturedVs = generateShader("shaders/textured.vert", GL_VERTEX_SHADER); | |
unsigned int texturedFs = generateShader("shaders/textured.frag", GL_FRAGMENT_SHADER); | |
// build the shader program | |
unsigned int texturedProgram = buildProgram({texturedVs, texturedFs}); | |
unsigned int lightVs = generateShader("shaders/light.vert", GL_VERTEX_SHADER); | |
unsigned int lightFs = generateShader("shaders/light.frag", GL_FRAGMENT_SHADER); | |
unsigned int lightProgram = buildProgram({lightVs, lightFs}); | |
float triangleVert[] = { | |
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, | |
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f, | |
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, | |
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, | |
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, | |
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, | |
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, | |
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, | |
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, | |
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, | |
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, | |
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, -1.0f, 0.0f, | |
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, | |
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, | |
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, | |
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, | |
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, | |
}; | |
/*unsigned short triangleInd[] = { | |
0, 1, 3, | |
1, 2, 3, | |
};*/ | |
// initialize vertex array for state management | |
unsigned int vao, lightVao; | |
glGenVertexArrays(1, &vao); | |
glBindVertexArray(vao); | |
// initialize vertex buffer | |
unsigned int vbo; | |
glGenBuffers(1, &vbo); | |
glBindBuffer(GL_ARRAY_BUFFER, vbo); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVert), triangleVert, GL_STATIC_DRAW); | |
// initialize index buffer | |
/*unsigned int ebo; | |
glGenBuffers(1, &ebo); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); | |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(triangleInd), triangleInd, GL_STATIC_DRAW);*/ | |
// link the vertex attributes | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), nullptr); | |
glEnableVertexAttribArray(0); | |
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), | |
reinterpret_cast<const void *>(3 * sizeof(float))); | |
glEnableVertexAttribArray(1); | |
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), | |
reinterpret_cast<const void *>(5 * sizeof(float))); | |
glEnableVertexAttribArray(2); | |
glGenVertexArrays(1, &lightVao); | |
glBindVertexArray(lightVao); | |
unsigned int lightVbo; | |
glGenBuffers(1, &lightVbo); | |
glBindBuffer(GL_ARRAY_BUFFER, lightVbo); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVert), triangleVert, GL_STATIC_DRAW); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), nullptr); | |
glEnableVertexAttribArray(0); | |
// initialize texture1 | |
unsigned int tex1; | |
glGenTextures(1, &tex1); | |
glBindTexture(GL_TEXTURE_2D, tex1); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
int tWidth, tHeight, tChannels; | |
unsigned char *texData = stbi_load("textures/tex1.jpg", &tWidth, &tHeight, &tChannels, 0); | |
if (texData) { | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, tWidth, tHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, texData); | |
glGenerateMipmap(GL_TEXTURE_2D); | |
} else { | |
std::cerr << "Failed to load texture1" << std::endl; | |
} | |
stbi_image_free(texData); | |
// initialize texture2 | |
unsigned int tex2; | |
glGenTextures(1, &tex2); | |
glBindTexture(GL_TEXTURE_2D, tex2); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
texData = stbi_load("textures/tex2.jpg", &tWidth, &tHeight, &tChannels, 0); | |
if (texData) { | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, tWidth, tHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, texData); | |
glGenerateMipmap(GL_TEXTURE_2D); | |
} else { | |
std::cerr << "Failed to load texture2" << std::endl; | |
} | |
stbi_image_free(texData); | |
glUseProgram(texturedProgram); | |
glUniform1i(glGetUniformLocation(texturedProgram, "uTex1"), 0); | |
glUniform1i(glGetUniformLocation(texturedProgram, "uTex2"), 1); | |
// main loop | |
while (!glfwWindowShouldClose(window)) { | |
// calculate delta time | |
float currentTicks = glfwGetTime(); | |
deltaTime = currentTicks - lastFrame; | |
lastFrame = currentTicks; | |
// set the view matrix | |
glm::mat4 view(1.0f); | |
view = glm::lookAt(glm::vec3(0, 0, 4), glm::vec3(0.0f), glm::vec3(0, 1, 0)); | |
// set the projection matrix | |
glm::mat4 projection(1.0f); | |
projection = glm::perspective(glm::radians(fov), (float) SCR_WIDTH / SCR_HEIGHT, 0.1f, 100.0f); | |
// set the model transformation | |
glm::mat4 texturedModel(1.0f); | |
texturedModel = glm::rotate(texturedModel, glm::radians(-45.0f), glm::vec3(1.0f, 0.0, 0.0f)); | |
texturedModel = glm::rotate(texturedModel, glm::radians(-45.0f), glm::vec3(0.0f, 0.0, 1.0f)); | |
// model = glm::scale(model, glm::vec3(abs(sin(time)), abs(sin(time)), 0.0f)) | |
glm::mat4 lightModel(1.0f); | |
lightModel = glm::rotate(lightModel, glm::radians(-45.0f), glm::vec3(1.0f, 0.0, 0.0f)); | |
lightModel = glm::scale(lightModel, glm::vec3(0.2f)); // a smaller cube | |
lightModel = glm::translate(lightModel, lightPos); | |
// move the light source | |
lightPos.x = 6.0f * sin(glfwGetTime()); | |
lightPos.y = 6.0f * cos(glfwGetTime()); | |
glClearColor(bgColor.r, bgColor.g, bgColor.b, bgColor.a); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_2D, tex1); | |
glActiveTexture(GL_TEXTURE1); | |
glBindTexture(GL_TEXTURE_2D, tex2); | |
glBindVertexArray(lightVao); | |
glUseProgram(lightProgram); | |
glUniformMatrix4fv(glGetUniformLocation(lightProgram, "uModel"), 1, GL_FALSE, glm::value_ptr(lightModel)); | |
glUniformMatrix4fv(glGetUniformLocation(lightProgram, "uView"), 1, GL_FALSE, glm::value_ptr(view)); | |
glUniformMatrix4fv(glGetUniformLocation(lightProgram, "uProjection"), 1, GL_FALSE, glm::value_ptr(projection)); | |
glDrawArrays(GL_TRIANGLES, 0, 36); | |
glBindVertexArray(vao); | |
// use the shader program | |
glUseProgram(texturedProgram); | |
// set the uniforms | |
glUniformMatrix4fv(glGetUniformLocation(texturedProgram, "uModel"), 1, GL_FALSE, glm::value_ptr(texturedModel)); | |
glUniformMatrix4fv(glGetUniformLocation(texturedProgram, "uView"), 1, GL_FALSE, glm::value_ptr(view)); | |
glUniformMatrix4fv(glGetUniformLocation(texturedProgram, "uProjection"), 1, GL_FALSE, glm::value_ptr(projection)); | |
glUniform3f(glGetUniformLocation(texturedProgram, "uLightColor"), 1.0f, 1.0f, 1.0f); | |
glUniform3f(glGetUniformLocation(texturedProgram, "uObjectColor"), 0.631f, 0.796f, 0.870f); | |
glUniform3f(glGetUniformLocation(texturedProgram, "uLightPos"), lightPos.x, lightPos.y, lightPos.z); | |
glUniform3f(glGetUniformLocation(texturedProgram, "uViewPos"), viewPos.x, viewPos.y, viewPos.z); | |
// draw OpenGL | |
glDrawArrays(GL_TRIANGLES, 0, 36); | |
// draw GUI | |
nk_glfw3_new_frame(); | |
if (nk_begin(nkContext, "Debug", nk_rect(10, 10, 180, 300), | |
NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_SCALABLE | NK_WINDOW_SCALABLE | | |
NK_WINDOW_MINIMIZABLE)) { | |
nk_layout_row_dynamic(nkContext, 20, 1); | |
nk_property_float(nkContext, "mix", 0.0f, &mix, 1.0f, 0.1f, 0.01f); | |
nk_property_float(nkContext, "fov", 0.25f, &fov, 110.0f, 1.0f, 1.0f); | |
nk_label(nkContext, "background", NK_TEXT_LEFT); | |
nk_layout_row_dynamic(nkContext, 120, 1); | |
bgColor = nk_color_picker(nkContext, bgColor, NK_RGBA); | |
} | |
nk_end(nkContext); | |
glPushAttrib(GL_DEPTH_BUFFER_BIT); | |
nk_glfw3_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_MEMORY, MAX_ELEMENT_MEMORY); | |
glPopAttrib(); | |
glfwSwapBuffers(window); | |
glfwPollEvents(); | |
} | |
nk_glfw3_shutdown(); | |
glfwDestroyWindow(window); | |
glfwTerminate(); | |
return 0; | |
} |
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
#version 330 core | |
in vec2 vTexCoord; | |
in vec3 vNormal; | |
in vec3 vFragPos; | |
uniform sampler2D uTex1; | |
uniform sampler2D uTex2; | |
uniform vec3 uLightPos; | |
uniform vec3 uLightColor; | |
uniform vec3 uObjectColor; | |
uniform vec3 uViewPos; | |
out vec4 FragColor; | |
void main() { | |
float ambientStrength = 0.1f; | |
vec3 ambient = ambientStrength * uLightColor; | |
vec3 norm = normalize(vNormal); | |
vec3 lightDir = normalize(uLightPos - vFragPos); | |
float diff = max(dot(norm, lightDir), 0.0f); | |
vec3 diffuse = diff * uLightColor; | |
float specularStrength = 1.0f; | |
vec3 viewDir = normalize(uViewPos - vFragPos); | |
vec3 reflectDir = reflect(-lightDir, norm); | |
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 256); | |
vec3 specular = specularStrength * spec * uLightColor; | |
vec3 result = (ambient + diffuse + specular) * uObjectColor; | |
FragColor = vec4(abs(vNormal), 1.0f); | |
} |
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
#version 330 core | |
layout (location = 0) in vec3 aPos; | |
layout (location = 1) in vec2 aTexCoord; | |
layout (location = 2) in vec3 aNormal; | |
uniform mat4 uModel; | |
uniform mat4 uView; | |
uniform mat4 uProjection; | |
out vec2 vTexCoord; | |
out vec3 vNormal; | |
out vec3 vFragPos; | |
void main() { | |
vFragPos = vec3(uModel * vec4(aPos, 1.0)); | |
vTexCoord = aTexCoord; | |
vNormal = aNormal; | |
gl_Position = uProjection * uView * vec4(vFragPos, 1.0f); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment