Initial commit
This commit is contained in:
commit
9ded69e903
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/cmake-build-debug/
|
4
CMakeLists.txt
Normal file
4
CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
project(graphics_labs)
|
||||||
|
|
||||||
|
add_subdirectory(lab2)
|
7
README.md
Normal file
7
README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Лабы по компьютерной графике 3 курс 2 семестр
|
||||||
|
|
||||||
|
## Lab2
|
||||||
|
Для сборки нужно выбрать цель Lab2, рабочая директория - lab2. Создана 23 марта 2023 года.
|
||||||
|
|
||||||
|
|
||||||
|
|
29
lab2/CMakeLists.txt
Normal file
29
lab2/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
project(Lab2)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
|
find_package(glfw3 3.3 REQUIRED)
|
||||||
|
find_package(GLEW REQUIRED)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
find_package(glm REQUIRED)
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
${PROJECT_NAME}
|
||||||
|
|
||||||
|
src/main.cpp
|
||||||
|
src/window/Camera.cpp
|
||||||
|
src/window/Camera.h
|
||||||
|
src/window/Window.cpp
|
||||||
|
src/window/Window.h
|
||||||
|
src/window/Events.cpp
|
||||||
|
src/window/Events.h
|
||||||
|
src/graphics/Mesh.h
|
||||||
|
src/graphics/Mesh.cpp
|
||||||
|
src/graphics/Shader.h
|
||||||
|
src/graphics/Shader.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME} glfw)
|
||||||
|
target_link_libraries(${PROJECT_NAME} GLEW::GLEW)
|
||||||
|
target_link_libraries(${PROJECT_NAME} OpenGL::GL)
|
10
lab2/res/main.fsh
Normal file
10
lab2/res/main.fsh
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec4 a_color;
|
||||||
|
|
||||||
|
out vec4 f_color;
|
||||||
|
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
f_color = a_color;
|
||||||
|
}
|
14
lab2/res/main.vsh
Normal file
14
lab2/res/main.vsh
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 v_position;
|
||||||
|
layout (location = 1) in float light;
|
||||||
|
|
||||||
|
out vec4 a_color;
|
||||||
|
uniform mat4 projview;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
// gl_Position = vec4(v_position, 1) * projview;
|
||||||
|
gl_Position = projview * vec4(v_position, 1);
|
||||||
|
a_color = vec4(0.5, 0, 1, 1) * light;
|
||||||
|
}
|
||||||
|
|
50
lab2/src/graphics/Mesh.cpp
Normal file
50
lab2/src/graphics/Mesh.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include "Mesh.h"
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
Mesh::Mesh(const float* buffer, size_t vertices, const int* attrs) : vertices(vertices){
|
||||||
|
vertexSize = 0;
|
||||||
|
for (int i = 0; attrs[i]; i++){
|
||||||
|
vertexSize += attrs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &vao);
|
||||||
|
glGenBuffers(1, &vbo);
|
||||||
|
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
if (buffer){
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, buffer, GL_STATIC_DRAW);
|
||||||
|
} else {
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, 0, {}, GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
int offset = 0;
|
||||||
|
for (int i = 0; attrs[i]; i++){
|
||||||
|
int size = attrs[i];
|
||||||
|
glVertexAttribPointer(i, size, GL_FLOAT, GL_FALSE, vertexSize * sizeof(float), (GLvoid*)(offset * sizeof(float)));
|
||||||
|
glEnableVertexAttribArray(i);
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh::~Mesh(){
|
||||||
|
glDeleteVertexArrays(1, &vao);
|
||||||
|
glDeleteBuffers(1, &vbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::reload(const float* buffer, size_t vertices){
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, buffer, GL_STATIC_DRAW);
|
||||||
|
this->vertices = vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::draw(){
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, vertices);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
19
lab2/src/graphics/Mesh.h
Normal file
19
lab2/src/graphics/Mesh.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef GRAPHICS_MESH_H_
|
||||||
|
#define GRAPHICS_MESH_H_
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
class Mesh {
|
||||||
|
unsigned int vao;
|
||||||
|
unsigned int vbo;
|
||||||
|
size_t vertices;
|
||||||
|
size_t vertexSize;
|
||||||
|
public:
|
||||||
|
Mesh(const float* buffer, size_t vertices, const int* attrs);
|
||||||
|
~Mesh();
|
||||||
|
|
||||||
|
void reload(const float* buffer, size_t vertices);
|
||||||
|
void draw();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* GRAPHICS_MESH_H_ */
|
128
lab2/src/graphics/Shader.cpp
Normal file
128
lab2/src/graphics/Shader.cpp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#include "Shader.h"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
Shader::Shader(unsigned int id) : id(id){
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::~Shader(){
|
||||||
|
glDeleteProgram(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::use(){
|
||||||
|
glUseProgram(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::uniformMatrix(const std::string &name, glm::mat4 matrix){
|
||||||
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
|
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(matrix));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::uniform1i(const std::string &name, int x){
|
||||||
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
|
glUniform1i(transformLoc, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::uniform1f(const std::string &name, float x){
|
||||||
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
|
glUniform1f(transformLoc, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::uniform2f(const std::string &name, float x, float y){
|
||||||
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
|
glUniform2f(transformLoc, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::uniform3f(const std::string &name, float x, float y, float z){
|
||||||
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
|
glUniform3f(transformLoc, x,y,z);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader* Shader::loadShader(const std::string& vertexFile, const std::string& fragmentFile) {
|
||||||
|
// Reading Files
|
||||||
|
std::string vertexCode;
|
||||||
|
std::string fragmentCode;
|
||||||
|
std::ifstream vShaderFile;
|
||||||
|
std::ifstream fShaderFile;
|
||||||
|
|
||||||
|
vShaderFile.exceptions(std::ifstream::badbit);
|
||||||
|
fShaderFile.exceptions(std::ifstream::badbit);
|
||||||
|
try {
|
||||||
|
vShaderFile.open(vertexFile);
|
||||||
|
fShaderFile.open(fragmentFile);
|
||||||
|
std::stringstream vShaderStream, fShaderStream;
|
||||||
|
|
||||||
|
vShaderStream << vShaderFile.rdbuf();
|
||||||
|
fShaderStream << fShaderFile.rdbuf();
|
||||||
|
|
||||||
|
vShaderFile.close();
|
||||||
|
fShaderFile.close();
|
||||||
|
|
||||||
|
vertexCode = vShaderStream.str();
|
||||||
|
fragmentCode = fShaderStream.str();
|
||||||
|
}
|
||||||
|
catch(std::ifstream::failure& e) {
|
||||||
|
std::cerr << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const GLchar* vShaderCode = vertexCode.c_str();
|
||||||
|
const GLchar* fShaderCode = fragmentCode.c_str();
|
||||||
|
|
||||||
|
GLuint vertex, fragment;
|
||||||
|
GLint success;
|
||||||
|
GLchar infoLog[512];
|
||||||
|
|
||||||
|
// Vertex Shader
|
||||||
|
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(vertex, 1, &vShaderCode, nullptr);
|
||||||
|
glCompileShader(vertex);
|
||||||
|
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
|
||||||
|
if (!success){
|
||||||
|
glGetShaderInfoLog(vertex, 512, nullptr, infoLog);
|
||||||
|
std::cerr << "SHADER::VERTEX: compilation failed" << std::endl;
|
||||||
|
std::cerr << infoLog << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fragment Shader
|
||||||
|
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(fragment, 1, &fShaderCode, nullptr);
|
||||||
|
glCompileShader(fragment);
|
||||||
|
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
|
||||||
|
if (!success){
|
||||||
|
glGetShaderInfoLog(fragment, 512, nullptr, infoLog);
|
||||||
|
std::cerr << "SHADER::FRAGMENT: compilation failed" << std::endl;
|
||||||
|
std::cerr << infoLog << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shader Program
|
||||||
|
GLuint id = glCreateProgram();
|
||||||
|
glAttachShader(id, vertex);
|
||||||
|
glAttachShader(id, fragment);
|
||||||
|
glLinkProgram(id);
|
||||||
|
|
||||||
|
glGetProgramiv(id, GL_LINK_STATUS, &success);
|
||||||
|
if (!success){
|
||||||
|
glGetProgramInfoLog(id, 512, nullptr, infoLog);
|
||||||
|
std::cerr << "SHADER::PROGRAM: linking failed" << std::endl;
|
||||||
|
std::cerr << infoLog << std::endl;
|
||||||
|
|
||||||
|
glDeleteShader(vertex);
|
||||||
|
glDeleteShader(fragment);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteShader(vertex);
|
||||||
|
glDeleteShader(fragment);
|
||||||
|
|
||||||
|
return new Shader(id);
|
||||||
|
}
|
25
lab2/src/graphics/Shader.h
Normal file
25
lab2/src/graphics/Shader.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef GRAPHICS_SHADER_H_
|
||||||
|
#define GRAPHICS_SHADER_H_
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class Shader {
|
||||||
|
public:
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
|
explicit Shader(unsigned int id);
|
||||||
|
~Shader();
|
||||||
|
|
||||||
|
void use();
|
||||||
|
void uniformMatrix(const std::string& name, glm::mat4 matrix);
|
||||||
|
void uniform1i(const std::string& name, int x);
|
||||||
|
void uniform1f(const std::string& name, float x);
|
||||||
|
void uniform2f(const std::string& name, float x, float y);
|
||||||
|
void uniform3f(const std::string& name, float x, float y, float z);
|
||||||
|
|
||||||
|
static Shader* loadShader(const std::string& vertexFile, const std::string& fragmentFile);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* GRAPHICS_SHADER_H_ */
|
184
lab2/src/main.cpp
Normal file
184
lab2/src/main.cpp
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
// GLM
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
#include "window/Window.h"
|
||||||
|
#include "window/Camera.h"
|
||||||
|
#include "window/Events.h"
|
||||||
|
#include "graphics/Mesh.h"
|
||||||
|
#include "graphics/Shader.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define SPEED_FACTOR 2.5f
|
||||||
|
|
||||||
|
|
||||||
|
static void updateCameraPosition(Camera& cam, float delta) {
|
||||||
|
static float camX = 0, camY= 0;
|
||||||
|
|
||||||
|
if (Events::_cursor_locked){
|
||||||
|
camY += -Events::deltaY / (float)Window::height * 2;
|
||||||
|
camX += -Events::deltaX / (float)Window::height * 2;
|
||||||
|
|
||||||
|
if (camY < -glm::radians(89.0f)){
|
||||||
|
camY = -glm::radians(89.0f);
|
||||||
|
}
|
||||||
|
if (camY > glm::radians(89.0f)){
|
||||||
|
camY = glm::radians(89.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
cam.rotation = glm::mat4(1.0f);
|
||||||
|
cam.rotate(camY, camX, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cam.updateVectors();
|
||||||
|
|
||||||
|
glm::vec3 dir(0,0,0);
|
||||||
|
if (Events::pressed(GLFW_KEY_W)){
|
||||||
|
dir.x += cam.dir.x;
|
||||||
|
dir.z += cam.dir.z;
|
||||||
|
}
|
||||||
|
if (Events::pressed(GLFW_KEY_S)){
|
||||||
|
dir.x -= cam.dir.x;
|
||||||
|
dir.z -= cam.dir.z;
|
||||||
|
}
|
||||||
|
if (Events::pressed(GLFW_KEY_D)){
|
||||||
|
dir.x += cam.right.x;
|
||||||
|
dir.z += cam.right.z;
|
||||||
|
}
|
||||||
|
if (Events::pressed(GLFW_KEY_A)){
|
||||||
|
dir.x -= cam.right.x;
|
||||||
|
dir.z -= cam.right.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Events::pressed(GLFW_KEY_SPACE)) {
|
||||||
|
dir.y = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Events::pressed(GLFW_KEY_LEFT_SHIFT)) {
|
||||||
|
dir.y = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir.x != 0 || dir.y != 0 || dir.z != 0) {
|
||||||
|
dir = glm::normalize(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
cam.position += dir * delta * SPEED_FACTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Mesh* world;
|
||||||
|
static Shader* shader;
|
||||||
|
static void drawWorld(Camera& cam) {
|
||||||
|
auto projview = cam.getProjection() * cam.getView();
|
||||||
|
shader->use();
|
||||||
|
|
||||||
|
// shader->uniformMatrix("pr", cam.getProjection() * cam.getView());
|
||||||
|
shader->uniformMatrix("projview", projview);
|
||||||
|
world->draw();
|
||||||
|
|
||||||
|
auto model_scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
|
static float angle = 0.0f;
|
||||||
|
|
||||||
|
auto model_translate = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, -2));
|
||||||
|
auto model_rotate = glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0, 1, 0));
|
||||||
|
angle += 0.001f;
|
||||||
|
|
||||||
|
shader->uniformMatrix("projview", projview * model_scale * model_translate * model_rotate);
|
||||||
|
world->draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mainloop(Camera& camera) {
|
||||||
|
long frame = 0;
|
||||||
|
float lastTime = Window::getTime();
|
||||||
|
float delta;
|
||||||
|
|
||||||
|
bool devdata = false;
|
||||||
|
Window::swapInterval(0);
|
||||||
|
while (!Window::isShouldClose()){
|
||||||
|
frame++;
|
||||||
|
float currentTime = Window::getTime();
|
||||||
|
delta = currentTime - lastTime;
|
||||||
|
lastTime = currentTime;
|
||||||
|
|
||||||
|
if (Events::jpressed(GLFW_KEY_ESCAPE)){
|
||||||
|
Window::setShouldClose(true);
|
||||||
|
}
|
||||||
|
if (Events::jpressed(GLFW_KEY_TAB)){
|
||||||
|
Events::toggleCursor();
|
||||||
|
}
|
||||||
|
if (Events::jpressed(GLFW_KEY_F3)){
|
||||||
|
devdata = !devdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCameraPosition(camera, delta);
|
||||||
|
|
||||||
|
drawWorld(camera);
|
||||||
|
|
||||||
|
// worldRenderer.draw(world, camera, occlusion);
|
||||||
|
// hud.draw(level, assets);
|
||||||
|
// if (devdata) {
|
||||||
|
// hud.drawDebug(level, assets, fps, occlusion);
|
||||||
|
// }
|
||||||
|
|
||||||
|
Window::swapBuffers();
|
||||||
|
Events::pullEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadResources() {
|
||||||
|
const float buffer[] = {
|
||||||
|
// треугольник
|
||||||
|
// X Y Z Light
|
||||||
|
-1, -1, 0.5, 0.5,
|
||||||
|
1, -1, 0.5, 0.1,
|
||||||
|
0, 1, 0.5, 0.9,
|
||||||
|
|
||||||
|
-1, -1, -0.5, 0.5,
|
||||||
|
1, -1, -0.5, 0.1,
|
||||||
|
0, 1, -0.5, 0.9,
|
||||||
|
};
|
||||||
|
const int mesh_attrs[] {
|
||||||
|
3, 1, 0
|
||||||
|
};
|
||||||
|
world = new Mesh(buffer, 6, mesh_attrs);
|
||||||
|
|
||||||
|
shader = Shader::loadShader("res/main.vsh", "res/main.fsh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void unloadResources() {
|
||||||
|
delete world;
|
||||||
|
delete shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Window::initialize(800, 600, "Lab2");
|
||||||
|
Events::initialize();
|
||||||
|
|
||||||
|
loadResources();
|
||||||
|
|
||||||
|
// glDisable(GL_DEPTH_TEST);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
Camera cam(glm::vec3(0, 0, 5), glm::radians(90.0f));
|
||||||
|
|
||||||
|
mainloop(cam);
|
||||||
|
|
||||||
|
unloadResources();
|
||||||
|
|
||||||
|
Events::finalize();
|
||||||
|
Window::terminate();
|
||||||
|
return 0;
|
||||||
|
}
|
57
lab2/src/window/Camera.cpp
Normal file
57
lab2/src/window/Camera.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// Created by vlad on 23.03.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "Window.h"
|
||||||
|
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
|
using namespace glm;
|
||||||
|
|
||||||
|
Camera::Camera(vec3 position, float fov) : position(position), fov(fov), rotation(1.0f) {
|
||||||
|
updateVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::updateVectors(){
|
||||||
|
front = vec3(rotation * vec4(0,0,-1,1));
|
||||||
|
right = vec3(rotation * vec4(1,0,0,1));
|
||||||
|
up = vec3(rotation * vec4(0,1,0,1));
|
||||||
|
dir = vec3(rotation * vec4(0,0,-1,1));
|
||||||
|
dir.y = 0;
|
||||||
|
float len = length(dir);
|
||||||
|
if (len > 0.0f){
|
||||||
|
dir.x /= len;
|
||||||
|
dir.z /= len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::rotate(float x, float y, float z){
|
||||||
|
rotation = glm::rotate(rotation, z, vec3(0,0,1));
|
||||||
|
rotation = glm::rotate(rotation, y, vec3(0,1,0));
|
||||||
|
rotation = glm::rotate(rotation, x, vec3(1,0,0));
|
||||||
|
|
||||||
|
updateVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 Camera::getProjection(){
|
||||||
|
float as = this->aspect;
|
||||||
|
if (as == 0.0f){
|
||||||
|
as = (float)Window::width / (float)Window::height;
|
||||||
|
}
|
||||||
|
if (perspective)
|
||||||
|
return glm::perspective(fov, as, 0.05f, 1500.0f);
|
||||||
|
else
|
||||||
|
if (flipped)
|
||||||
|
return glm::ortho(0.0f, fov * as, fov, 0.0f);
|
||||||
|
else
|
||||||
|
return glm::ortho(0.0f, fov * as, 0.0f, fov);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 Camera::getView(){
|
||||||
|
if (perspective)
|
||||||
|
return glm::lookAt(position, position+front, up);
|
||||||
|
else
|
||||||
|
return glm::translate(glm::mat4(1.0f), position);
|
||||||
|
}
|
||||||
|
|
33
lab2/src/window/Camera.h
Normal file
33
lab2/src/window/Camera.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// Created by vlad on 23.03.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_LABS_CAMERA_H
|
||||||
|
#define GRAPHICS_LABS_CAMERA_H
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class Camera {
|
||||||
|
public:
|
||||||
|
void updateVectors();
|
||||||
|
|
||||||
|
glm::vec3 front;
|
||||||
|
glm::vec3 up;
|
||||||
|
glm::vec3 right;
|
||||||
|
glm::vec3 dir;
|
||||||
|
|
||||||
|
glm::vec3 position;
|
||||||
|
float fov;
|
||||||
|
glm::mat4 rotation;
|
||||||
|
bool perspective = true;
|
||||||
|
bool flipped = false;
|
||||||
|
float aspect = 0.0f;
|
||||||
|
Camera(glm::vec3 position, float fov);
|
||||||
|
|
||||||
|
void rotate(float x, float y, float z);
|
||||||
|
|
||||||
|
glm::mat4 getProjection();
|
||||||
|
glm::mat4 getView();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GRAPHICS_LABS_CAMERA_H
|
114
lab2/src/window/Events.cpp
Normal file
114
lab2/src/window/Events.cpp
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
//
|
||||||
|
// Created by vlad on 23.03.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Events.h"
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
bool* Events::_keys;
|
||||||
|
uint* Events::_frames;
|
||||||
|
uint Events::_current = 0;
|
||||||
|
float Events::deltaX = 0.0f;
|
||||||
|
float Events::deltaY = 0.0f;
|
||||||
|
float Events::x = 0.0f;
|
||||||
|
float Events::y = 0.0f;
|
||||||
|
bool Events::_cursor_locked = false;
|
||||||
|
bool Events::_cursor_started = false;
|
||||||
|
|
||||||
|
#define _MOUSE_BUTTONS 1024
|
||||||
|
|
||||||
|
void cursor_position_callback(GLFWwindow* window, double xpos, double ypos){
|
||||||
|
if (Events::_cursor_started){
|
||||||
|
Events::deltaX += xpos-Events::x;
|
||||||
|
Events::deltaY += ypos-Events::y;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Events::_cursor_started = true;
|
||||||
|
}
|
||||||
|
Events::x = xpos;
|
||||||
|
Events::y = ypos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_button_callback(GLFWwindow* window, int button, int action, int mode){
|
||||||
|
if (action == GLFW_PRESS){
|
||||||
|
Events::_keys[_MOUSE_BUTTONS+button] = true;
|
||||||
|
Events::_frames[_MOUSE_BUTTONS+button] = Events::_current;
|
||||||
|
}
|
||||||
|
else if (action == GLFW_RELEASE){
|
||||||
|
Events::_keys[_MOUSE_BUTTONS+button] = false;
|
||||||
|
Events::_frames[_MOUSE_BUTTONS+button] = Events::_current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) {
|
||||||
|
if (action == GLFW_PRESS){
|
||||||
|
Events::_keys[key] = true;
|
||||||
|
Events::_frames[key] = Events::_current;
|
||||||
|
}
|
||||||
|
else if (action == GLFW_RELEASE){
|
||||||
|
Events::_keys[key] = false;
|
||||||
|
Events::_frames[key] = Events::_current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void window_size_callback(GLFWwindow* window, int width, int height){
|
||||||
|
glViewport(0,0, width, height);
|
||||||
|
Window::width = width;
|
||||||
|
Window::height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Events::initialize(){
|
||||||
|
GLFWwindow* window = Window::window;
|
||||||
|
_keys = new bool[1032];
|
||||||
|
_frames = new uint[1032];
|
||||||
|
|
||||||
|
memset(_keys, false, 1032*sizeof(bool));
|
||||||
|
memset(_frames, 0, 1032*sizeof(uint));
|
||||||
|
|
||||||
|
glfwSetKeyCallback(window, key_callback);
|
||||||
|
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||||
|
glfwSetCursorPosCallback(window, cursor_position_callback);
|
||||||
|
glfwSetWindowSizeCallback(window, window_size_callback);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::finalize(){
|
||||||
|
delete[] _keys;
|
||||||
|
delete[] _frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Events::pressed(int keycode){
|
||||||
|
if (keycode < 0 || keycode >= _MOUSE_BUTTONS)
|
||||||
|
return false;
|
||||||
|
return _keys[keycode];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Events::jpressed(int keycode){
|
||||||
|
if (keycode < 0 || keycode >= _MOUSE_BUTTONS)
|
||||||
|
return false;
|
||||||
|
return _keys[keycode] && _frames[keycode] == _current;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Events::clicked(int button){
|
||||||
|
int index = _MOUSE_BUTTONS+button;
|
||||||
|
return _keys[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Events::jclicked(int button){
|
||||||
|
int index = _MOUSE_BUTTONS+button;
|
||||||
|
return _keys[index] && _frames[index] == _current;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::toggleCursor(){
|
||||||
|
_cursor_locked = !_cursor_locked;
|
||||||
|
Window::setCursorMode(_cursor_locked ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::pullEvents(){
|
||||||
|
_current++;
|
||||||
|
deltaX = 0.0f;
|
||||||
|
deltaY = 0.0f;
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
37
lab2/src/window/Events.h
Normal file
37
lab2/src/window/Events.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// Created by vlad on 23.03.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_LABS_EVENTS_H
|
||||||
|
#define GRAPHICS_LABS_EVENTS_H
|
||||||
|
|
||||||
|
#include "Window.h"
|
||||||
|
|
||||||
|
typedef unsigned int uint;
|
||||||
|
|
||||||
|
class Events {
|
||||||
|
public:
|
||||||
|
static bool* _keys;
|
||||||
|
static uint* _frames;
|
||||||
|
static uint _current;
|
||||||
|
static float deltaX;
|
||||||
|
static float deltaY;
|
||||||
|
static float x;
|
||||||
|
static float y;
|
||||||
|
static bool _cursor_locked;
|
||||||
|
static bool _cursor_started;
|
||||||
|
|
||||||
|
static int initialize();
|
||||||
|
static void finalize();
|
||||||
|
static void pullEvents();
|
||||||
|
|
||||||
|
static bool pressed(int keycode);
|
||||||
|
static bool jpressed(int keycode);
|
||||||
|
|
||||||
|
static bool clicked(int button);
|
||||||
|
static bool jclicked(int button);
|
||||||
|
|
||||||
|
static void toggleCursor();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GRAPHICS_LABS_EVENTS_H
|
83
lab2/src/window/Window.cpp
Normal file
83
lab2/src/window/Window.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
//
|
||||||
|
// Created by vlad on 23.03.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include "Window.h"
|
||||||
|
|
||||||
|
GLFWwindow* Window::window;
|
||||||
|
int Window::width = 0;
|
||||||
|
int Window::height = 0;
|
||||||
|
|
||||||
|
int Window::initialize(int w, int h, const char* title){
|
||||||
|
glfwInit();
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
|
||||||
|
//glfwWindowHint(GLFW_SAMPLES, 2);
|
||||||
|
|
||||||
|
window = glfwCreateWindow(w, h, title, nullptr, nullptr);
|
||||||
|
if (window == nullptr){
|
||||||
|
std::cerr << "Failed to create GLFW Window" << std::endl;
|
||||||
|
glfwTerminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
|
||||||
|
glewExperimental = GL_TRUE;
|
||||||
|
if (glewInit() != GLEW_OK){
|
||||||
|
std::cerr << "Failed to initialize GLEW" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
glViewport(0, 0, w, h);
|
||||||
|
|
||||||
|
glClearColor(0.0f,0.0f,0.0f,1);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
Window::width = w;
|
||||||
|
Window::height = h;
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::viewport(int x, int y, int w, int h){
|
||||||
|
glViewport(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::setCursorMode(int mode){
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::terminate(){
|
||||||
|
glfwTerminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::isShouldClose(){
|
||||||
|
return glfwWindowShouldClose(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::setShouldClose(bool flag){
|
||||||
|
glfwSetWindowShouldClose(window, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::swapInterval(int interval){
|
||||||
|
glfwSwapInterval(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::swapBuffers(){
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Window::getTime() {
|
||||||
|
return (float)glfwGetTime();
|
||||||
|
}
|
28
lab2/src/window/Window.h
Normal file
28
lab2/src/window/Window.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Created by vlad on 23.03.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_LABS_WINDOW_H
|
||||||
|
#define GRAPHICS_LABS_WINDOW_H
|
||||||
|
|
||||||
|
class GLFWwindow;
|
||||||
|
|
||||||
|
class Window {
|
||||||
|
public:
|
||||||
|
static int width;
|
||||||
|
static int height;
|
||||||
|
static GLFWwindow* window; // не лучшее решение делать window публичным
|
||||||
|
static int initialize(int w, int h, const char* title);
|
||||||
|
static void terminate();
|
||||||
|
|
||||||
|
static void viewport(int x, int y, int w, int h);
|
||||||
|
static void setCursorMode(int mode);
|
||||||
|
static bool isShouldClose();
|
||||||
|
static void setShouldClose(bool flag);
|
||||||
|
static void swapBuffers();
|
||||||
|
static void swapInterval(int interval);
|
||||||
|
|
||||||
|
static float getTime();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GRAPHICS_LABS_WINDOW_H
|
Loading…
x
Reference in New Issue
Block a user