Added shaders got smooth min working
This commit is contained in:
parent
db4fcead4f
commit
d534be6ee1
|
@ -20,6 +20,14 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
|
@ -96,8 +104,8 @@
|
|||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)$(Configuration)</OutDir>
|
||||
<IntDir>$(SolutionDir)bin\intermediates\$(Platform)$(Configuration)</IntDir>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)bin\intermediates\$(Platform)$(Configuration)\</IntDir>
|
||||
<LibraryPath>$(SolutionDir)\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)</LibraryPath>
|
||||
<IncludePath>$(SolutionDir)\imgui-master;$(SolutionDir)\include;$(SolutionDir)\imgui_master;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -13,10 +13,29 @@
|
|||
<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>
|
||||
</Filter>
|
||||
<Filter Include="Shaders">
|
||||
<UniqueIdentifier>{de7b03ae-538e-4924-978f-dbbf7fd055af}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Application.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</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>
|
||||
</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 <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <GL/glew.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()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
@ -10,10 +154,61 @@ void idle()
|
|||
|
||||
void display(GLFWwindow* window)
|
||||
{
|
||||
glfwSwapBuffers(window);
|
||||
|
||||
glClearColor(0.1f, 0.1f, 0.18f, 1.0f);
|
||||
glClearColor(1.0f, 0.f, 1.0f, 1.0f);
|
||||
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)
|
||||
|
@ -25,27 +220,105 @@ void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, in
|
|||
case GLFW_KEY_ESCAPE:
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
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()
|
||||
{
|
||||
float vertices[] = {
|
||||
-0.5f, -0.5f, 0.0f,
|
||||
0.5f, -0.5f, 0.0f,
|
||||
0.0f, 0.5f, 0.0f
|
||||
};
|
||||
glewInit();
|
||||
scene::shader = CreateShader("shaders/parade_vs.glsl", "shaders/parade_fs.glsl");
|
||||
glUseProgram(scene::shader);
|
||||
|
||||
unsigned int VBO;
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
InitCanvas();
|
||||
}
|
||||
|
||||
int main()
|
||||
|
@ -55,7 +328,7 @@ int main()
|
|||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
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)
|
||||
{
|
||||
std::cout << "Failed to create window" << std::endl;
|
||||
|
@ -64,10 +337,13 @@ int main()
|
|||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
//glfwSetFramebufferSizeCallback(window, framebuffer_size_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();
|
||||
|
||||
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