Skip to content

Instantly share code, notes, and snippets.

@AregevDev
Last active August 20, 2019 19:46
Show Gist options
  • Save AregevDev/81ddfca959cb641bff74052adf986f67 to your computer and use it in GitHub Desktop.
Save AregevDev/81ddfca959cb641bff74052adf986f67 to your computer and use it in GitHub Desktop.
No normal matrix, just output the normals
#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;
}
#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);
}
#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