Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 29.04.2025
Сообщений: 1

Камера в GLFW

29.04.2025, 18:40. Показов 1496. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здарова мужики, не могу понять как перемещать камеру. Создал для нее отдельный класс, но чот не вдупляю где ошибка. Делал на основе ответа нейронки, т.к. сам только начал путь в плюсах. Если есть ошибки в оформлении кода (нечистаемость например) отпишитесь.

Класс камеры:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "Camera.hpp"
#include <glm/gtc/matrix_transform.hpp>
#include <glad/glad.h>
#include <glm/ext/vector_float3.hpp>
#include <iostream>
#include <glm/gtc/type_ptr.hpp>
 
// Шейдерные программы
const char* cameraVertexShader = R"(
#version 330 core
layout (location = 0) in vec3 aPos;
 
uniform mat4 view;
uniform mat4 projection;
uniform mat4 model;
 
void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
}
)";
 
const char* cameraFragmentShader = R"(
#version 330 core
out vec4 FragColor;
 
void main()
{
    FragColor = vec4(1.0, 1.0, 1.0, 1.0); // Белый цвет по умолчанию
}
)";
 
GLuint createShaderProgramCam() {
    // Вершинный шейдер
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &cameraVertexShader, NULL);
    glCompileShader(vertexShader);
 
    // Проверка ошибок компиляции вершинного шейдера
    GLint success;
    GLchar infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cerr << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
 
    // Фрагментный шейдер
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &cameraFragmentShader, NULL);
    glCompileShader(fragmentShader);
 
    // Проверка ошибок компиляции фрагментного шейдера
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cerr << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
 
    // Шейдерная программа
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
 
    // Проверка ошибок линковки
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cerr << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
    }
 
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
 
    return shaderProgram;
}
 
Camera::Camera(glm::vec3 position) : position(position) {
    // Установка позиции и векторов по умолчанию
    target = glm::vec3(0.0f, 0.0f, 0.0f);
    up = glm::vec3(0.0f, 1.0f, 0.0f);
    shaderProgram = createShaderProgramCam();
 
    // Инициализация матрицы проекции
    projection = glm::perspective(
        glm::radians(45.0f),  // Угол обзора (FOV) в градусах
        800.0f / 600.0f,      // Соотношение сторон (ширина/высота)
        0.1f,                 // Ближняя плоскость отсечения (near)
        1000.0f                // Дальняя плоскость отсечения (far)
    );
}
 
Camera::~Camera() {
    glDeleteProgram(shaderProgram);
}
 
void Camera::Draw() {
    glUseProgram(shaderProgram);
 
    // Матрица вида (камера)
    glm::mat4 view = glm::lookAt(
        position,    // Положение камеры
        target,      // Направление камеры (куда смотрит)
        up           // Вектор "вверх"
    );
 
    // Передаем матрицы в шейдер
    GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
 
    GLint projLoc = glGetUniformLocation(shaderProgram, "projection");
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
 
    glm::mat4 model = glm::mat4(1.0f); // Единичная матрица
    model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); // Перемещение
    model = glm::rotate(model, glm::radians(45.0f), glm::vec3(0.0f, 1.0f, 0.0f)); // Вращение
    model = glm::scale(model, glm::vec3(1.0f, 1.0f, 1.0f)); // Масштаб
    GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
}
 
void Camera::SetPositionV3(glm::vec3 V3) {
    position = V3;
}
 
void Camera::SetTargetV3(glm::vec3 V3) {
    target = V3;
}
 
void Camera::SetUpV3(glm::vec3 V3) {
    up = V3;
}
 
