Added shaders got smooth min working
This commit is contained in:
parent
db4fcead4f
commit
d534be6ee1
|
@ -20,6 +20,14 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\Application.cpp" />
|
<ClCompile Include="src\Application.cpp" />
|
||||||
|
<ClCompile Include="src\Camera.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="shaders\parade_fs.glsl" />
|
||||||
|
<None Include="shaders\parade_vs.glsl" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="include\Camera.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<VCProjectVersion>16.0</VCProjectVersion>
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
@ -96,8 +104,8 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)bin\$(Platform)$(Configuration)</OutDir>
|
<OutDir>$(SolutionDir)bin\$(Platform)$(Configuration)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)bin\intermediates\$(Platform)$(Configuration)</IntDir>
|
<IntDir>$(SolutionDir)bin\intermediates\$(Platform)$(Configuration)\</IntDir>
|
||||||
<LibraryPath>$(SolutionDir)\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)</LibraryPath>
|
<LibraryPath>$(SolutionDir)\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)</LibraryPath>
|
||||||
<IncludePath>$(SolutionDir)\imgui-master;$(SolutionDir)\include;$(SolutionDir)\imgui_master;$(IncludePath)</IncludePath>
|
<IncludePath>$(SolutionDir)\imgui-master;$(SolutionDir)\include;$(SolutionDir)\imgui_master;$(IncludePath)</IncludePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -13,10 +13,29 @@
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Shaders">
|
||||||
|
<UniqueIdentifier>{de7b03ae-538e-4924-978f-dbbf7fd055af}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\Application.cpp">
|
<ClCompile Include="src\Application.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\Camera.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="shaders\parade_vs.glsl">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="shaders\parade_fs.glsl">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="include\Camera.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
glm::vec3 m_position = { 0.f, 0.f, 1.f };
|
||||||
|
glm::vec3 m_front = { 0.f, 0.f, 0.f };
|
||||||
|
glm::vec3 m_up = { 0.f, 1.f, 0.f };
|
||||||
|
glm::vec3 m_right = { 1.f, 0.f, 0.f };
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Since all variables are dependent on each other I've decided to
|
||||||
|
// disable the setters until I make sure they don't break things
|
||||||
|
// glm::vec3& position() { return m_position; }
|
||||||
|
// glm::vec3& front() { return m_front; }
|
||||||
|
// glm::vec3& up() { return m_up; }
|
||||||
|
// glm::vec3& right() { return m_right; }
|
||||||
|
|
||||||
|
const glm::vec3& position() const { return m_position; }
|
||||||
|
const glm::vec3& front() const { return m_front; }
|
||||||
|
const glm::vec3& up() const { return m_up; }
|
||||||
|
const glm::vec3& right() const { return m_right; }
|
||||||
|
|
||||||
|
void pan(float dist_x, float dist_y);
|
||||||
|
void orbit(float yaw, float pitch);
|
||||||
|
void zoom(float dist);
|
||||||
|
};
|
|
@ -0,0 +1,169 @@
|
||||||
|
#version 400
|
||||||
|
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform mat4 V;
|
||||||
|
uniform mat4 M;
|
||||||
|
uniform vec3 cam_pos;
|
||||||
|
uniform int window_width;
|
||||||
|
uniform int window_height;
|
||||||
|
|
||||||
|
uniform vec3 la;
|
||||||
|
uniform vec3 ld;
|
||||||
|
uniform vec3 ls;
|
||||||
|
uniform vec3 ka;
|
||||||
|
uniform vec3 kd;
|
||||||
|
uniform vec3 ks;
|
||||||
|
|
||||||
|
in vec3 v_pos;
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
struct Torus
|
||||||
|
{
|
||||||
|
float R;
|
||||||
|
float r;
|
||||||
|
};
|
||||||
|
|
||||||
|
Torus torus;
|
||||||
|
|
||||||
|
struct Sphere
|
||||||
|
{
|
||||||
|
vec3 center;
|
||||||
|
float r;
|
||||||
|
};
|
||||||
|
|
||||||
|
Sphere sphere;
|
||||||
|
|
||||||
|
void initTorus()
|
||||||
|
{
|
||||||
|
torus.R = 0.5;
|
||||||
|
torus.r = 0.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initSphere()
|
||||||
|
{
|
||||||
|
sphere.center = vec3(0.0, 0.25, 0.0);
|
||||||
|
sphere.r = 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
float sphereSDF(vec3 p, vec3 center, float r) {
|
||||||
|
return length(p - center) - r;
|
||||||
|
}
|
||||||
|
|
||||||
|
float torusSDF(vec3 p, float R, float r) {
|
||||||
|
vec2 q = vec2(length(p.xz) - R, p.y);
|
||||||
|
return length(q) - r;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 estimateNormalsSphere(vec3 p)
|
||||||
|
{
|
||||||
|
float epsilon = 0.001;
|
||||||
|
float x = sphereSDF(vec3(p.x + epsilon, p.y, p.z), sphere.center, sphere.r) - sphereSDF(vec3(p.x - epsilon, p.y, p.z), sphere.center, sphere.r);
|
||||||
|
float y = sphereSDF(vec3(p.x, p.y + epsilon, p.z), sphere.center, sphere.r) - sphereSDF(vec3(p.x, p.y - epsilon, p.z), sphere.center, sphere.r);
|
||||||
|
float z = sphereSDF(vec3(p.x, p.y, p.z + epsilon), sphere.center, sphere.r) - sphereSDF(vec3(p.x, p.y, p.z - epsilon), sphere.center, sphere.r);
|
||||||
|
return normalize(vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 estimateNormalsTorus(vec3 p)
|
||||||
|
{
|
||||||
|
float epsilon = 0.001;
|
||||||
|
float x = torusSDF(vec3(p.x + epsilon, p.y, p.z), torus.R, torus.r) - torusSDF(vec3(p.x - epsilon, p.y, p.z), torus.R, torus.r);
|
||||||
|
float y = torusSDF(vec3(p.x, p.y + epsilon, p.z), torus.R, torus.r) - torusSDF(vec3(p.x, p.y - epsilon, p.z), torus.R, torus.r);
|
||||||
|
float z = torusSDF(vec3(p.x, p.y, p.z + epsilon), torus.R, torus.r) - torusSDF(vec3(p.x, p.y, p.z - epsilon), torus.R, torus.r);
|
||||||
|
return normalize(vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
float smoothMinSDF(float d1, float d2, float k) {
|
||||||
|
float h = max(k - abs(d1 - d2), 0) / k;
|
||||||
|
return min(d1, d2) - h * h * h * k * 1.0 / 6.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float smoothMaxSDF(float d1, float d2, float k) {
|
||||||
|
float h = clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0);
|
||||||
|
return mix(d2, d1, h) - k * h * (1.0 - h);
|
||||||
|
}
|
||||||
|
|
||||||
|
float blendSDF(float d1, float d2) {
|
||||||
|
return (d1 * d2) / (d1 + d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 estimateSmoothNormals(vec3 p, float smoothness) {
|
||||||
|
float epsilon = 0.001;
|
||||||
|
float d = smoothMinSDF(torusSDF(p, torus.R, torus.r), sphereSDF(p, sphere.center, sphere.r), smoothness);
|
||||||
|
float nx = smoothMinSDF(torusSDF(vec3(p.x + epsilon, p.y, p.z), torus.R, torus.r), sphereSDF(vec3(p.x + epsilon, p.y, p.z), sphere.center, sphere.r), smoothness) - d;
|
||||||
|
float ny = smoothMinSDF(torusSDF(vec3(p.x, p.y + epsilon, p.z), torus.R, torus.r), sphereSDF(vec3(p.x, p.y + epsilon, p.z), sphere.center, sphere.r), smoothness) - d;
|
||||||
|
float nz = smoothMinSDF(torusSDF(vec3(p.x, p.y, p.z + epsilon), torus.R, torus.r), sphereSDF(vec3(p.x, p.y, p.z + epsilon), sphere.center, sphere.r), smoothness) - d;
|
||||||
|
return normalize(vec3(nx, ny, nz));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec3 normals;
|
||||||
|
vec3 color = la;
|
||||||
|
vec4 ray_pos = vec4(cam_pos, 1.0);
|
||||||
|
float ray_dist = 0.0;
|
||||||
|
float max_dist = 100.0;
|
||||||
|
float epsilon = 0.001;
|
||||||
|
int steps = 0;
|
||||||
|
int max_steps = 1000;
|
||||||
|
vec3 light_pos = vec3(0.0, 1.0, 0.0);
|
||||||
|
int spec_exponent = 40;
|
||||||
|
|
||||||
|
initTorus();
|
||||||
|
initSphere();
|
||||||
|
|
||||||
|
vec2 ndc_pos = 2.0 * vec2(gl_FragCoord.x / window_width, gl_FragCoord.y / window_height) - 1.0;
|
||||||
|
vec4 cam_dir = inverse(P) * vec4(ndc_pos, 1.0, 1.0);
|
||||||
|
cam_dir /= cam_dir.w;
|
||||||
|
cam_dir = vec4(cam_dir.xyz, 0.0);
|
||||||
|
|
||||||
|
vec4 ray_dir = normalize(inverse(V) * cam_dir);
|
||||||
|
|
||||||
|
while (ray_dist < max_dist && steps < max_steps)
|
||||||
|
{
|
||||||
|
steps++;
|
||||||
|
float distTorus = torusSDF(ray_pos.xyz, torus.R, torus.r);
|
||||||
|
float distSphere = sphereSDF(ray_pos.xyz, sphere.center, sphere.r);
|
||||||
|
float minDist = smoothMinSDF(distTorus, distSphere, 1.0);
|
||||||
|
//bool isTorus = distTorus < distSphere;
|
||||||
|
//float minDist = min(distTorus, distSphere);
|
||||||
|
|
||||||
|
if (minDist <= epsilon)
|
||||||
|
{
|
||||||
|
vec4 ambient_color, diffuse_color;
|
||||||
|
|
||||||
|
ambient_color = vec4(ka, 1.0);
|
||||||
|
diffuse_color = vec4(kd, 1.0);
|
||||||
|
|
||||||
|
vec4 ambient = vec4(la, 1.0) * ambient_color;
|
||||||
|
|
||||||
|
normals = estimateSmoothNormals(ray_pos.xyz, 1.0);
|
||||||
|
|
||||||
|
//if (isTorus)
|
||||||
|
// normals = estimateNormalsTorus(ray_pos.xyz);
|
||||||
|
//else
|
||||||
|
// normals = estimateNormalsSphere(ray_pos.xyz);
|
||||||
|
|
||||||
|
vec3 nw = normalize(normals);
|
||||||
|
vec3 lw = normalize(light_pos - ray_pos.xyz);
|
||||||
|
float dist = length(vec4(ray_pos.xyz - light_pos, 1.0));
|
||||||
|
vec4 diffuse = max(dot(nw, lw), 0) * diffuse_color * vec4(ld, 1.0);
|
||||||
|
|
||||||
|
float spec;
|
||||||
|
vec3 vw = normalize(cam_pos - ray_pos.xyz);
|
||||||
|
|
||||||
|
vec3 halfwayDir = normalize(lw + vw);
|
||||||
|
spec = pow(max(dot(halfwayDir, nw), 0), spec_exponent);
|
||||||
|
|
||||||
|
vec4 specular = spec * vec4(ks * ls, 1.0);
|
||||||
|
|
||||||
|
color = (ambient + (1.0 / (dist * dist) * (diffuse + specular))).xyz;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ray_pos += ray_dir * minDist;
|
||||||
|
ray_dist += minDist;
|
||||||
|
}
|
||||||
|
|
||||||
|
FragColor = vec4(color, 1.0);
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
#version 400
|
||||||
|
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform mat4 V;
|
||||||
|
uniform mat4 M;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 pos_attrib;
|
||||||
|
|
||||||
|
out vec3 v_pos;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = vec4(pos_attrib, 1.0);
|
||||||
|
//v_pos = pos_attrib;
|
||||||
|
}
|
|
@ -1,8 +1,152 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtx/transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include <Camera.h>
|
||||||
|
|
||||||
|
float vertices[] = {
|
||||||
|
-0.5f, -0.5f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.0f,
|
||||||
|
0.0f, 0.5f, 0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
float canvas[] = {
|
||||||
|
-1.0f, 1.0f, 0.0f,
|
||||||
|
-1.0f, -1.0f, 0.0f,
|
||||||
|
1.0f, 1.0f, 0.0f,
|
||||||
|
1.0f, -1.0f, 0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int VBO;
|
||||||
|
unsigned int VAO;
|
||||||
|
|
||||||
|
namespace window
|
||||||
|
{
|
||||||
|
int size[] = { 800, 600 };
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace scene
|
||||||
|
{
|
||||||
|
Camera camera;
|
||||||
|
unsigned int shader = -1;
|
||||||
|
|
||||||
|
float angle = glm::pi<float>() / 2.0;
|
||||||
|
|
||||||
|
float yaw = -90.f;
|
||||||
|
float pitch = 0.f;
|
||||||
|
|
||||||
|
glm::vec3 Lp = { 0.f, 1.f, 0.f }; // Light position
|
||||||
|
glm::vec3 La = { 124.0 / 255.0, 114.0 / 255.0, 160.0 / 255.0 }; // Light ambient color
|
||||||
|
glm::vec3 Ld = { 1.f, 1.f, 1.f }; // Light diffuse color
|
||||||
|
glm::vec3 Ls = { 1.f, 1.f, 1.f }; // Light specular color
|
||||||
|
|
||||||
|
glm::vec3 ka = { 0.25f, 0.25f, 0.25f }; // Object ambient color
|
||||||
|
glm::vec3 kd = { 193.0 / 255.0, 41.0 / 255.0, 46.0 / 255.0 }; // Object diffuse color
|
||||||
|
glm::vec3 ks = { 1.0f, 1.0f, 1.0f }; // Object specular color
|
||||||
|
int specular_exponent = 10.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace mouse
|
||||||
|
{
|
||||||
|
bool altPressed = false;
|
||||||
|
|
||||||
|
double xlast;
|
||||||
|
double ylast;
|
||||||
|
double xoffset;
|
||||||
|
double yoffset;
|
||||||
|
|
||||||
|
float sensitivity = 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create a NULL-terminated string by reading the provided file
|
||||||
|
static char* ReadShaderSource(const char* shaderFile)
|
||||||
|
{
|
||||||
|
std::ifstream ifs(shaderFile, std::ios::in | std::ios::binary | std::ios::ate);
|
||||||
|
if (ifs.is_open())
|
||||||
|
{
|
||||||
|
unsigned int filesize = static_cast<unsigned int>(ifs.tellg());
|
||||||
|
ifs.seekg(0, std::ios::beg);
|
||||||
|
char* bytes = new char[filesize + 1];
|
||||||
|
memset(bytes, 0, filesize + 1);
|
||||||
|
ifs.read(bytes, filesize);
|
||||||
|
ifs.close();
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int CompileShader(unsigned int type, const std::string& source)
|
||||||
|
{
|
||||||
|
unsigned int id = glCreateShader(type);
|
||||||
|
const char* src = source.c_str();
|
||||||
|
glShaderSource(id, 1, &src, nullptr);
|
||||||
|
glCompileShader(id);
|
||||||
|
|
||||||
|
int result;
|
||||||
|
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||||
|
if (result == GL_FALSE)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
|
||||||
|
char* message = (char*)alloca(length * sizeof(char));
|
||||||
|
glGetShaderInfoLog(id, length, &length, message);
|
||||||
|
std::cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader!" << std::endl;
|
||||||
|
std::cout << message << std::endl;
|
||||||
|
glDeleteShader(id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int CreateShader(const std::string& vertexShaderFile, const std::string& fragmentShaderFile)
|
||||||
|
{
|
||||||
|
std::string vertexShader = ReadShaderSource(vertexShaderFile.c_str());
|
||||||
|
std::string fragmentShader = ReadShaderSource(fragmentShaderFile.c_str());
|
||||||
|
GLuint program = glCreateProgram();
|
||||||
|
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
|
||||||
|
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
|
||||||
|
|
||||||
|
glAttachShader(program, vs);
|
||||||
|
glAttachShader(program, fs);
|
||||||
|
glLinkProgram(program);
|
||||||
|
glValidateProgram(program);
|
||||||
|
|
||||||
|
glDeleteShader(vs);
|
||||||
|
glDeleteShader(fs);
|
||||||
|
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitCanvas()
|
||||||
|
{
|
||||||
|
glBindAttribLocation(scene::shader, 0, "pos_attrib");
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &VAO);
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
glGenBuffers(1, &VBO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(canvas), canvas, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, 0, 0, 0);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void idle()
|
void idle()
|
||||||
{
|
{
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
@ -10,10 +154,61 @@ void idle()
|
||||||
|
|
||||||
void display(GLFWwindow* window)
|
void display(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
glfwSwapBuffers(window);
|
glClearColor(1.0f, 0.f, 1.0f, 1.0f);
|
||||||
|
|
||||||
glClearColor(0.1f, 0.1f, 0.18f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
glm::mat4 M = glm::rotate(scene::angle, glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
|
glm::mat4 V = glm::lookAt(scene::camera.position(), scene::camera.front(), scene::camera.up());
|
||||||
|
glm::mat4 P = glm::perspective(glm::pi<float>() / 2.0f, (float)window::size[0] / (float)window::size[1], 0.1f, 100.0f);
|
||||||
|
|
||||||
|
glViewport(0, 0, window::size[0], window::size[1]);
|
||||||
|
|
||||||
|
int P_loc = glGetUniformLocation(scene::shader, "P");
|
||||||
|
if (P_loc != -1)
|
||||||
|
{
|
||||||
|
glUniformMatrix4fv(P_loc, 1, false, glm::value_ptr(P));
|
||||||
|
}
|
||||||
|
int V_loc = glGetUniformLocation(scene::shader, "V");
|
||||||
|
if (V_loc != -1)
|
||||||
|
{
|
||||||
|
glUniformMatrix4fv(V_loc, 1, false, glm::value_ptr(V));
|
||||||
|
}
|
||||||
|
int M_loc = glGetUniformLocation(scene::shader, "M");
|
||||||
|
if (M_loc != -1)
|
||||||
|
{
|
||||||
|
glUniformMatrix4fv(M_loc, 1, false, glm::value_ptr(M));
|
||||||
|
}
|
||||||
|
int cam_pos_loc = glGetUniformLocation(scene::shader, "cam_pos");
|
||||||
|
if (cam_pos_loc != -1)
|
||||||
|
{
|
||||||
|
glUniform3fv(cam_pos_loc, 1, glm::value_ptr(scene::camera.position()));
|
||||||
|
}
|
||||||
|
int window_width_loc = glGetUniformLocation(scene::shader, "window_width");
|
||||||
|
if (window_width_loc != -1)
|
||||||
|
{
|
||||||
|
glUniform1i(window_width_loc, window::size[0]);
|
||||||
|
}
|
||||||
|
int window_height_loc = glGetUniformLocation(scene::shader, "window_height");
|
||||||
|
if (window_height_loc != -1)
|
||||||
|
{
|
||||||
|
glUniform1i(window_height_loc, window::size[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
glUniform3fv(glGetUniformLocation(scene::shader, "light_pos"), 1, glm::value_ptr(scene::Lp));
|
||||||
|
glUniform3fv(glGetUniformLocation(scene::shader, "la"), 1, glm::value_ptr(scene::La));
|
||||||
|
glUniform3fv(glGetUniformLocation(scene::shader, "ld"), 1, glm::value_ptr(scene::Ld));
|
||||||
|
glUniform3fv(glGetUniformLocation(scene::shader, "ls"), 1, glm::value_ptr(scene::Ls));
|
||||||
|
|
||||||
|
glUniform3fv(glGetUniformLocation(scene::shader, "ka"), 1, glm::value_ptr(scene::ka));
|
||||||
|
glUniform3fv(glGetUniformLocation(scene::shader, "kd"), 1, glm::value_ptr(scene::kd));
|
||||||
|
glUniform3fv(glGetUniformLocation(scene::shader, "ks"), 1, glm::value_ptr(scene::ks));
|
||||||
|
glUniform1i(glGetUniformLocation(scene::shader, "spec_exponent"), scene::specular_exponent);
|
||||||
|
|
||||||
|
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, sizeof(vertices) / 3);
|
||||||
|
|
||||||
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||||
|
@ -25,27 +220,105 @@ void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, in
|
||||||
case GLFW_KEY_ESCAPE:
|
case GLFW_KEY_ESCAPE:
|
||||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||||
break;
|
break;
|
||||||
|
case GLFW_KEY_LEFT_ALT:
|
||||||
|
mouse::altPressed = true;
|
||||||
|
break;
|
||||||
|
case GLFW_KEY_RIGHT_ALT:
|
||||||
|
mouse::altPressed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == GLFW_RELEASE)
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case GLFW_KEY_LEFT_ALT:
|
||||||
|
mouse::altPressed = false;
|
||||||
|
break;
|
||||||
|
case GLFW_KEY_RIGHT_ALT:
|
||||||
|
mouse::altPressed = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
void orbit_camera()
|
||||||
{
|
{
|
||||||
glViewport(0, 0, width, height);
|
scene::yaw += mouse::xoffset;
|
||||||
|
scene::pitch += mouse::yoffset;
|
||||||
|
|
||||||
|
scene::camera.orbit(scene::yaw, scene::pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pan_camera()
|
||||||
|
{
|
||||||
|
float translateSensitivity = 0.02;
|
||||||
|
|
||||||
|
scene::camera.pan((float)mouse::xoffset * -translateSensitivity, (float)mouse::yoffset * translateSensitivity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void zoom_camera()
|
||||||
|
{
|
||||||
|
scene::camera.zoom((float)mouse::yoffset * 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cursor_offset(double xcurrent, double ycurrent)
|
||||||
|
{
|
||||||
|
mouse::xoffset = xcurrent - mouse::xlast;
|
||||||
|
mouse::yoffset = ycurrent - mouse::ylast;
|
||||||
|
mouse::xlast = xcurrent;
|
||||||
|
mouse::ylast = ycurrent;
|
||||||
|
|
||||||
|
mouse::xoffset *= mouse::sensitivity;
|
||||||
|
mouse::yoffset *= mouse::sensitivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
//This function gets called when the mouse moves over the window.
|
||||||
|
void cursor_pos_callback(GLFWwindow* window, double x, double y)
|
||||||
|
{
|
||||||
|
if (mouse::altPressed)
|
||||||
|
{
|
||||||
|
cursor_offset(x, y);
|
||||||
|
|
||||||
|
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) orbit_camera();
|
||||||
|
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS) pan_camera();
|
||||||
|
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS) zoom_camera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//This function gets called when a mouse button is pressed.
|
||||||
|
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||||
|
{
|
||||||
|
//std::cout << "button : " << button << ", action: " << action << ", mods: " << mods << std::endl;
|
||||||
|
if (action == GLFW_PRESS) glfwGetCursorPos(window, &mouse::xlast, &mouse::ylast);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
|
||||||
|
{
|
||||||
|
scene::camera.zoom((float)yoffset * -0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||||
|
//{
|
||||||
|
// window::size[0] = width;
|
||||||
|
// window::size[1] = height;
|
||||||
|
// glViewport(0, 0, width, height);
|
||||||
|
//}
|
||||||
|
|
||||||
|
void window_size_callback(GLFWwindow* window, int width, int height)
|
||||||
|
{
|
||||||
|
window::size[0] = width;
|
||||||
|
window::size[1] = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
float vertices[] = {
|
glewInit();
|
||||||
-0.5f, -0.5f, 0.0f,
|
scene::shader = CreateShader("shaders/parade_vs.glsl", "shaders/parade_fs.glsl");
|
||||||
0.5f, -0.5f, 0.0f,
|
glUseProgram(scene::shader);
|
||||||
0.0f, 0.5f, 0.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned int VBO;
|
InitCanvas();
|
||||||
glGenBuffers(1, &VBO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
@ -55,7 +328,7 @@ int main()
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
|
||||||
GLFWwindow* window = glfwCreateWindow(800, 600, "Parade", nullptr, nullptr);
|
GLFWwindow* window = glfwCreateWindow(window::size[0], window::size[1], "Parade", nullptr, nullptr);
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
std::cout << "Failed to create window" << std::endl;
|
std::cout << "Failed to create window" << std::endl;
|
||||||
|
@ -64,10 +337,13 @@ int main()
|
||||||
}
|
}
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
|
|
||||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
//glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||||
glfwSetKeyCallback(window, keyboard_callback);
|
glfwSetKeyCallback(window, keyboard_callback);
|
||||||
|
glfwSetCursorPosCallback(window, cursor_pos_callback);
|
||||||
|
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||||
|
glfwSetScrollCallback(window, scroll_callback);
|
||||||
|
glfwSetWindowSizeCallback(window, window_size_callback);
|
||||||
|
|
||||||
glewInit();
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "Camera.h"
|
||||||
|
|
||||||
|
void Camera::pan(float dist_x, float dist_y) {
|
||||||
|
m_front += m_right * dist_x;
|
||||||
|
m_position += m_right * dist_x;
|
||||||
|
|
||||||
|
m_front += m_up * dist_y;
|
||||||
|
m_position += m_up * dist_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::orbit(float yaw, float pitch) {
|
||||||
|
glm::vec3 direction;
|
||||||
|
|
||||||
|
direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
|
||||||
|
direction.y = -sin(glm::radians(pitch));
|
||||||
|
direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
|
||||||
|
|
||||||
|
m_right.x = cos(glm::radians(yaw + 90.f));
|
||||||
|
m_right.z = sin(glm::radians(yaw + 90.f));
|
||||||
|
m_right = glm::normalize(m_right);
|
||||||
|
|
||||||
|
m_position = m_front - glm::normalize(direction) * glm::length(m_position - m_front);
|
||||||
|
m_up = glm::cross(m_right, glm::normalize(m_front - m_position));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::zoom(float dist) {
|
||||||
|
m_position += (m_position - m_front) * dist;
|
||||||
|
if (glm::length(m_position - m_front) > 100.f) {
|
||||||
|
m_position = glm::normalize(m_position) * 100.f + m_front;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue