Feature Complete Private
This commit is contained in:
parent
85583a8880
commit
3887733e67
6
.gitignore
vendored
6
.gitignore
vendored
@ -1 +1,7 @@
|
|||||||
ExternalResources
|
ExternalResources
|
||||||
|
|
||||||
|
Abgabe
|
||||||
|
|
||||||
|
963830_rohmenf.zip
|
||||||
|
|
||||||
|
bugs.md
|
||||||
112
RubiksCube/Camera.h
Normal file
112
RubiksCube/Camera.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
class Camera : public Entity {
|
||||||
|
private:
|
||||||
|
GLFWwindow* _window;
|
||||||
|
InputSystem* _inputSystem;
|
||||||
|
|
||||||
|
glm::mat4 _view;
|
||||||
|
glm::mat4 _projection;
|
||||||
|
|
||||||
|
glm::quat _orientation;
|
||||||
|
|
||||||
|
glm::vec2 _dragStart;
|
||||||
|
bool _wasMouseClicked;
|
||||||
|
|
||||||
|
float _scrollPositionPrevious;
|
||||||
|
float _scrollPositionDelta;
|
||||||
|
|
||||||
|
static inline float cameraDistance = 8.15f;
|
||||||
|
|
||||||
|
static inline Camera* _instance;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const glm::mat4& View() const { return _view * glm::mat4_cast(_orientation); }
|
||||||
|
const glm::mat4& Projection() const { return _projection; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
Camera(GLFWwindow* window, InputSystem* inputSystem) : Entity(nullptr) {
|
||||||
|
_instance = this;
|
||||||
|
_window = window;
|
||||||
|
_inputSystem = inputSystem;
|
||||||
|
|
||||||
|
_wasMouseClicked = false;
|
||||||
|
|
||||||
|
_view = glm::lookAt(glm::vec3(0.0f, 0.0f, cameraDistance), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
_projection = glm::mat4(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(double deltaTime) override {
|
||||||
|
int screenWidth;
|
||||||
|
int screenHeight;
|
||||||
|
|
||||||
|
glfwGetFramebufferSize(_window, &screenWidth, &screenHeight);
|
||||||
|
|
||||||
|
float aspec = (float)screenWidth / (float)screenHeight;
|
||||||
|
|
||||||
|
_projection = glm::perspective(glm::radians(45.0f), aspec, 0.1f, 100.0f);
|
||||||
|
|
||||||
|
if (_inputSystem->WasKeyPressed(GLFW_KEY_SPACE))
|
||||||
|
_orientation = glm::quat(1.0f, glm::vec3(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
glm::fvec2 velocity(0.0f, 0.0f);
|
||||||
|
if (_inputSystem->IsKeyPressed(GLFW_KEY_UP))
|
||||||
|
velocity.x = glm::radians(90.0f);
|
||||||
|
if (_inputSystem->IsKeyPressed(GLFW_KEY_DOWN))
|
||||||
|
velocity.x = glm::radians(-90.0f);
|
||||||
|
|
||||||
|
if (_inputSystem->IsKeyPressed(GLFW_KEY_RIGHT))
|
||||||
|
velocity.y = glm::radians(90.0f);
|
||||||
|
if (_inputSystem->IsKeyPressed(GLFW_KEY_LEFT))
|
||||||
|
velocity.y = glm::radians(-90.0f);
|
||||||
|
|
||||||
|
if (!_wasMouseClicked && _inputSystem->IsRightMouseDown()) {
|
||||||
|
_inputSystem->GetMousePos(_dragStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_wasMouseClicked && _inputSystem->IsRightMouseDown()) {
|
||||||
|
glm::vec2 currentMousePositions;
|
||||||
|
_inputSystem->GetMousePos(currentMousePositions);
|
||||||
|
glm::vec2 dragDiff = currentMousePositions - _dragStart;
|
||||||
|
_dragStart = currentMousePositions;
|
||||||
|
|
||||||
|
_orientation = glm::quat(1.0f, glm::vec3(dragDiff.y, dragDiff.x, 0.0f) * 0.008f) * _orientation;
|
||||||
|
_orientation = glm::normalize(_orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
_wasMouseClicked = _inputSystem->IsRightMouseDown();
|
||||||
|
|
||||||
|
glm::quat velocityQuaternion = glm::quat(0.0f, glm::vec3(velocity.x, velocity.y, 0.0f));
|
||||||
|
|
||||||
|
_orientation += 0.5f * (float)deltaTime * velocityQuaternion * _orientation;
|
||||||
|
_orientation = glm::normalize(_orientation);
|
||||||
|
|
||||||
|
_view = glm::translate(_view, glm::vec3(0.0f, 0.0f, _scrollPositionDelta));
|
||||||
|
_scrollPositionDelta = 0.0f;
|
||||||
|
|
||||||
|
// since callbacks need to be static use a singleton
|
||||||
|
glfwSetScrollCallback(_window, Camera::scrollCallbackGlobal);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scrollCallbackGlobal(GLFWwindow* window, double xOffset, double yOffset) {
|
||||||
|
_instance->scrollCallback(window, xOffset, yOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scrollCallback(GLFWwindow* window, double xOffset, double yOffset) {
|
||||||
|
_scrollPositionDelta = yOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAspectRatio(float aspec) {
|
||||||
|
_projection = glm::perspective(glm::radians(45.0f), aspec, 0.1f, 100.0f);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,9 +1,7 @@
|
|||||||
#include "Cube.h"
|
#include "Cube.h"
|
||||||
|
|
||||||
Cube::Cube()
|
Cube::Cube() : Entity(nullptr)
|
||||||
{
|
{
|
||||||
this->_transform = glm::mat4(1.0f);
|
|
||||||
|
|
||||||
for(int x=-1;x<=1;x++) {
|
for(int x=-1;x<=1;x++) {
|
||||||
for(int y=-1;y<=1;y++) {
|
for(int y=-1;y<=1;y++) {
|
||||||
for(int z=-1;z<=1;z++) {
|
for(int z=-1;z<=1;z++) {
|
||||||
@ -35,7 +33,7 @@ Cube::Cube()
|
|||||||
sideColors[Side::Forward] = SideColor[Side::Forward];
|
sideColors[Side::Forward] = SideColor[Side::Forward];
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionedCube* cubeAtIndex = new PartitionedCube(glm::vec3(x, y, z), sideColors);
|
PartitionedCube* cubeAtIndex = new PartitionedCube(this, glm::vec3(x, y, z), sideColors);
|
||||||
|
|
||||||
this->_children[x + 1][y + 1][z + 1] = cubeAtIndex;
|
this->_children[x + 1][y + 1][z + 1] = cubeAtIndex;
|
||||||
}
|
}
|
||||||
@ -53,20 +51,6 @@ Cube::~Cube() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cube::Update(double deltaTime) {
|
|
||||||
for(int x=0;x<3;x++) {
|
|
||||||
for(int y=0;y<3;y++) {
|
|
||||||
for(int z=0;z<3;z++) {
|
|
||||||
_children[x][y][z]->Update(deltaTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cube::Transform(glm::mat4 transform) {
|
|
||||||
this->_transform *= transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cube::_FindAxisChildren(const glm::ivec3& axis, int index, std::vector<glm::ivec3>& result) const {
|
void Cube::_FindAxisChildren(const glm::ivec3& axis, int index, std::vector<glm::ivec3>& result) const {
|
||||||
glm::ivec3 orientationBuffer[3] = {
|
glm::ivec3 orientationBuffer[3] = {
|
||||||
axis,
|
axis,
|
||||||
@ -83,12 +67,20 @@ void Cube::_FindAxisChildren(const glm::ivec3& axis, int index, std::vector<glm:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cube::_TransformData(const glm::ivec3& axis, int index, const glm::mat3& transform) {
|
void Cube::TransformData(const glm::ivec3& axis, int index, int turns) {
|
||||||
PartitionedCube* previousCubeList[3][3][3];
|
PartitionedCube* previousCubeList[3][3][3];
|
||||||
memcpy(previousCubeList, this->_children, sizeof(this->_children));
|
memcpy(previousCubeList, this->_children, sizeof(this->_children));
|
||||||
|
|
||||||
std::vector<glm::ivec3> result;
|
std::vector<glm::ivec3> result;
|
||||||
|
|
||||||
|
glm::mat3 transform = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f) * turns, glm::vec3(axis));
|
||||||
|
|
||||||
|
for(int x=0;x<3;x++) {
|
||||||
|
for(int y=0;y<3;y++) {
|
||||||
|
transform[x][y] = lroundf(transform[x][y]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_FindAxisChildren(axis, index, result);
|
_FindAxisChildren(axis, index, result);
|
||||||
|
|
||||||
for(auto& position : result) {
|
for(auto& position : result) {
|
||||||
@ -98,20 +90,22 @@ void Cube::_TransformData(const glm::ivec3& axis, int index, const glm::mat3& tr
|
|||||||
newPosition += glm::ivec3(1);
|
newPosition += glm::ivec3(1);
|
||||||
|
|
||||||
_children[newPosition.x][newPosition.y][newPosition.z] = previousCubeList[position.x][position.y][position.z];
|
_children[newPosition.x][newPosition.y][newPosition.z] = previousCubeList[position.x][position.y][position.z];
|
||||||
|
|
||||||
|
_children[newPosition.x][newPosition.y][newPosition.z]->TransformData(axis, turns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cube::Transform(const glm::ivec3& axis, int index, const glm::mat3& transform) {
|
void Cube::Transform(const glm::ivec3& axis, int index, const glm::mat3& transform) {
|
||||||
_TransformData(axis, index, transform);
|
// _TransformData(axis, index, transform);
|
||||||
|
|
||||||
std::vector<glm::ivec3> result;
|
std::vector<glm::ivec3> result;
|
||||||
|
|
||||||
_FindAxisChildren(transform * axis, index, result);
|
_FindAxisChildren(axis, index, result);
|
||||||
|
|
||||||
for(auto& position : result) {
|
for(auto& position : result) {
|
||||||
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
|
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
|
||||||
|
|
||||||
cube->Transform(glm::mat4(transform));
|
cube->TransformLocal(glm::mat4(transform));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,16 +117,29 @@ void Cube::TransformTemp(const glm::ivec3& axis, int index, const glm::mat3& tra
|
|||||||
for(auto& position : result) {
|
for(auto& position : result) {
|
||||||
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
|
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
|
||||||
|
|
||||||
cube->Transform(glm::mat4(transform));
|
cube->TransformTemp(glm::mat4(transform));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cube::TransformAnimation(const glm::ivec3& axis, int index, const glm::mat3& transform, float duration) {
|
void Cube::UndoTransformTemp()
|
||||||
_TransformData(axis, index, transform);
|
{
|
||||||
|
for(int x=0;x<3;x++) {
|
||||||
|
for(int y=0;y<3;y++) {
|
||||||
|
for(int z=0;z<3;z++) {
|
||||||
|
_children[x][y][z]->UndoTransformTemp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cube::TransformAnimation(const glm::ivec3& axis, int index, float angle, float duration) {
|
||||||
|
// _TransformData(axis, index, transform);
|
||||||
|
|
||||||
std::vector<glm::ivec3> result;
|
std::vector<glm::ivec3> result;
|
||||||
|
|
||||||
_FindAxisChildren(transform * axis, index, result);
|
_FindAxisChildren(axis, index, result);
|
||||||
|
|
||||||
|
glm::quat transform = glm::angleAxis(angle, glm::vec3(axis));
|
||||||
|
|
||||||
for(auto& position : result) {
|
for(auto& position : result) {
|
||||||
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
|
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
|
||||||
|
|||||||
@ -1,36 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
#include "PartitionedCube.h"
|
#include "PartitionedCube.h"
|
||||||
|
|
||||||
// Colors according to https://ruwix.com/the-rubiks-cube/japanese-western-color-schemes/
|
// Colors according to https://ruwix.com/the-rubiks-cube/japanese-western-color-schemes/
|
||||||
class Cube
|
class Cube : public Entity
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
glm::mat4 _transform;
|
|
||||||
|
|
||||||
PartitionedCube* _children[3][3][3];
|
PartitionedCube* _children[3][3][3];
|
||||||
|
|
||||||
void _TransformData(const glm::ivec3& axis, int index, const glm::mat3& transform);
|
|
||||||
|
|
||||||
void _FindAxisChildren(const glm::ivec3& axis, int index, std::vector<glm::ivec3>& result) const;
|
void _FindAxisChildren(const glm::ivec3& axis, int index, std::vector<glm::ivec3>& result) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Cube();
|
Cube();
|
||||||
~Cube();
|
virtual ~Cube();
|
||||||
|
|
||||||
void Update(double deltaTime);
|
|
||||||
|
|
||||||
const int ChildPartitionsCount = 27;
|
const int ChildPartitionsCount = 27;
|
||||||
PartitionedCube** Children() { return &(_children[0][0][0]); }
|
PartitionedCube** Children() { return &(_children[0][0][0]); }
|
||||||
|
|
||||||
const glm::mat4& Transform() const { return _transform; }
|
void TransformData(const glm::ivec3& axis, int index, int turns);
|
||||||
|
void TransformAnimation(const glm::ivec3& axis, int index, float angle, float duration);
|
||||||
void TransformAnimation(const glm::ivec3& axis, int index, const glm::mat3& transform, float duration);
|
|
||||||
void Transform(const glm::ivec3& axis, int index, const glm::mat3& transform);
|
void Transform(const glm::ivec3& axis, int index, const glm::mat3& transform);
|
||||||
void TransformTemp(const glm::ivec3& axis, int index, const glm::mat3& transform);
|
void TransformTemp(const glm::ivec3& axis, int index, const glm::mat3& transform);
|
||||||
void Transform(glm::mat4 transform);
|
void UndoTransformTemp();
|
||||||
|
|
||||||
static constexpr Color SideColor[6] = {
|
static constexpr Color SideColor[6] = {
|
||||||
Color::ORANGE(),
|
Color::ORANGE(),
|
||||||
|
|||||||
68
RubiksCube/Debug.cpp
Normal file
68
RubiksCube/Debug.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include "Debug.h"
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
|
void Debug::Render(DefaultUniform& uniform)
|
||||||
|
{
|
||||||
|
RenderLines(uniform);
|
||||||
|
|
||||||
|
_lines.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debug::RenderLines(DefaultUniform& uniform) const
|
||||||
|
{
|
||||||
|
glUseProgram(_shader);
|
||||||
|
glBindVertexArray(_vba);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||||
|
|
||||||
|
int vertexCount = _lines.size() * 6;
|
||||||
|
|
||||||
|
int viewportWidth, viewportHeight;
|
||||||
|
glfwGetFramebufferSize(_window, &viewportWidth, &viewportHeight);
|
||||||
|
|
||||||
|
glm::vec2 viewport = glm::vec2(viewportWidth, viewportHeight);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
glUniform2fv(_uniformViewportRes, 1, glm::value_ptr(viewport));
|
||||||
|
glUniformMatrix4fv(_uniformModel, 1, GL_FALSE, glm::value_ptr(uniform.model));
|
||||||
|
glUniformMatrix4fv(_uniformView, 1, GL_FALSE, glm::value_ptr(uniform.view));
|
||||||
|
glUniformMatrix4fv(_uniformProjection, 1, GL_FALSE, glm::value_ptr(uniform.projection));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DebugVertexData* data = new DebugVertexData[vertexCount];
|
||||||
|
int index = 0;
|
||||||
|
for(const auto& line : _lines) {
|
||||||
|
int vertexIndex = index * 6;
|
||||||
|
|
||||||
|
glm::vec3 quad[4] = {
|
||||||
|
line.positionFirst,
|
||||||
|
line.positionFirst,
|
||||||
|
line.positionLast,
|
||||||
|
line.positionLast
|
||||||
|
};
|
||||||
|
|
||||||
|
glm::vec3 direction = line.positionLast - line.positionFirst;
|
||||||
|
|
||||||
|
data[ vertexIndex + 0 ] = DebugVertexData { quad[0], direction, line.color, line.lineWidth };
|
||||||
|
data[ vertexIndex + 1 ] = DebugVertexData { quad[1], direction, line.color, line.lineWidth };
|
||||||
|
data[ vertexIndex + 2 ] = DebugVertexData { quad[2], direction, line.color, line.lineWidth };
|
||||||
|
data[ vertexIndex + 3 ] = DebugVertexData { quad[1], direction, line.color, line.lineWidth };
|
||||||
|
data[ vertexIndex + 4 ] = DebugVertexData { quad[2], direction, line.color, line.lineWidth };
|
||||||
|
data[ vertexIndex + 5 ] = DebugVertexData { quad[3], direction, line.color, line.lineWidth };
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(DebugVertexData) * vertexCount, data, GL_STATIC_DRAW);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glUseProgram(0);
|
||||||
|
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
146
RubiksCube/Debug.h
Normal file
146
RubiksCube/Debug.h
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Color.h"
|
||||||
|
|
||||||
|
#include "ShaderUtil.h"
|
||||||
|
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
#include <gl/glew.h>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct GLFWwindow;
|
||||||
|
|
||||||
|
struct DebugLine {
|
||||||
|
glm::vec3 positionFirst;
|
||||||
|
glm::vec3 positionLast;
|
||||||
|
float lineWidth;
|
||||||
|
Color color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DebugPoint {
|
||||||
|
glm::vec3 position;
|
||||||
|
Color color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DebugDirection {
|
||||||
|
glm::vec3 origin;
|
||||||
|
glm::vec3 direction;
|
||||||
|
float lineWidth;
|
||||||
|
Color color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DebugVertexData {
|
||||||
|
glm::vec3 v;
|
||||||
|
glm::vec3 tangent;
|
||||||
|
Color color;
|
||||||
|
float lineWidth;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Debug : public Entity
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<DebugLine> _lines;
|
||||||
|
std::vector<DebugPoint> _points;
|
||||||
|
|
||||||
|
GLFWwindow* _window;
|
||||||
|
|
||||||
|
GLuint _vba;
|
||||||
|
GLuint _vbo;
|
||||||
|
GLuint _shader;
|
||||||
|
|
||||||
|
GLuint _uniformViewportRes;
|
||||||
|
GLuint _uniformModel;
|
||||||
|
GLuint _uniformView;
|
||||||
|
GLuint _uniformProjection;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Debug() : Entity(nullptr) { }
|
||||||
|
Debug(GLFWwindow* window) : Entity(nullptr) {
|
||||||
|
_window = window;
|
||||||
|
|
||||||
|
glGenBuffers(1, &_vbo);
|
||||||
|
glGenVertexArrays(1, &_vba);
|
||||||
|
glBindVertexArray(_vba);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, v));
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, tangent));
|
||||||
|
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, color));
|
||||||
|
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, lineWidth));
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
glEnableVertexAttribArray(3);
|
||||||
|
|
||||||
|
_shader = ShaderUtil::CreateShaderProgram("line.vert", "line.frag");
|
||||||
|
|
||||||
|
_uniformViewportRes = glGetUniformLocation(_shader, "uViewportRes");
|
||||||
|
_uniformModel = glGetUniformLocation(_shader, "model");
|
||||||
|
_uniformView = glGetUniformLocation(_shader, "view");
|
||||||
|
_uniformProjection = glGetUniformLocation(_shader, "projection");
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
Instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Debug() {
|
||||||
|
glDeleteVertexArrays(1, &_vba);
|
||||||
|
glDeleteBuffers(1, &_vbo);
|
||||||
|
glDeleteProgram(_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Render(DefaultUniform& uniform) override;
|
||||||
|
void RenderLines(DefaultUniform& uniform) const;
|
||||||
|
|
||||||
|
static inline Debug* Instance;
|
||||||
|
|
||||||
|
void Line(const glm::vec3& positionFirst, const glm::vec3& positionLast, const Color& color) {
|
||||||
|
_lines.push_back(DebugLine { positionFirst, positionLast, 1.0f, color });
|
||||||
|
}
|
||||||
|
|
||||||
|
void Direction(const glm::vec3& origin, const glm::vec3& direction, const Color& color) {
|
||||||
|
glm::vec4 capWorldPos = glm::vec4(origin + direction * 1.0f, 1.0f);
|
||||||
|
|
||||||
|
_lines.push_back(DebugLine { origin, capWorldPos, 8.0f, color });
|
||||||
|
|
||||||
|
glm::vec3 up = glm::vec3(direction[1], direction[2], direction[0]);
|
||||||
|
|
||||||
|
glm::vec3 capOffsets[4] = {
|
||||||
|
glm::vec3( 1.0f, 1.0f, -1.0f),
|
||||||
|
glm::vec3(-1.0f, 1.0f, -1.0f),
|
||||||
|
glm::vec3( 1.0f, -1.0f, -1.0f),
|
||||||
|
glm::vec3(-1.0f, -1.0f, -1.0f)
|
||||||
|
};
|
||||||
|
|
||||||
|
glm::mat4 capLocalTf = glm::lookAt(glm::vec3(capWorldPos), origin, up);
|
||||||
|
|
||||||
|
capLocalTf = glm::inverse(capLocalTf);
|
||||||
|
|
||||||
|
float extends = 0.05f;
|
||||||
|
for(const glm::vec3& offset : capOffsets) {
|
||||||
|
Line(capWorldPos, capLocalTf * glm::vec4(extends * offset, 1.0f), color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Point(const glm::vec3& position, const Color& color) {
|
||||||
|
for(int axis=0;axis<3;axis++) {
|
||||||
|
glm::vec3 forward = glm::vec3(0.0f);
|
||||||
|
forward[axis] = 1.0f;
|
||||||
|
|
||||||
|
glm::vec3 lineOrigin = position - forward;
|
||||||
|
glm::vec3 lineDestinatio = position + forward;
|
||||||
|
|
||||||
|
Line(lineOrigin, lineDestinatio, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
81
RubiksCube/Entity.cpp
Normal file
81
RubiksCube/Entity.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
void Entity::_UpdateChildTransform() const {
|
||||||
|
for(auto& child : _children) {
|
||||||
|
child->_localToWorld = _localToWorld * child->_transform;
|
||||||
|
child->_worldToLocal = glm::inverse(child->_transform);
|
||||||
|
|
||||||
|
child->_UpdateChildTransform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity::Entity(Entity* parent) : _localToWorld(1.0f), _worldToLocal(1.0f)
|
||||||
|
{
|
||||||
|
_parent = parent;
|
||||||
|
_transform = glm::mat4(1.0f);
|
||||||
|
|
||||||
|
if (parent == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
parent->AddChild(this);
|
||||||
|
_localToWorld = _parent->_localToWorld;
|
||||||
|
_worldToLocal = glm::inverse(_localToWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity::~Entity() {
|
||||||
|
_parent->RemoveChild(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::AddChild(Entity* entity) {
|
||||||
|
_children.insert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::RemoveChild(Entity* entity) {
|
||||||
|
_children.erase(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::Transform(const glm::mat4& transform) {
|
||||||
|
glm::mat4 transformLocalBasis = _worldToLocal * transform;
|
||||||
|
|
||||||
|
_transform = transformLocalBasis * _transform;
|
||||||
|
|
||||||
|
if (_parent == nullptr) {
|
||||||
|
_localToWorld = _transform;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_localToWorld = _parent->LocalToWorld() * _transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
_worldToLocal = glm::inverse(_localToWorld);
|
||||||
|
_UpdateChildTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::TransformLocal(const glm::mat4& transform)
|
||||||
|
{
|
||||||
|
_transform = transform * _transform;
|
||||||
|
|
||||||
|
if (_parent == nullptr) {
|
||||||
|
_localToWorld = _transform;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_localToWorld = _parent->LocalToWorld() * _transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
_worldToLocal = glm::inverse(_localToWorld);
|
||||||
|
_UpdateChildTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::SetTransform(const glm::mat4& transform) {
|
||||||
|
_transform = transform;
|
||||||
|
|
||||||
|
if (_parent != nullptr) {
|
||||||
|
_localToWorld = transform * _parent->_localToWorld;
|
||||||
|
_worldToLocal = glm::inverse(transform) * _parent->_worldToLocal;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_localToWorld = transform;
|
||||||
|
_worldToLocal = glm::inverse(transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
_UpdateChildTransform();
|
||||||
|
}
|
||||||
40
RubiksCube/Entity.h
Normal file
40
RubiksCube/Entity.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
|
class Entity {
|
||||||
|
private:
|
||||||
|
glm::mat4 _transform;
|
||||||
|
|
||||||
|
glm::mat4 _localToWorld;
|
||||||
|
glm::mat4 _worldToLocal;
|
||||||
|
|
||||||
|
Entity* _parent;
|
||||||
|
std::unordered_set<Entity*> _children;
|
||||||
|
|
||||||
|
void _UpdateChildTransform() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Entity(Entity* parent);
|
||||||
|
virtual ~Entity();
|
||||||
|
|
||||||
|
void AddChild(Entity* entity);
|
||||||
|
void RemoveChild(Entity* entity);
|
||||||
|
|
||||||
|
Entity* Parent() const { return _parent; }
|
||||||
|
|
||||||
|
void Transform(const glm::mat4& transform);
|
||||||
|
void TransformLocal(const glm::mat4& transform);
|
||||||
|
void SetTransform(const glm::mat4& transform);
|
||||||
|
const glm::mat4& LocalToWorld() const { return _localToWorld; }
|
||||||
|
const glm::mat4& WorldToLocal() const { return _worldToLocal; }
|
||||||
|
const glm::mat4& LocalObjectTransform() const { return _transform; }
|
||||||
|
|
||||||
|
virtual void Render(DefaultUniform& uniform) { };
|
||||||
|
virtual void Update(double deltaTime) { };
|
||||||
|
|
||||||
|
};
|
||||||
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include <ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
void InputSystem::ObserveKey(int key) {
|
void InputSystem::ObserveKey(int key) {
|
||||||
_keyCodeDictionaryObserver.emplace(key, KeyObserver(_window, key));
|
_keyCodeDictionaryObserver.emplace(key, KeyObserver(_window, key));
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include "KeyObserver.h"
|
#include "KeyObserver.h"
|
||||||
|
|
||||||
|
|||||||
1
RubiksCube/Mesh.cpp
Normal file
1
RubiksCube/Mesh.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "Mesh.h"
|
||||||
97
RubiksCube/Mesh.h
Normal file
97
RubiksCube/Mesh.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <gl/glew.h>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
|
#include "Shader.h"
|
||||||
|
|
||||||
|
class DefaultUniform {
|
||||||
|
private:
|
||||||
|
|
||||||
|
public:
|
||||||
|
glm::mat4 model;
|
||||||
|
glm::mat4 view;
|
||||||
|
glm::mat4 projection;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class TVertexData, class TUniform = DefaultUniform>
|
||||||
|
class Mesh
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
TUniform _uniform;
|
||||||
|
|
||||||
|
GLuint _uniformModel;
|
||||||
|
GLuint _uniformView;
|
||||||
|
GLuint _uniformProjection;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<TVertexData> _vertexData;
|
||||||
|
|
||||||
|
GLuint _vba;
|
||||||
|
GLuint _vbo;
|
||||||
|
Shader* shader;
|
||||||
|
|
||||||
|
bool _isVertexDirty;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TUniform& Uniform() { return _uniform; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
Mesh(Shader* shader) : shader(shader), _isVertexDirty(true) {
|
||||||
|
shader->Initialize();
|
||||||
|
|
||||||
|
glCreateVertexArrays(1, &_vba);
|
||||||
|
glCreateBuffers(1, &_vbo);
|
||||||
|
|
||||||
|
_uniformModel = glGetUniformLocation(shader->Reference(), "model");
|
||||||
|
_uniformView = glGetUniformLocation(shader->Reference(), "view");
|
||||||
|
_uniformProjection = glGetUniformLocation(shader->Reference(), "projection");
|
||||||
|
}
|
||||||
|
|
||||||
|
~Mesh() {
|
||||||
|
glDeleteVertexArrays(1, &_vba);
|
||||||
|
glDeleteBuffers(1, &_vbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddTriangle(const TVertexData& p0, const TVertexData& p1, const TVertexData& p2) {
|
||||||
|
_vertexData.push_back(p0);
|
||||||
|
_vertexData.push_back(p1);
|
||||||
|
_vertexData.push_back(p2);
|
||||||
|
|
||||||
|
_isVertexDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddQuad(const TVertexData& p0, const TVertexData& p1, const TVertexData& p2, const TVertexData& p3) {
|
||||||
|
AddTriangle(p0, p1, p2);
|
||||||
|
AddTriangle(p1, p2, p3);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Render(const TUniform& uniform) {
|
||||||
|
shader->Use();
|
||||||
|
|
||||||
|
glUniformMatrix4fv(_uniformModel, 1, GL_FALSE, glm::value_ptr(uniform.model));
|
||||||
|
glUniformMatrix4fv(_uniformView, 1, GL_FALSE, glm::value_ptr(uniform.view));
|
||||||
|
glUniformMatrix4fv(_uniformProjection, 1, GL_FALSE, glm::value_ptr(uniform.projection));
|
||||||
|
|
||||||
|
glBindVertexArray(_vba);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||||
|
|
||||||
|
if (_isVertexDirty) {
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(TVertexData) * _vertexData.size(), _vertexData.data(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
_isVertexDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, _vertexData.size());
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
shader->Disable();
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
@ -1,23 +1,30 @@
|
|||||||
#include "PartitionedCube.h"
|
#include "PartitionedCube.h"
|
||||||
|
|
||||||
|
#include "Debug.h"
|
||||||
|
|
||||||
#include "Cube.h"
|
#include "Cube.h"
|
||||||
|
|
||||||
#include <glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
PartitionedCube::PartitionedCube(const glm::vec3& position, Color* sideColors) : _faces {
|
Shader PartitionedCubeMesh::_shader("cube.vert", "cube.frag");
|
||||||
sideColors[0],
|
|
||||||
sideColors[1],
|
Texture PartitionedCubeMesh::_diffuse;
|
||||||
sideColors[2],
|
Texture PartitionedCubeMesh::_roughness;
|
||||||
sideColors[3],
|
Texture PartitionedCubeMesh::_normal;
|
||||||
sideColors[4],
|
|
||||||
sideColors[5],
|
PartitionedCube::PartitionedCube(Cube* parent, const glm::vec3& position, Color* sideColors) : Entity(parent)
|
||||||
}
|
|
||||||
{
|
{
|
||||||
this->_transform = glm::translate(glm::mat4(1.0f), position);
|
this->TransformLocal(glm::translate(glm::mat4(1.0f), position));
|
||||||
|
|
||||||
|
this->_transformTem = glm::mat4(1.0f);
|
||||||
|
|
||||||
|
for(int i=0;i<6;i++) {
|
||||||
|
_faces[i] = sideColors[i];
|
||||||
|
}
|
||||||
|
|
||||||
_animationTime = 0.0f;
|
_animationTime = 0.0f;
|
||||||
_animationTimeExtend = 0.0f;
|
_animationTimeExtend = 0.0f;
|
||||||
_animationTransformInvoke = _transform;
|
|
||||||
_animationTransform = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
|
_animationTransform = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
|
||||||
_animationFinished = true;
|
_animationFinished = true;
|
||||||
|
|
||||||
@ -33,7 +40,7 @@ PartitionedCube::PartitionedCube(const glm::vec3& position, Color* sideColors) :
|
|||||||
|
|
||||||
z[axis] = factor;
|
z[axis] = factor;
|
||||||
x[(axis+1)%3] = 1.0f;
|
x[(axis+1)%3] = 1.0f;
|
||||||
y[(axis+2)%3] = 1.0f;
|
y = glm::cross(x, z);
|
||||||
|
|
||||||
glm::vec3 v0 = x * 0.5f + y * 0.5f + 0.5f * z;
|
glm::vec3 v0 = x * 0.5f + y * 0.5f + 0.5f * z;
|
||||||
glm::vec3 v1 = x * -0.5f + y * 0.5f + 0.5f * z;
|
glm::vec3 v1 = x * -0.5f + y * 0.5f + 0.5f * z;
|
||||||
@ -42,37 +49,109 @@ PartitionedCube::PartitionedCube(const glm::vec3& position, Color* sideColors) :
|
|||||||
|
|
||||||
int s = 2 * axis + reverse; // (-x, +x, -y, +y, -z, +z)
|
int s = 2 * axis + reverse; // (-x, +x, -y, +y, -z, +z)
|
||||||
|
|
||||||
_meshData.addFace(v0, v1, v2, v3, sideColors[s]);
|
glm::vec2 uv0 = glm::vec2(1.0f, 1.0f);
|
||||||
|
glm::vec2 uv1 = glm::vec2(0.0f, 1.0f);
|
||||||
|
glm::vec2 uv2 = glm::vec2(1.0f, 0.0f);
|
||||||
|
glm::vec2 uv3 = glm::vec2(0.0f, 0.0f);
|
||||||
|
|
||||||
|
VertexData d0 = VertexData(v0, z, uv0, sideColors[s]);
|
||||||
|
VertexData d1 = VertexData(v1, z, uv1, sideColors[s]);
|
||||||
|
VertexData d2 = VertexData(v2, z, uv2, sideColors[s]);
|
||||||
|
VertexData d3 = VertexData(v3, z, uv3, sideColors[s]);
|
||||||
|
|
||||||
|
_mesh.AddQuad(d0, d1, d2, d3);
|
||||||
|
|
||||||
factor = -factor;
|
factor = -factor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_mesh.CalculateTangents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PartitionedCube::Update(double deltaTime) {
|
void PartitionedCube::Update(double deltaTime) {
|
||||||
this->_animationTime -= deltaTime;
|
this->_animationTime -= deltaTime;
|
||||||
|
|
||||||
if (!_animationFinished && _animationTime <= 0.0f) {
|
if (!_animationFinished && _animationTime <= 0.0f) {
|
||||||
|
_animationTime = 0.0f;
|
||||||
|
|
||||||
|
const glm::mat4 finishedAnimationTransform = TransformCustom();
|
||||||
|
SetTransform(finishedAnimationTransform);
|
||||||
_animationFinished = true;
|
_animationFinished = true;
|
||||||
|
|
||||||
_transform = glm::mat4_cast(_animationTransform) * _animationTransformInvoke;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PartitionedCube::Transform(glm::mat4 transformation)
|
void PartitionedCube::Render(DefaultUniform& uniform) {
|
||||||
{
|
uniform.model = TransformCustom();
|
||||||
this->_transform = transformation * this->_transform;
|
|
||||||
_animationTransformInvoke = transformation * _animationTransformInvoke;
|
_mesh.Render(uniform);
|
||||||
_animationTransform = glm::quat_cast(transformation * glm::mat4_cast(_animationTransform));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PartitionedCube::TransformAnimation(const glm::mat4& transform, float duration) {
|
int toIndex(const glm::ivec3& direction) {
|
||||||
|
int axis = glm::abs(direction.x * 1 + direction.y * 2 + direction.z * 3) - 1;
|
||||||
|
int allAxis = direction.x + direction.y + direction.z;
|
||||||
|
int x = glm::sign(allAxis);
|
||||||
|
|
||||||
|
int reverse = (x + 1) / 2;
|
||||||
|
|
||||||
|
return axis * 2 + reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::ivec3 toDirection(int index) {
|
||||||
|
int axis = index / 2;
|
||||||
|
int reverse = index % 2;
|
||||||
|
|
||||||
|
glm::ivec3 direction = glm::ivec3(0);
|
||||||
|
direction[axis] = 1;
|
||||||
|
|
||||||
|
if (reverse == 0)
|
||||||
|
direction = -direction;
|
||||||
|
|
||||||
|
return direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartitionedCube::TransformData(const glm::ivec3& axis, int turns) {
|
||||||
|
Color previousListColors[6];
|
||||||
|
for(int i=0;i<6;i++) {
|
||||||
|
previousListColors[i] = _faces[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat3 rotations = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f) * turns, glm::vec3(axis));
|
||||||
|
|
||||||
|
for(int axis=0;axis<3;axis++) {
|
||||||
|
for(int direction=-1;direction<=1;direction+=2) {
|
||||||
|
glm::ivec3 position = glm::ivec3(0);
|
||||||
|
position[axis] = direction;
|
||||||
|
|
||||||
|
glm::vec3 newPosition = rotations * position;
|
||||||
|
|
||||||
|
glm::ivec3 newPositionStable;
|
||||||
|
newPositionStable.x = std::round(newPosition.x);
|
||||||
|
newPositionStable.y = std::round(newPosition.y);
|
||||||
|
newPositionStable.z = std::round(newPosition.z);
|
||||||
|
|
||||||
|
int newIndex = toIndex(newPositionStable);
|
||||||
|
int index = toIndex(position);
|
||||||
|
_faces[newIndex] = previousListColors[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartitionedCube::TransformAnimation(const glm::quat& transform, float duration) {
|
||||||
if (!_animationFinished)
|
if (!_animationFinished)
|
||||||
_transform = glm::mat4_cast(_animationTransform) * _animationTransformInvoke;
|
SetTransform(TransformCustom());
|
||||||
|
|
||||||
this->_animationTransformInvoke = this->_transform;
|
this->_animationTransform = transform;
|
||||||
this->_animationTransform = glm::quat_cast(transform);
|
|
||||||
this->_animationTime = duration;
|
this->_animationTime = duration;
|
||||||
this->_animationTimeExtend = duration;
|
this->_animationTimeExtend = duration;
|
||||||
_animationFinished = false;
|
_animationFinished = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PartitionedCube::TransformTemp(const glm::mat4& transform)
|
||||||
|
{
|
||||||
|
_transformTem = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartitionedCube::UndoTransformTemp()
|
||||||
|
{
|
||||||
|
_transformTem = glm::mat4(1.0f);
|
||||||
|
}
|
||||||
|
|||||||
@ -4,47 +4,121 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
#include <ext/quaternion_float.hpp>
|
#include <glm/ext/quaternion_float.hpp>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
#include "Texture.h"
|
||||||
|
#include "Shader.h"
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
struct VertexData {
|
struct VertexData {
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
|
glm::vec3 normal;
|
||||||
|
glm::vec2 uv0;
|
||||||
|
glm::vec3 tangent;
|
||||||
|
glm::vec3 bitangent;
|
||||||
Color color;
|
Color color;
|
||||||
|
|
||||||
VertexData() : position(glm::vec3(0.0f, 0.0f, 0.0f)), color(Color::WHITE()) {
|
VertexData(const glm::vec3& position, const glm::vec3& normal, const glm::vec2 uv0, Color color) : position(position), color(color), normal(normal), uv0(uv0), tangent(0.0f), bitangent(0.0f) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
VertexData(const glm::vec3& position, Color color) : position(position), color(color) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MeshData {
|
class PartitionedCubeMesh : public Mesh<VertexData> {
|
||||||
int vertexIndex;
|
private:
|
||||||
std::vector<VertexData> data;
|
static Shader _shader;
|
||||||
int triangleIndex;
|
static Texture _diffuse;
|
||||||
|
static Texture _roughness;
|
||||||
|
static Texture _normal;
|
||||||
|
|
||||||
MeshData() {
|
GLuint _uniformDiffuse;
|
||||||
vertexIndex = 0;
|
GLuint _uniformRoughness;
|
||||||
triangleIndex = 0;
|
GLuint _uniformNormal;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PartitionedCubeMesh() : Mesh(&_shader) {
|
||||||
|
_shader.Use();
|
||||||
|
|
||||||
|
glBindVertexArray(_vba);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||||
|
|
||||||
|
int shd = shader->Reference();
|
||||||
|
|
||||||
|
_uniformDiffuse = glGetUniformLocation(shd, "diffuse");
|
||||||
|
_uniformRoughness = glGetUniformLocation(shd, "roughness");
|
||||||
|
_uniformNormal = glGetUniformLocation(shd, "normal");
|
||||||
|
|
||||||
|
glUniform1i(_uniformDiffuse, 0);
|
||||||
|
glUniform1i(_uniformRoughness, 1);
|
||||||
|
glUniform1i(_uniformNormal, 2);
|
||||||
|
|
||||||
|
glVertexAttribPointer(glGetAttribLocation(shd, "position"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, position));
|
||||||
|
glVertexAttribPointer(glGetAttribLocation(shd, "normal"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, normal));
|
||||||
|
glVertexAttribPointer(glGetAttribLocation(shd, "uv0"), 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uv0));
|
||||||
|
glVertexAttribPointer(glGetAttribLocation(shd, "tangent"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, tangent));
|
||||||
|
glVertexAttribPointer(glGetAttribLocation(shd, "bitangent"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, bitangent));
|
||||||
|
glVertexAttribPointer(glGetAttribLocation(shd, "color"), 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, color));
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
glEnableVertexAttribArray(3);
|
||||||
|
glEnableVertexAttribArray(4);
|
||||||
|
glEnableVertexAttribArray(5);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
_shader.Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTriangle(glm::vec3 v0, glm::vec3 v1, glm::vec3 v2, Color color) {
|
virtual void Render(const DefaultUniform& uniform) override {
|
||||||
data.push_back(VertexData(v0, color));
|
_shader.Use();
|
||||||
data.push_back(VertexData(v1, color));
|
|
||||||
data.push_back(VertexData(v2, color));
|
|
||||||
vertexIndex += 3;
|
|
||||||
|
|
||||||
triangleIndex ++;
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, _diffuse.Reference());
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, _roughness.Reference());
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, _normal.Reference());
|
||||||
|
|
||||||
|
_shader.Disable();
|
||||||
|
|
||||||
|
Mesh::Render(uniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addFace(glm::vec3 v0, glm::vec3 v1, glm::vec3 v2, glm::vec3 v3, Color color) {
|
static void LoadResources() {
|
||||||
addTriangle(v0, v1, v2, color);
|
_diffuse = Texture("diffuse.png");
|
||||||
addTriangle(v3, v2, v1, color);
|
_roughness = Texture("roughness.png");
|
||||||
|
_normal = Texture("normal.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalculateTangents() {
|
||||||
|
for(int i=0;i<_vertexData.size();i += 3) {
|
||||||
|
VertexData& d0 = _vertexData.at(i + 0);
|
||||||
|
VertexData& d1 = _vertexData.at(i + 1);
|
||||||
|
VertexData& d2 = _vertexData.at(i + 2);
|
||||||
|
|
||||||
|
glm::vec3 deltaPos1 = d1.position - d0.position;
|
||||||
|
glm::vec3 deltaPos2 = d2.position - d0.position;
|
||||||
|
|
||||||
|
glm::vec2 deltaUV1 = d1.uv0 - d0.uv0;
|
||||||
|
glm::vec2 deltaUV2 = d2.uv0 - d0.uv0;
|
||||||
|
|
||||||
|
float r = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x);
|
||||||
|
d0.tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y) * r;
|
||||||
|
d0.bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x) * r;
|
||||||
|
d1.tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y) * r;
|
||||||
|
d1.bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x) * r;
|
||||||
|
d2.tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y) * r;
|
||||||
|
d2.bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x) * r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,40 +135,45 @@ constexpr glm::vec3 SideToDirection[6] = {
|
|||||||
glm::vec3(0.0f, 0.0f, 1.0f),
|
glm::vec3(0.0f, 0.0f, 1.0f),
|
||||||
};
|
};
|
||||||
|
|
||||||
class PartitionedCube
|
class Cube;
|
||||||
|
|
||||||
|
class PartitionedCube : public Entity
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
glm::mat4 _transform;
|
glm::mat4 _transformTem;
|
||||||
|
|
||||||
glm::mat4 _animationTransformInvoke;
|
|
||||||
glm::quat _animationTransform;
|
glm::quat _animationTransform;
|
||||||
float _animationTime;
|
float _animationTime;
|
||||||
float _animationTimeExtend;
|
float _animationTimeExtend;
|
||||||
bool _animationFinished;
|
bool _animationFinished;
|
||||||
|
|
||||||
Color _faces[6];
|
Color _faces[6];
|
||||||
MeshData _meshData;
|
PartitionedCubeMesh _mesh;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PartitionedCube(const glm::vec3& position, Color sideColors[6]);
|
PartitionedCube(Cube* parent, const glm::vec3& position, Color* sideColors);
|
||||||
|
|
||||||
void Update(double deltaTime);
|
void Update(double deltaTime) override;
|
||||||
|
void Render(DefaultUniform& uniform) override;
|
||||||
|
|
||||||
const glm::mat4 Transform() const {
|
const glm::mat4 TransformCustom() const {
|
||||||
// Need to use slerp since rotations are non-linear and would not interpolate this way
|
// Need to use slerp since rotations are non-linear and would not interpolate this way
|
||||||
|
//
|
||||||
|
// However a lerp can be used and then normalized, with not that much of an
|
||||||
|
// error but being much more performant thus preferred function
|
||||||
if (false == _animationFinished) {
|
if (false == _animationFinished) {
|
||||||
float lerpFactor = 1.0f - ( _animationTime / _animationTimeExtend);
|
float lerpFactor = 1.0f - ( _animationTime / _animationTimeExtend);
|
||||||
|
|
||||||
glm::mat4 animationView = glm::mat4_cast(glm::slerp(glm::quat(1.0f, 0.0f, 0.0f, 0.0f), _animationTransform, lerpFactor));
|
glm::mat4 animationView = glm::mat4_cast(glm::normalize(glm::lerp(glm::quat(1.0f, 0.0f, 0.0f, 0.0f), _animationTransform, lerpFactor)));
|
||||||
|
|
||||||
return animationView * _animationTransformInvoke;
|
return Parent()->LocalToWorld() * animationView * LocalObjectTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _transform;
|
return Parent()->LocalToWorld() * _transformTem * LocalObjectTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
const MeshData& MeshData() const { return _meshData; };
|
void TransformData(const glm::ivec3& axis, int turns);
|
||||||
|
void TransformAnimation(const glm::quat& transform, float duration);
|
||||||
void Transform(glm::mat4 transformation);
|
void TransformTemp(const glm::mat4& transform);
|
||||||
void TransformAnimation(const glm::mat4& transform, float duration);
|
void UndoTransformTemp();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
class Plane
|
class Plane
|
||||||
{
|
{
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
#include "GameInterface.h"
|
#include "GameInterface.h"
|
||||||
#include "SceneInterface.h"
|
#include "SceneInterface.h"
|
||||||
|
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -71,10 +71,10 @@
|
|||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<ExternalIncludePath>$(SolutionDir)/../ExternalResources/glew/include;$(SolutionDir)/../ExternalResources/glfw/include;$(SolutionDir)/../ExternalResources/glm/glm;$(SolutionDir)/../ExternalResources/stb;$(ExternalIncludePath)</ExternalIncludePath>
|
<ExternalIncludePath>$(SolutionDir)/../ExternalResources/glew/include;$(SolutionDir)/../ExternalResources/glfw/include;$(SolutionDir)/../ExternalResources/glm;$(SolutionDir)/../ExternalResources/stb;$(ExternalIncludePath)</ExternalIncludePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ExternalIncludePath>$(SolutionDir)/../ExternalResources/glew/include;$(SolutionDir)/../ExternalResources/glfw/include;$(SolutionDir)/../ExternalResources/glm/glm;$(SolutionDir)/../ExternalResources/stb;$(ExternalIncludePath)</ExternalIncludePath>
|
<ExternalIncludePath>$(SolutionDir)/../ExternalResources/glew/include;$(SolutionDir)/../ExternalResources/glfw/include;$(SolutionDir)/../ExternalResources/glm;$(SolutionDir)/../ExternalResources/stb;$(ExternalIncludePath)</ExternalIncludePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@ -110,6 +110,7 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -126,6 +127,7 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -139,30 +141,36 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Color.cpp" />
|
<ClCompile Include="Color.cpp" />
|
||||||
<ClCompile Include="Cube.cpp" />
|
<ClCompile Include="Cube.cpp" />
|
||||||
|
<ClCompile Include="Debug.cpp" />
|
||||||
|
<ClCompile Include="Entity.cpp" />
|
||||||
<ClCompile Include="GameInterface.cpp" />
|
<ClCompile Include="GameInterface.cpp" />
|
||||||
<ClCompile Include="InputSystem.cpp" />
|
<ClCompile Include="InputSystem.cpp" />
|
||||||
<ClCompile Include="KeyObserver.cpp" />
|
<ClCompile Include="KeyObserver.cpp" />
|
||||||
|
<ClCompile Include="Mesh.cpp" />
|
||||||
<ClCompile Include="PartitionedCube.cpp" />
|
<ClCompile Include="PartitionedCube.cpp" />
|
||||||
<ClCompile Include="Plane.cpp" />
|
<ClCompile Include="Plane.cpp" />
|
||||||
<ClCompile Include="RubiksCube.cpp" />
|
<ClCompile Include="RubiksCube.cpp" />
|
||||||
<ClCompile Include="SceneInterface.cpp" />
|
<ClCompile Include="SceneInterface.cpp" />
|
||||||
<ClCompile Include="Shader.cpp" />
|
|
||||||
<ClCompile Include="ShaderUtil.cpp" />
|
<ClCompile Include="ShaderUtil.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Camera.h" />
|
||||||
<ClInclude Include="Color.h" />
|
<ClInclude Include="Color.h" />
|
||||||
<ClInclude Include="Cube.h" />
|
<ClInclude Include="Cube.h" />
|
||||||
|
<ClInclude Include="Debug.h" />
|
||||||
|
<ClInclude Include="Entity.h" />
|
||||||
<ClInclude Include="GameInterface.h" />
|
<ClInclude Include="GameInterface.h" />
|
||||||
<ClInclude Include="InputSystem.h" />
|
<ClInclude Include="InputSystem.h" />
|
||||||
<ClInclude Include="KeyObserver.h" />
|
<ClInclude Include="KeyObserver.h" />
|
||||||
<ClInclude Include="MeshData.h" />
|
<ClInclude Include="Mesh.h" />
|
||||||
<ClInclude Include="PartitionedCube.h" />
|
<ClInclude Include="PartitionedCube.h" />
|
||||||
<ClInclude Include="Plane.h" />
|
<ClInclude Include="Plane.h" />
|
||||||
<ClInclude Include="SceneInterface.h" />
|
<ClInclude Include="SceneInterface.h" />
|
||||||
|
<ClInclude Include="Settings.h" />
|
||||||
<ClInclude Include="Shader.h" />
|
<ClInclude Include="Shader.h" />
|
||||||
<ClInclude Include="ShaderUtil.h" />
|
<ClInclude Include="ShaderUtil.h" />
|
||||||
<ClInclude Include="Side.h" />
|
<ClInclude Include="Side.h" />
|
||||||
<ClInclude Include="VertexData.h" />
|
<ClInclude Include="Texture.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CopyFileToFolders Include="cube.frag">
|
<CopyFileToFolders Include="cube.frag">
|
||||||
@ -176,6 +184,40 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
</CopyFileToFolders>
|
</CopyFileToFolders>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<CopyFileToFolders Include="line.frag">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<FileType>Document</FileType>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
<CopyFileToFolders Include="line.vert">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<FileType>Document</FileType>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<CopyFileToFolders Include="normal.png">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<CopyFileToFolders Include="diffuse.png">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
<CopyFileToFolders Include="roughness.png">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<CopyFileToFolders Include="diffuse_test.png">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|||||||
@ -36,9 +36,6 @@
|
|||||||
<ClCompile Include="Color.cpp">
|
<ClCompile Include="Color.cpp">
|
||||||
<Filter>Quelldateien</Filter>
|
<Filter>Quelldateien</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Shader.cpp">
|
|
||||||
<Filter>Quelldateien</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ShaderUtil.cpp">
|
<ClCompile Include="ShaderUtil.cpp">
|
||||||
<Filter>Quelldateien</Filter>
|
<Filter>Quelldateien</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -51,6 +48,15 @@
|
|||||||
<ClCompile Include="Plane.cpp">
|
<ClCompile Include="Plane.cpp">
|
||||||
<Filter>Quelldateien</Filter>
|
<Filter>Quelldateien</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Debug.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Mesh.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Entity.cpp">
|
||||||
|
<Filter>Quelldateien</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="GameInterface.h">
|
<ClInclude Include="GameInterface.h">
|
||||||
@ -68,15 +74,6 @@
|
|||||||
<ClInclude Include="Color.h">
|
<ClInclude Include="Color.h">
|
||||||
<Filter>Headerdateien</Filter>
|
<Filter>Headerdateien</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Shader.h">
|
|
||||||
<Filter>Headerdateien</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="VertexData.h">
|
|
||||||
<Filter>Headerdateien</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="MeshData.h">
|
|
||||||
<Filter>Headerdateien</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Side.h">
|
<ClInclude Include="Side.h">
|
||||||
<Filter>Headerdateien</Filter>
|
<Filter>Headerdateien</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -92,6 +89,27 @@
|
|||||||
<ClInclude Include="Plane.h">
|
<ClInclude Include="Plane.h">
|
||||||
<Filter>Headerdateien</Filter>
|
<Filter>Headerdateien</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Debug.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Settings.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Mesh.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Texture.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Shader.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Entity.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Camera.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CopyFileToFolders Include="cube.frag">
|
<CopyFileToFolders Include="cube.frag">
|
||||||
@ -100,5 +118,23 @@
|
|||||||
<CopyFileToFolders Include="cube.vert">
|
<CopyFileToFolders Include="cube.vert">
|
||||||
<Filter>Shaders</Filter>
|
<Filter>Shaders</Filter>
|
||||||
</CopyFileToFolders>
|
</CopyFileToFolders>
|
||||||
|
<CopyFileToFolders Include="line.frag">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
<CopyFileToFolders Include="line.vert">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
<CopyFileToFolders Include="normal.png">
|
||||||
|
<Filter>Ressourcendateien</Filter>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
<CopyFileToFolders Include="diffuse.png">
|
||||||
|
<Filter>Ressourcendateien</Filter>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
<CopyFileToFolders Include="roughness.png">
|
||||||
|
<Filter>Ressourcendateien</Filter>
|
||||||
|
</CopyFileToFolders>
|
||||||
|
<CopyFileToFolders Include="diffuse_test.png">
|
||||||
|
<Filter>Ressourcendateien</Filter>
|
||||||
|
</CopyFileToFolders>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@ -6,9 +6,10 @@
|
|||||||
|
|
||||||
#include "Plane.h"
|
#include "Plane.h"
|
||||||
|
|
||||||
#include <glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
#include <gtx/string_cast.hpp>
|
#include <glm/gtx/string_cast.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@ -16,6 +17,20 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
SceneInterface::SceneInterface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneInterface::~SceneInterface()
|
||||||
|
{
|
||||||
|
for(Entity* entity : _entities) {
|
||||||
|
delete entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete currentAction;
|
||||||
|
}
|
||||||
|
|
||||||
void SceneInterface::Initialize(GLFWwindow* window)
|
void SceneInterface::Initialize(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
_inputSystem.SetWindow(window);
|
_inputSystem.SetWindow(window);
|
||||||
@ -40,22 +55,30 @@ void SceneInterface::Initialize(GLFWwindow* window)
|
|||||||
|
|
||||||
_wasMouseDown = false;
|
_wasMouseDown = false;
|
||||||
|
|
||||||
this->_shaderProgram = ShaderUtil::CreateShaderProgram("cube.vert", "cube.frag");
|
_debug = new Debug(window);
|
||||||
this->_transformLocation = glGetUniformLocation(this->_shaderProgram, "transformation");
|
|
||||||
|
|
||||||
glGenVertexArrays(1, &this->_arrayBufferObject);
|
PartitionedCubeMesh::LoadResources();
|
||||||
glGenBuffers(1, &this->_vertexBufferObject);
|
|
||||||
|
|
||||||
glBindVertexArray(_arrayBufferObject);
|
_camera = new Camera(window, &_inputSystem);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, this->_vertexBufferObject);
|
Cube* cube = new Cube();
|
||||||
|
_cube = cube;
|
||||||
|
|
||||||
glVertexAttribPointer(glGetAttribLocation(_shaderProgram, "position"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, position));
|
_entities.push_back(_debug);
|
||||||
glEnableVertexAttribArray(0);
|
_entities.push_back(_camera);
|
||||||
glVertexAttribPointer(glGetAttribLocation(_shaderProgram, "color"), 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, color));
|
_entities.push_back(_cube);
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
for(PartitionedCube** cube = _cube->Children();cube != _cube->Children() + _cube->ChildPartitionsCount;cube++) {
|
||||||
glBindVertexArray(0);
|
_entities.push_back(*cube);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Controls: " << std::endl;
|
||||||
|
std::cout << "Numpad 1, 2, 3, 7, 8, 9 + Shift Rotate X Axis Down Up View" << std::endl;
|
||||||
|
std::cout << "Numpad 1, 4, 7, 3, 6, 9 Rotate Y Axis Left Right View" << std::endl;
|
||||||
|
std::cout << "Arrows Up, Down, Right, Left Rotate Camera relative lookat" << std::endl;
|
||||||
|
std::cout << "Space Reset Look Changes" << std::endl;
|
||||||
|
std::cout << "Mouse Scroll Vertically Zoom" << std::endl;
|
||||||
|
std::cout << "Left Mouse Rotate Cube Planes" << std::endl;
|
||||||
|
std::cout << "Right Mouse Rotate Camera" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 basisCoordinateVectors[] = {
|
glm::vec3 basisCoordinateVectors[] = {
|
||||||
@ -113,33 +136,19 @@ void IntersectLinePlane(const glm::vec3& lineStart, const glm::vec3& lineDirecti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneInterface::EnqueueAction(const Action& action) {
|
void SceneInterface::EnqueueAction(Action* action) {
|
||||||
_actions.push(action);
|
_actions.push(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneInterface::Update(float deltaTime)
|
void SceneInterface::Update(float deltaTime)
|
||||||
{
|
{
|
||||||
_cube.Update(deltaTime);
|
|
||||||
_inputSystem.Update();
|
_inputSystem.Update();
|
||||||
|
|
||||||
if (_inputSystem.WasKeyPressed(GLFW_KEY_SPACE))
|
for(Entity* entity : _entities) {
|
||||||
_orientation = glm::quat(1.0f, glm::vec3(0.0f, 0.0f, 0.0f));
|
entity->Update(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
glm::fvec2 velocity(0.0f, 0.0f);
|
|
||||||
if (_inputSystem.IsKeyPressed(GLFW_KEY_UP))
|
|
||||||
velocity.x = glm::radians(90.0f);
|
|
||||||
if (_inputSystem.IsKeyPressed(GLFW_KEY_DOWN))
|
|
||||||
velocity.x = glm::radians(-90.0f);
|
|
||||||
|
|
||||||
if (_inputSystem.IsKeyPressed(GLFW_KEY_RIGHT))
|
|
||||||
velocity.y = glm::radians(90.0f);
|
|
||||||
if (_inputSystem.IsKeyPressed(GLFW_KEY_LEFT))
|
|
||||||
velocity.y = glm::radians(-90.0f);
|
|
||||||
|
|
||||||
glm::quat velocityQuaternion = glm::quat(0.0f, glm::vec3(velocity.x, velocity.y, 0.0f));
|
|
||||||
|
|
||||||
_orientation += 0.5f * (float)deltaTime * velocityQuaternion * _orientation;
|
|
||||||
_orientation = glm::normalize(_orientation);
|
|
||||||
|
|
||||||
// int spinIndex = 0;
|
// int spinIndex = 0;
|
||||||
|
|
||||||
@ -170,16 +179,54 @@ void SceneInterface::Update(float deltaTime)
|
|||||||
int axisIndex = spinAxis.x == 0; // x => 0, y => 1
|
int axisIndex = spinAxis.x == 0; // x => 0, y => 1
|
||||||
int spinIndex = keyToIndex[axisIndex][rotationKey - 1];
|
int spinIndex = keyToIndex[axisIndex][rotationKey - 1];
|
||||||
|
|
||||||
if (reverse)
|
int reverseSign = reverse ? -1 : 1;
|
||||||
spinAxis *= -1;
|
|
||||||
|
spinAxis *= reverseSign;
|
||||||
|
spinIndex *= reverseSign;
|
||||||
|
|
||||||
|
glm::mat3 cubeMat = glm::mat3(_cube->LocalToWorld()) * glm::mat3(_camera->View());
|
||||||
|
|
||||||
|
glm::mat3 orthogonalized = cubeMat;
|
||||||
|
for(int column=0;column<3;column++) {
|
||||||
|
int nearestCardinalisedAxis = 0;
|
||||||
|
for(int i=0;i<3;i++) {
|
||||||
|
if (glm::abs(orthogonalized[column][i]) > glm::abs(orthogonalized[column][nearestCardinalisedAxis])) {
|
||||||
|
nearestCardinalisedAxis = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int columnToPlace=0;columnToPlace<3;columnToPlace++) {
|
||||||
|
for(int i=0;i<3;i++) {
|
||||||
|
if (columnToPlace == column) {
|
||||||
|
if (nearestCardinalisedAxis == i) {
|
||||||
|
orthogonalized[columnToPlace][i] = glm::sign(orthogonalized[columnToPlace][i]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
orthogonalized[columnToPlace][i] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (nearestCardinalisedAxis == i) {
|
||||||
|
orthogonalized[columnToPlace][i] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat3 screenToCube = glm::inverse(orthogonalized);
|
||||||
|
|
||||||
|
spinAxis = screenToCube * spinAxis;
|
||||||
|
int direction = spinAxis.x + spinAxis.y + spinAxis.z;
|
||||||
|
|
||||||
|
EnqueueAction(new ActionSpinDefault(_cube, spinAxis, spinIndex, 1.0f));
|
||||||
|
|
||||||
// _cube.TransformAnimation(cubeSpinAxis, spinIndex, rotation, 1.0f);
|
// _cube.TransformAnimation(cubeSpinAxis, spinIndex, rotation, 1.0f);
|
||||||
|
|
||||||
EnqueueAction(Action(spinAxis, spinIndex, 1.0f));
|
|
||||||
|
|
||||||
std::cout << glm::to_string(spinAxis) << " " << spinIndex << std::endl;
|
std::cout << glm::to_string(spinAxis) << " " << spinIndex << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentAction == nullptr) {
|
||||||
if (!_wasMouseDown && _inputSystem.IsLeftMouseDown()) {
|
if (!_wasMouseDown && _inputSystem.IsLeftMouseDown()) {
|
||||||
OnDragStart();
|
OnDragStart();
|
||||||
}
|
}
|
||||||
@ -191,28 +238,39 @@ void SceneInterface::Update(float deltaTime)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_wasMouseDown = _inputSystem.IsLeftMouseDown();
|
_wasMouseDown = _inputSystem.IsLeftMouseDown();
|
||||||
|
}
|
||||||
|
|
||||||
currentAction.duration -= deltaTime;
|
if (currentAction != nullptr) {
|
||||||
if (currentAction.duration <= 0.0f && _actions.size() > 0) {
|
currentAction->duration -= deltaTime;
|
||||||
Action& action = _actions.front();
|
}
|
||||||
|
|
||||||
|
if (currentAction != nullptr && currentAction->duration > 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_actions.size() > 0) {
|
||||||
|
delete currentAction;
|
||||||
|
|
||||||
|
Action* action = _actions.front();
|
||||||
_actions.pop();
|
_actions.pop();
|
||||||
|
|
||||||
ApplyAction(action);
|
ApplyAction(action);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
currentAction = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneInterface::OnDragStart() {
|
void SceneInterface::OnDragStart() {
|
||||||
_inputSystem.GetMousePos(_initialMouseLocation);
|
_inputSystem.GetMousePos(_initialMouseLocation);
|
||||||
|
|
||||||
Plane planes[6];
|
|
||||||
|
|
||||||
glm::vec3 lineStart;
|
glm::vec3 lineStart;
|
||||||
glm::vec3 lineDirection;
|
glm::vec3 lineDirection;
|
||||||
glm::mat4 viewPerspective = _perspective * _view;
|
glm::mat4 viewPerspective = _camera->Projection() * _camera->View();
|
||||||
|
|
||||||
_inputSystem.GetPickingRay(viewPerspective, lineStart, lineDirection);
|
_inputSystem.GetPickingRay(viewPerspective, lineStart, lineDirection);
|
||||||
|
|
||||||
glm::mat4 transform = glm::mat4(1.0f);
|
glm::mat4 transform = _cube->LocalToWorld();
|
||||||
|
|
||||||
for(int axis=0;axis<3;axis++) {
|
for(int axis=0;axis<3;axis++) {
|
||||||
for(int direction=-1;direction<=1;direction+=2) {
|
for(int direction=-1;direction<=1;direction+=2) {
|
||||||
@ -252,7 +310,7 @@ void SceneInterface::OnDrag(double deltaTime) {
|
|||||||
|
|
||||||
glm::vec3 lineStart;
|
glm::vec3 lineStart;
|
||||||
glm::vec3 lineDirection;
|
glm::vec3 lineDirection;
|
||||||
glm::mat4 transform = _perspective * _view;
|
glm::mat4 transform = _camera->Projection() * _camera->View();
|
||||||
_inputSystem.GetPickingRay(transform, lineStart, lineDirection);
|
_inputSystem.GetPickingRay(transform, lineStart, lineDirection);
|
||||||
|
|
||||||
float intersectionDistance = -1.0f;
|
float intersectionDistance = -1.0f;
|
||||||
@ -269,7 +327,7 @@ void SceneInterface::OnDrag(double deltaTime) {
|
|||||||
float dragAbsDistance = abs(glm::distance(glm::vec2(0.0f), directionPlane));
|
float dragAbsDistance = abs(glm::distance(glm::vec2(0.0f), directionPlane));
|
||||||
|
|
||||||
if (dragAbsDistance >= MIN_DRAG_MAGNITUDE) {
|
if (dragAbsDistance >= MIN_DRAG_MAGNITUDE) {
|
||||||
glm::vec3 mousePosition = glm::inverse(planeTransform) * glm::vec4(_mousePositionPlane, 0.0f, 1.0f);
|
glm::vec3 mousePosition = planeTransform * glm::vec4(_mousePositionPlane, 0.0f, 1.0f);
|
||||||
|
|
||||||
glm::vec3 direction = glm::inverse(planeTransform) * glm::vec4(directionPlane, 0.0f, 0.0f);
|
glm::vec3 direction = glm::inverse(planeTransform) * glm::vec4(directionPlane, 0.0f, 0.0f);
|
||||||
|
|
||||||
@ -284,108 +342,71 @@ void SceneInterface::OnDrag(double deltaTime) {
|
|||||||
|
|
||||||
glm::ivec3 axis = orthogonalise(axisSingle);
|
glm::ivec3 axis = orthogonalise(axisSingle);
|
||||||
|
|
||||||
std::cout << glm::to_string(axisSingle) << std::endl;
|
_cube->UndoTransformTemp();
|
||||||
std::cout << glm::to_string(direction) << std::endl;
|
|
||||||
std::cout << glm::to_string(axis) << std::endl;
|
|
||||||
|
|
||||||
_cube.TransformTemp(axis, index, glm::rotate(glm::mat4(1.0f), glm::radians(abs(glm::distance(glm::vec2(0.0f), directionPlane))), axisSingle));
|
float angle = glm::radians(90.0f * ( 1.0f / 3.0f ) * abs(glm::distance(glm::vec2(0.0f), directionPlane)));
|
||||||
|
|
||||||
|
_cube->TransformTemp(axis, index, glm::rotate(glm::mat4(1.0f), angle, axisSingle));
|
||||||
|
_spinIndex = index;
|
||||||
|
_spinAxis = axis;
|
||||||
|
_spinDelta = angle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float rotations = 2 * glm::pi<float>();
|
||||||
|
|
||||||
|
const float quarterRotation = rotations * 0.25f;
|
||||||
|
|
||||||
void SceneInterface::OnDragStop() {
|
void SceneInterface::OnDragStop() {
|
||||||
|
// Undo any temporarilies
|
||||||
|
_cube->UndoTransformTemp();
|
||||||
|
|
||||||
|
// Transform Instantly to current angle
|
||||||
|
_cube->Transform(_spinAxis, _spinIndex, glm::rotate(glm::mat4(1.0f), _spinDelta, glm::vec3(_spinAxis)));
|
||||||
|
|
||||||
|
float angleNormalized = std::fmodf(_spinDelta, quarterRotation);
|
||||||
|
|
||||||
|
float remainingAngle = 0.5f - glm::abs(angleNormalized - quarterRotation * 0.5f);
|
||||||
|
|
||||||
|
float remainingFactor = remainingAngle / quarterRotation;
|
||||||
|
|
||||||
|
int rotations = round(_spinDelta / quarterRotation);
|
||||||
|
|
||||||
|
// remaining rotation animating
|
||||||
|
if (_spinDelta > 0.0f && rotations > 0) {
|
||||||
|
EnqueueAction(new ActionSpinAfterDragging(_cube, _spinAxis, _spinIndex, ( quarterRotation * rotations ) - _spinDelta, rotations, remainingFactor * 1.0f));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
EnqueueAction(new ActionSpinAfterDragging(_cube, _spinAxis, _spinIndex, -( _spinDelta ), rotations, remainingFactor * 1.0f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneInterface::ApplyAction(const Action& action) {
|
void SceneInterface::ApplyAction(Action* action) {
|
||||||
currentAction = action;
|
currentAction = action;
|
||||||
|
|
||||||
glm::mat3 cubeMat = _cube.Transform() * glm::mat4_cast(_orientation);
|
action->Invoke();
|
||||||
|
|
||||||
glm::mat3 orthogonalized = cubeMat;
|
|
||||||
for(int column=0;column<3;column++) {
|
|
||||||
int nearestCardinalisedAxis = 0;
|
|
||||||
for(int i=0;i<3;i++) {
|
|
||||||
if (glm::abs(orthogonalized[column][i]) > glm::abs(orthogonalized[column][nearestCardinalisedAxis])) {
|
|
||||||
nearestCardinalisedAxis = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int columnToPlace=0;columnToPlace<3;columnToPlace++) {
|
|
||||||
for(int i=0;i<3;i++) {
|
|
||||||
if (columnToPlace == column) {
|
|
||||||
if (nearestCardinalisedAxis == i) {
|
|
||||||
orthogonalized[columnToPlace][i] = glm::sign(orthogonalized[columnToPlace][i]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
orthogonalized[columnToPlace][i] = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (nearestCardinalisedAxis == i) {
|
|
||||||
orthogonalized[columnToPlace][i] = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 axis = action.axis;
|
|
||||||
|
|
||||||
int direction = axis.x + axis.y + axis.z;
|
|
||||||
|
|
||||||
axis = glm::inverse(orthogonalized) * axis;
|
|
||||||
|
|
||||||
int index = action.index;
|
|
||||||
index *= direction;
|
|
||||||
|
|
||||||
glm::mat4 rotationMat = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), axis);
|
|
||||||
for(int i=0;i<3;i++) {
|
|
||||||
for(int g=0;g<3;g++) {
|
|
||||||
rotationMat[i][g] = round(rotationMat[i][g]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glm::imat3x3 rotation = glm::imat3x3(rotationMat);
|
|
||||||
|
|
||||||
_cube.TransformAnimation(axis, index, rotation, action.duration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneInterface::Render(float aspectRatio) {
|
void SceneInterface::Render(float aspectRatio) {
|
||||||
glUseProgram(_shaderProgram);
|
if (_camera == nullptr)
|
||||||
glBindVertexArray(this->_arrayBufferObject);
|
return;
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, this->_vertexBufferObject);
|
DefaultUniform uniform;
|
||||||
|
uniform.view = _camera->View();
|
||||||
|
uniform.projection = _camera->Projection();
|
||||||
|
|
||||||
_view = glm::lookAt(glm::vec3(0.0f, 0.0f, 4.75f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)) * glm::mat4_cast(_orientation);
|
for(Entity* entity : _entities) {
|
||||||
_perspective = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f);
|
uniform.model = entity->LocalToWorld();
|
||||||
|
|
||||||
auto transformation = _perspective * _view;
|
entity->Render(uniform);
|
||||||
|
}
|
||||||
|
|
||||||
// std::cout << "perspective: " << glm::to_string(glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f)) << std::endl;
|
// std::cout << "perspective: " << glm::to_string(glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f)) << std::endl;
|
||||||
// std::cout << "view : " << glm::to_string(glm::lookAt(glm::vec3(0.0f, 0.0f, -3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f))) << std::endl;
|
// std::cout << "view : " << glm::to_string(glm::lookAt(glm::vec3(0.0f, 0.0f, -3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f))) << std::endl;
|
||||||
// std::cout << "model : " << glm::to_string(_cube.Transform()) << std::endl;
|
// std::cout << "model : " << glm::to_string(_cube.Transform()) << std::endl;
|
||||||
|
|
||||||
for(int i=0;i<_cube.ChildPartitionsCount;i++) {
|
|
||||||
const PartitionedCube* cube = _cube.Children()[i];
|
|
||||||
|
|
||||||
const MeshData& meshData = cube->MeshData();
|
|
||||||
|
|
||||||
const glm::vec3& position = meshData.data[0].position;
|
|
||||||
|
|
||||||
auto localTransform = transformation * cube->Transform();
|
|
||||||
|
|
||||||
glUniformMatrix4fv(_transformLocation, 1, GL_FALSE, glm::value_ptr(localTransform));
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * meshData.vertexIndex, meshData.data.data(), GL_STATIC_DRAW);
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, meshData.vertexIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
glUseProgram(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneInterface::ClearResources()
|
void SceneInterface::ClearResources()
|
||||||
{
|
{
|
||||||
glDeleteBuffers(1, &_vertexBufferObject);
|
|
||||||
glDeleteVertexArrays(1, &_arrayBufferObject);
|
|
||||||
glDeleteProgram(_shaderProgram);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,69 +2,109 @@
|
|||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
#include "Debug.h"
|
||||||
#include "Plane.h"
|
#include "Plane.h"
|
||||||
#include "InputSystem.h"
|
#include "InputSystem.h"
|
||||||
#include "GameInterface.h"
|
#include "GameInterface.h"
|
||||||
|
#include "Camera.h"
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "Cube.h"
|
#include "Cube.h"
|
||||||
|
|
||||||
#include <ext/quaternion_float.hpp>
|
#include <glm/ext/quaternion_float.hpp>
|
||||||
|
|
||||||
#include <gl/glew.h>
|
#include <gl/glew.h>
|
||||||
|
|
||||||
struct Action {
|
struct Action {
|
||||||
glm::ivec3 axis;
|
protected:
|
||||||
int index;
|
Cube* _cube;
|
||||||
|
|
||||||
|
public:
|
||||||
double duration;
|
double duration;
|
||||||
|
|
||||||
Action() : axis(glm::ivec3(0)), index(0), duration(0.0f) { }
|
Action(Cube* cube, double duration) : _cube(cube), duration(duration) { }
|
||||||
|
virtual void Invoke() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
Action(const glm::ivec3& axis, int index, double duration)
|
struct ActionSpinDefault : public Action {
|
||||||
: axis(axis), index(index), duration(duration) {
|
glm::ivec3 axis;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
ActionSpinDefault() : Action(nullptr, 0.0f), axis(glm::ivec3(0)), index(0) { }
|
||||||
|
|
||||||
|
ActionSpinDefault(Cube* cube, const glm::ivec3& axis, int index, double duration)
|
||||||
|
: Action(cube, duration), axis(axis), index(index) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Invoke() override {
|
||||||
|
_cube->TransformAnimation(axis, index, glm::radians(90.0f), duration);
|
||||||
|
|
||||||
|
_cube->TransformData(axis, index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ActionSpinAfterDragging : public Action {
|
||||||
|
glm::ivec3 axis;
|
||||||
|
int index;
|
||||||
|
float angle;
|
||||||
|
int turns;
|
||||||
|
|
||||||
|
ActionSpinAfterDragging() : Action(nullptr, 0.0f), axis(glm::ivec3(0)), index(0), angle(0.0f), turns(0) { }
|
||||||
|
|
||||||
|
ActionSpinAfterDragging(Cube* cube, const glm::ivec3& axis, int index, float angle, int turns, double duration)
|
||||||
|
: Action(cube, duration), axis(axis), index(index), angle(angle), turns(turns) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Invoke() override {
|
||||||
|
_cube->TransformAnimation(axis, index, angle, duration);
|
||||||
|
|
||||||
|
_cube->TransformData(axis, index, turns);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SceneInterface : public GameInterface
|
class SceneInterface : public GameInterface
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Cube _cube;
|
Cube* _cube;
|
||||||
std::queue<Action> _actions;
|
Camera* _camera;
|
||||||
Action currentAction;
|
|
||||||
|
std::vector<Entity*> _entities;
|
||||||
|
|
||||||
|
std::queue<Action*> _actions;
|
||||||
|
Action* currentAction;
|
||||||
|
|
||||||
|
Debug* _debug;
|
||||||
|
|
||||||
InputSystem _inputSystem;
|
InputSystem _inputSystem;
|
||||||
|
|
||||||
glm::quat _orientation;
|
|
||||||
|
|
||||||
bool _wasMouseDown;
|
bool _wasMouseDown;
|
||||||
glm::vec2 _initialMouseLocation;
|
glm::vec2 _initialMouseLocation;
|
||||||
Plane _plane;
|
Plane _plane;
|
||||||
glm::vec2 _mousePositionPlane;
|
glm::vec2 _mousePositionPlane;
|
||||||
|
|
||||||
glm::mat4 _view;
|
int _spinIndex;
|
||||||
glm::mat4 _perspective;
|
glm::ivec3 _spinAxis;
|
||||||
|
float _spinDelta;
|
||||||
GLuint _shaderProgram;
|
|
||||||
GLuint _transformLocation;
|
|
||||||
GLuint _arrayBufferObject;
|
|
||||||
GLuint _vertexBufferObject;
|
|
||||||
|
|
||||||
const float MIN_DRAG_MAGNITUDE = 0.16f;
|
const float MIN_DRAG_MAGNITUDE = 0.16f;
|
||||||
|
|
||||||
void ApplyAction(const Action& action);
|
void ApplyAction(Action* action);
|
||||||
|
|
||||||
void OnDragStart();
|
void OnDragStart();
|
||||||
void OnDrag(double deltaTime);
|
void OnDrag(double deltaTime);
|
||||||
void OnDragStop();
|
void OnDragStop();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
SceneInterface();
|
||||||
|
~SceneInterface();
|
||||||
|
|
||||||
void Initialize(GLFWwindow* window) override;
|
void Initialize(GLFWwindow* window) override;
|
||||||
|
|
||||||
void Update(float deltaTime) override;
|
void Update(float deltaTime) override;
|
||||||
void Render(float aspectRatio) override;
|
void Render(float aspectRatio) override;
|
||||||
|
|
||||||
void EnqueueAction(const Action& action);
|
void EnqueueAction(Action* action);
|
||||||
|
|
||||||
void ClearResources() override;
|
void ClearResources() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
12
RubiksCube/Settings.h
Normal file
12
RubiksCube/Settings.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
const bool ENABLE_DEBUG = true;
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
const float TURN_ANIMATION_DURATION = 1.25f;
|
||||||
|
const float MIN_TURN_DISTANCE = 3.0f;
|
||||||
|
|
||||||
|
const float MIN_CAMERA_DISTANCE = 4.2f;
|
||||||
|
const float MAX_CAMERA_DISTANCE = 10.0f;
|
||||||
|
const float CAMERA_DISTANCE_START = 8.0f;
|
||||||
|
}
|
||||||
@ -1 +0,0 @@
|
|||||||
#include "Shader.h"
|
|
||||||
@ -1,5 +1,45 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
class Shader
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
#include "ShaderUtil.h"
|
||||||
|
|
||||||
|
class Shader {
|
||||||
|
private:
|
||||||
|
const char* _vert;
|
||||||
|
const char* _frag;
|
||||||
|
|
||||||
|
GLuint _id;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Shader(const char* vert, const char* frag) : _vert(vert), _frag(frag), _id(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~Shader() {
|
||||||
|
if (_id != 0) {
|
||||||
|
glDeleteProgram(_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint Reference() const { return _id; }
|
||||||
|
|
||||||
|
void Initialize() {
|
||||||
|
if (_id != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_id = ShaderUtil::CreateShaderProgram(_vert, _frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Use() {
|
||||||
|
Initialize();
|
||||||
|
|
||||||
|
glUseProgram(_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Disable() {
|
||||||
|
Initialize();
|
||||||
|
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
97
RubiksCube/Texture.h
Normal file
97
RubiksCube/Texture.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
#include <gl/glew.h>
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
class Texture {
|
||||||
|
private:
|
||||||
|
GLuint _id;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char* _texture;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GLuint Reference() const {
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Texture() : _id(0) { }
|
||||||
|
|
||||||
|
Texture(const char* file) {
|
||||||
|
int width, height, len;
|
||||||
|
|
||||||
|
stbi_set_flip_vertically_on_load(1);
|
||||||
|
unsigned char* data = stbi_load(file, &width, &height, &len, STBI_rgb_alpha);
|
||||||
|
|
||||||
|
glGenTextures(1, &_id);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, _id);
|
||||||
|
|
||||||
|
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_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
stbi_image_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture(const Texture& other) : Texture(other._texture) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture& operator=(const Texture& other) {
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
Texture copy(other._texture);
|
||||||
|
this->_id = other._id;
|
||||||
|
this->_texture = other._texture;
|
||||||
|
|
||||||
|
copy._id = 0;
|
||||||
|
copy._texture = nullptr;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture(Texture&& other) noexcept {
|
||||||
|
_id = other._id;
|
||||||
|
_texture = other._texture;
|
||||||
|
|
||||||
|
other._id = 0;
|
||||||
|
other._texture = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture& operator= (Texture&& other) noexcept {
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
this->_id = other._id;
|
||||||
|
this->_texture = other._texture;
|
||||||
|
|
||||||
|
other._id = 0;
|
||||||
|
other._texture = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Texture() {
|
||||||
|
if (_id == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glDeleteTextures(1, &_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Use() const {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, _id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Disable() const {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
@ -1,9 +1,45 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
in vec4 vertexColor;
|
in vec4 vertexColor;
|
||||||
|
|
||||||
|
in mat3 TBN;
|
||||||
|
|
||||||
|
in vec3 fPos;
|
||||||
|
in vec2 TCordinate;
|
||||||
|
|
||||||
|
uniform sampler2D diffuse;
|
||||||
|
uniform sampler2D roughness;
|
||||||
|
uniform sampler2D normal;
|
||||||
|
|
||||||
|
const vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);
|
||||||
|
const vec3 lightDir = vec3(-1.0f, -1.0f, 1.0f);
|
||||||
|
const float ambient = 0.24f;
|
||||||
|
const float specularValue = 1.0f;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
color = vertexColor;
|
vec4 diffuseBase = texture(diffuse, TCordinate);
|
||||||
|
|
||||||
|
vec3 normal = texture(normal, TCordinate).rgb;
|
||||||
|
normal = normal * 2.0f - 1.0f;
|
||||||
|
normal = normalize(mat3(view) * TBN * normal);
|
||||||
|
|
||||||
|
vec3 lightNormal = normalize(vec3(view * vec4(lightDir, 0.0f)));
|
||||||
|
|
||||||
|
float diffValue = max(dot(normal, lightNormal), 0.0f);
|
||||||
|
float diffuse = diffValue;
|
||||||
|
|
||||||
|
vec3 viewDir = normalize(-fPos);
|
||||||
|
|
||||||
|
vec3 reflectDir = reflect(-lightNormal, normal);
|
||||||
|
|
||||||
|
float spec = pow(max(dot(viewDir, reflectDir), 0.0f), 16);
|
||||||
|
float specular = specularValue * spec;
|
||||||
|
|
||||||
|
float roughness = texture(roughness, TCordinate).g;
|
||||||
|
|
||||||
|
color = vertexColor * diffuseBase * vec4((ambient + diffuse) * lightColor, 1.0f) + vec4(roughness * specular * lightColor, 1.0f);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,34 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
uniform mat4 transformation;
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
layout (location=0) in vec3 position;
|
layout (location=0) in vec3 position;
|
||||||
layout (location=1) in vec4 color;
|
layout (location=1) in vec3 normal;
|
||||||
|
layout (location=2) in vec2 uv0;
|
||||||
|
layout (location=3) in vec3 tangent;
|
||||||
|
layout (location=4) in vec3 bitangent;
|
||||||
|
layout (location=5) in vec4 color;
|
||||||
|
|
||||||
out vec4 vertexColor;
|
out vec4 vertexColor;
|
||||||
|
|
||||||
|
out mat3 TBN;
|
||||||
|
|
||||||
|
out vec3 fPos;
|
||||||
|
out vec2 TCordinate;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = transformation * vec4(position, 1.0f);
|
gl_Position = projection * view * model * vec4(position, 1.0f);
|
||||||
|
|
||||||
|
fPos = vec3(view * model * vec4(position, 1.0f));
|
||||||
|
|
||||||
vertexColor = color;
|
vertexColor = color;
|
||||||
|
|
||||||
|
vec3 T = normalize(vec3(model * vec4(tangent, 0.0f)));
|
||||||
|
vec3 B = normalize(vec3(model * vec4(bitangent, 0.0f)));
|
||||||
|
vec3 N = normalize(vec3(model * vec4(normal, 0.0f)));
|
||||||
|
TBN = mat3(T, B, N);
|
||||||
|
|
||||||
|
TCordinate = uv0;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
RubiksCube/diffuse.png
Normal file
BIN
RubiksCube/diffuse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
BIN
RubiksCube/diffuse_test.png
Normal file
BIN
RubiksCube/diffuse_test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
19
RubiksCube/line.frag
Normal file
19
RubiksCube/line.frag
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
const float blend = 1.5f;
|
||||||
|
|
||||||
|
in float lineStrength;
|
||||||
|
|
||||||
|
in vec4 color;
|
||||||
|
in float lineWidth;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec4 col = color;
|
||||||
|
float d = length(vec2(lineStrength) - gl_FragCoord.xy);
|
||||||
|
float w = lineWidth;
|
||||||
|
|
||||||
|
fragColor = col;
|
||||||
|
}
|
||||||
69
RubiksCube/line.vert
Normal file
69
RubiksCube/line.vert
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
uniform vec2 uViewportRes;
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 position;
|
||||||
|
layout (location = 1) in vec3 tangent;
|
||||||
|
layout (location = 2) in vec4 iColor;
|
||||||
|
layout (location = 3) in float iLineWidth;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
out float lineWidth;
|
||||||
|
out float lineStrength;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
int index = gl_VertexID % 6;
|
||||||
|
float orientation = 1.0f + ( (index % 2) * -2 );
|
||||||
|
|
||||||
|
vec4 positionScreen = projection * view * model * vec4(position, 1.0f);
|
||||||
|
vec4 directionScreen = projection * view * model * vec4(position + tangent, 0.0f);
|
||||||
|
|
||||||
|
vec4 normal = positionScreen - directionScreen;
|
||||||
|
|
||||||
|
positionScreen.xyz /= positionScreen.w;
|
||||||
|
positionScreen.xy *= (uViewportRes * 0.5f);
|
||||||
|
|
||||||
|
float aspectRatio = projection[1][1] / projection[0][0];
|
||||||
|
|
||||||
|
normal.xyz /= normal.w;
|
||||||
|
positionScreen += vec4(normalize(normal.yx * vec2(-1.0f, 1.0f) * orientation), 0.0f, 0.0f) * 0.5f * iLineWidth;
|
||||||
|
|
||||||
|
positionScreen.xy /= (uViewportRes * 0.5f);
|
||||||
|
positionScreen.xyz *= positionScreen.w;
|
||||||
|
|
||||||
|
|
||||||
|
gl_Position = positionScreen;
|
||||||
|
|
||||||
|
lineWidth = iLineWidth;
|
||||||
|
lineStrength = orientation;
|
||||||
|
color = iColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainBackup(void)
|
||||||
|
{
|
||||||
|
float aspectRatio = 0.0f;
|
||||||
|
|
||||||
|
int index = gl_VertexID % 6;
|
||||||
|
float orientation = 1 + ( (index % 2) * -2 );
|
||||||
|
|
||||||
|
vec4 positionCamera = view * model * vec4(position, 1.0f);
|
||||||
|
|
||||||
|
float distance = -position.z;
|
||||||
|
|
||||||
|
vec4 tv = projection * view * model * vec4(position + tangent, 0.0f);
|
||||||
|
|
||||||
|
vec4 v = vec4(normalize(tv.yx) * orientation * vec2(-1.0f, 1.0f), 0.0f, 0.0f) * distance;
|
||||||
|
|
||||||
|
vec4 direction = positionCamera - tv;
|
||||||
|
|
||||||
|
direction.xy = direction.yx * vec2(-1.0f, 1.0f) * orientation;
|
||||||
|
|
||||||
|
gl_Position = (projection * positionCamera) + vec4(direction.xy, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
lineWidth = iLineWidth;
|
||||||
|
lineStrength = orientation;
|
||||||
|
color = vec4(iColor.xyz, 1.0f);
|
||||||
|
}
|
||||||
BIN
RubiksCube/normal.png
Normal file
BIN
RubiksCube/normal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
RubiksCube/roughness.png
Normal file
BIN
RubiksCube/roughness.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
39
readme.txt
Normal file
39
readme.txt
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
Rubiks Cube Projekt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Steuerung:
|
||||||
|
|
||||||
|
Linke Maustaste Halten und Ziehen Cube angeklickte Scheibe drehen
|
||||||
|
Rechte Maustaste Halten und Ziehen Kamera drehen
|
||||||
|
Scrollrad Zoom
|
||||||
|
|
||||||
|
Shift + Numpad 1, 2, 3 ( Numlock ausschalten! ) Cube Horizontal nach unten
|
||||||
|
Shift + Numpad 7, 8, 9 ( Numlock ausschalten! ) Cube Horizontal nach oben
|
||||||
|
Numpad 1, 4, 7 Cube vertikal links drehen
|
||||||
|
Numpad 9, 6, 3 Cube vertikal rechts drehen
|
||||||
|
|
||||||
|
Space Ansicht ( Drehung ) zurücksetzen
|
||||||
|
|
||||||
|
Kurze Übersicht der Welt:
|
||||||
|
Die Anwendung wird gestartet, mit der Kamera von vorne auf den Cube gerichtet.
|
||||||
|
Der Cube bleibt im World-Space ohne Veränderungen.
|
||||||
|
Die Kamera dreht sich um den Cube herum.
|
||||||
|
Die Lichtquelle leuchtet von unten links und von vorne.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Logische Repräsentation
|
||||||
|
- Tastatursteuerung
|
||||||
|
- + Animations
|
||||||
|
- Kamerasteuerung
|
||||||
|
- Maussteuerung Kamerarelativ
|
||||||
|
- + Animations
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Rendering:
|
||||||
|
- Directional Lighting
|
||||||
|
- Blinn-Shading
|
||||||
|
- Diffuse Texturierung
|
||||||
|
- Normal Map mit Textur als Normal
|
||||||
|
- Specular Map
|
||||||
Loading…
x
Reference in New Issue
Block a user