void Camera::SetProjection(float fov, float aspect, float near, float far) {
    projection = glm::perspective(glm::radians(fov), aspect, near, far);
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
int main() {
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
 
    GLFWwindow* window = glfwCreateWindow(800, 600, "Cube Example", NULL, NULL);
    if (window == NULL) {
        std::cerr << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
 
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cerr << "Failed to initialize GLAD" << std::endl;
        return -1;
    }
    // Камера
    Camera cam(glm::vec3(0, 0, 10));
    
    // Создаем несколько кубов
    Cube cube1(0.5f);
    cube1.SetPosition(-0.5f, 0.0f, 0.0f);
    cube1.SetColor(1.0f, 0.0f, 0.0f);  // Красный
    cube1.SetAngle(45.0f);
 
    Cube cube2(0.3f);
    cube2.SetPosition(0.5f, 0.0f, 0.0f);
    cube2.SetColor(0.0f, 0.0f, 1.0f);  // Синий
    cube2.SetAngle(128.0f);
 
    Cube cube3(20.0f);
    cube3.SetPosition(0.0f, -20.0f, 0.0f);
 
    glEnable(GL_DEPTH_TEST);
 
    while (!glfwWindowShouldClose(window)) {
        processInput(window);
 
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
        // Обработка ввода
        processInput(window);
 
        cam.Draw();
 
        // Отрисовка кубов
        cube1.Draw();
        cube2.Draw();
 
        
 
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
 
    glfwTerminate();
    return 0;
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.04.2025, 18:40
Ответы с готовыми решениями:

GLFW
объясните пожалуйста как пользоваться ЭТИМ(я даже не знаю что это) или киньте ссылки где можно...

Подключение GLFW
Приветствую. прошу помочь подключить GLFW к своему проекту у меня visual c++ 2010 express edition

Проблемы с подключением GLFW
Уважаемые форумчане, я пытаюсь подключить библиотеку GLFW. Скачал библиотеку с сайта...

1
-19 / 11 / 2
Регистрация: 13.10.2021
Сообщений: 51
29.04.2025, 19:29
Лучший ответ Сообщение было отмечено Izobretatel_ как решение

Решение

1. Добавь управление камерой в processInput:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void processInput(GLFWwindow* window, Camera& cam) {
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
 
    float cameraSpeed = 0.05f;
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
        cam.SetPositionV3(cam.position + cameraSpeed * glm::normalize(cam.target - cam.position));
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
        cam.SetPositionV3(cam.position - cameraSpeed * glm::normalize(cam.target - cam.position));
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
        cam.SetPositionV3(cam.position - glm::normalize(glm::cross(cam.target - cam.position, cam.up)) * cameraSpeed;
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
        cam.SetPositionV3(cam.position + glm::normalize(glm::cross(cam.target - cam.position, cam.up)) * cameraSpeed);
}
2. Измени класс Camera(убери шейдеры оттуда):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Camera {
public:
    glm::vec3 position;
    glm::vec3 target;
    glm::vec3 up;
    glm::mat4 projection;
    
    Camera(glm::vec3 position);
    ~Camera();
    
    glm::mat4 GetViewMatrix() const;
    void SetPositionV3(glm::vec3 V3);
    void SetTargetV3(glm::vec3 V3);
    void SetUpV3(glm::vec3 V3);
    void SetProjection(float fov, float aspect, float near, float far);
};
 
// В Camera.cpp:
glm::mat4 Camera::GetViewMatrix() const {
    return glm::lookAt(position, target, up);
}
3. Используй камеру в основном цикле:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while (!glfwWindowShouldClose(window)) {
    processInput(window, cam);  // Передаём камеру
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    // Получаем матрицы из камеры
    glm::mat4 view = cam.GetViewMatrix();
    glm::mat4 projection = cam.projection;
    
    // Передаём матрицы в шейдеры кубов
    cube1.Draw(view, projection);
    cube2.Draw(view, projection);
    
    glfwSwapBuffers(window);
    glfwPollEvents();
}
4. Класс cube:
C++
1
2
3
4
5
6
7
8
9
10
11
12
class Cube {
public:
    void Draw(const glm::mat4& view, const glm::mat4& projection) {
        glUseProgram(shaderProgram);
        
        // Передаём матрицы
        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
        
        // ... остальная отрисовка
    }
};
Не уверен, что сработает, но я фиксил так
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.04.2025, 19:29
Помогаю со студенческими работами здесь

Какой тип проекта выбрать для написания программ с помощью GLFW, чтобы не было консоли
Я сижу в Microsoft Visual c++ 2010 express. Я выбрал &quot;пустой проект&quot; но помимо окна создаваемого с...

Обработка нажатий клавиш с glfw
Изучаю glfw. Задался вопросом обработки нажатий клавиш. Нашел функцию glfwGetKey(int key), где...

Не видит функций OpenGL, хотя GLFW подключен
Приветствую. Решил начать изучать OpenGL, возникла следующая проблема: линковщик ругается на...

VC++ 2015, GLEW, GLFW, ссылка на неразрешённый внешний символ
Ошибка LNK2019 ссылка на неразрешенный внешний символ _gluOrtho2D@32 в функции _main #include...

LNK1120: 2 unresolved externals | Glew | GLFW
Выходит ошибки при компелирование кода, надеюсь кто-нибудь подскажет, в чем может быть проблема....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Ниже машинный перевод статьи The Thinkpad X220 Tablet is the best budget school laptop period . Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы,. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru