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