Копия проекта с 02
This commit is contained in:
parent
da9a3ffde7
commit
19990e877b
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "some_name",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/../dependencies/GLFW/include",
|
||||
"${workspaceFolder}/../dependencies/glad/include",
|
||||
"${workspaceFolder}/../dependencies/glm"
|
||||
],
|
||||
"compilerPath": "C:/MinGW/bin/g++.exe",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++11",
|
||||
"intelliSenseMode": "gcc-x86"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"fstream": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"map": "cpp",
|
||||
"atomic": "cpp"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"tasks": [
|
||||
{
|
||||
"type": "cppbuild",
|
||||
"label": "C/C++: make сборка",
|
||||
"command": "make",
|
||||
"args": [
|
||||
"${input:target}"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"detail": "Задача создана отладчиком."
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"id": "target",
|
||||
"description": "Цель сборки (all, list, clean)",
|
||||
"default": "all",
|
||||
"type": "promptString"
|
||||
},
|
||||
],
|
||||
"version": "2.0.0"
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
# Компилятор и директория проекта
|
||||
ifeq ($(OS), Windows_NT)
|
||||
# С возможностью сборки x32
|
||||
ifeq ($(MAKECMDGOALS), x32)
|
||||
CC = C:/MinGW/bin/g++.exe
|
||||
else
|
||||
CC = C:/MinGW64/bin/g++.exe
|
||||
endif
|
||||
PROJECT_DIR = $(shell echo %cd%)
|
||||
PATH_SEPARATOR = \\
|
||||
# Имя исполняемого файла
|
||||
EXECUTABLE = $(notdir $(strip $(PROJECT_DIR))).exe
|
||||
else
|
||||
CC = g++
|
||||
PROJECT_DIR = $(shell pwd)
|
||||
PATH_SEPARATOR = /
|
||||
# Имя исполняемого файла
|
||||
EXECUTABLE = $(notdir $(strip $(PROJECT_DIR)))
|
||||
endif
|
||||
|
||||
# Опции компилятора
|
||||
CFLAGS += -c
|
||||
CFLAGS += -I./include
|
||||
CFLAGS += -I../dependencies/GLFW/include
|
||||
CFLAGS += -I../dependencies/glad/include
|
||||
CFLAGS += -I../dependencies/glm
|
||||
|
||||
# Опции линкера
|
||||
LDFLAGS += --std=c++11
|
||||
# Архитектурозависимые опции линкера
|
||||
ifeq ($(OS), Windows_NT)
|
||||
# GLFW в зависимости от архитектуры
|
||||
ifeq ($(MAKECMDGOALS), x32)
|
||||
LDFLAGS += -L../dependencies/GLFW/lib-mingw
|
||||
else
|
||||
LDFLAGS += -L../dependencies/GLFW/lib-mingw-w64
|
||||
endif
|
||||
|
||||
LDFLAGS += -static
|
||||
LDFLAGS += -lglfw3dll
|
||||
LDFLAGS += -lopengl32
|
||||
else
|
||||
LDFLAGS += -lglfw
|
||||
LDFLAGS += -lGL
|
||||
endif
|
||||
|
||||
# Библиотека GLAD
|
||||
GLAD := ../dependencies/glad/src/glad.c
|
||||
GLAD_O := $(GLAD:.c=.o)
|
||||
|
||||
# Файлы из директории src
|
||||
SOURCES_C = $(wildcard src/*.c)
|
||||
SOURCES_CPP = $(wildcard src/*.cpp)
|
||||
|
||||
# Директория с объектными файлами
|
||||
OBJ_DIR := Obj
|
||||
# Объектные файлы
|
||||
OBJECTS = $(addprefix $(OBJ_DIR)/,$(SOURCES_C:src/%.c=%.o) $(SOURCES_CPP:src/%.cpp=%.o))
|
||||
|
||||
# Для x32 сборки под Windows
|
||||
ifeq ($(OS), Windows_NT)
|
||||
ifeq ($(MAKECMDGOALS), x32)
|
||||
x32: all
|
||||
endif
|
||||
endif
|
||||
|
||||
# Цель по умолчанию, зависит от EXECUTABLE
|
||||
all: $(EXECUTABLE)
|
||||
|
||||
# Цель сборки исполняемого файла, зависит от OBJ_DIR, OBJECTS и GLAD_O
|
||||
$(EXECUTABLE): $(OBJ_DIR) $(OBJECTS) $(GLAD_O)
|
||||
$(CC) $(OBJECTS) $(GLAD_O) $(LDFLAGS) -o $@
|
||||
|
||||
# Цель для сборки GLAD
|
||||
$(GLAD_O): $(GLAD)
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
# Цель для создания директории с объектными файлами
|
||||
$(OBJ_DIR):
|
||||
@mkdir $(OBJ_DIR)
|
||||
|
||||
# Цель сборки объектных файлов
|
||||
$(OBJ_DIR)/%.o: src/%.c
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
$(OBJ_DIR)/%.o: src/%.cpp
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
# Цель вывода всех файлов, учавствтующих в сборке
|
||||
list:
|
||||
@echo "В сборке участвуют:" $(OBJECTS)
|
||||
|
||||
# Очистка
|
||||
ifeq ($(OS), Windows_NT)
|
||||
clean: $(OBJ_DIR)
|
||||
@rmdir /s /q $(OBJ_DIR)
|
||||
else
|
||||
clean: $(OBJ_DIR)
|
||||
@rm -f $(EXECUTABLE) $(OBJECTS)
|
||||
endif
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef BUFFERS_H
|
||||
#define BUFFERS_H
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
// Объект массива вершин
|
||||
class VAO
|
||||
{
|
||||
public:
|
||||
VAO(); // Создает VAO и активирует его
|
||||
~VAO(); // Уничтожает VAO
|
||||
VAO(const VAO & copy); // Конструктор копирования
|
||||
VAO& operator=(const VAO & other); // Оператор присваивания
|
||||
|
||||
void use(); // Активация VAO
|
||||
static void disable(); // Деактивация активного VAO
|
||||
|
||||
private:
|
||||
GLuint handler; // Дескриптор
|
||||
static std::map<GLuint, GLuint> handler_count; // Счетчик использований дескриптора
|
||||
};
|
||||
|
||||
// Тип буфера
|
||||
enum BUFFER_TYPE { VERTEX = GL_ARRAY_BUFFER
|
||||
, ELEMENT = GL_ELEMENT_ARRAY_BUFFER
|
||||
};
|
||||
|
||||
// Объект вершинного буфера
|
||||
class BO
|
||||
{
|
||||
public:
|
||||
BO(BUFFER_TYPE type); // Создает пустой буфер заданного типа
|
||||
BO(BUFFER_TYPE type, const void *data, int size); // Создает и загружает туда данные
|
||||
~BO(); // Уничтожает буфер
|
||||
BO(const BO & copy); // Конструктор копирования
|
||||
BO& operator=(const BO & other); // Оператор присваивания
|
||||
|
||||
void load(const void *data, int size, GLuint mode = GL_STATIC_DRAW); // Загрузка данных в буфер
|
||||
void use();
|
||||
|
||||
protected:
|
||||
GLuint handler; // Дескриптор
|
||||
BUFFER_TYPE type; // Тип буфера
|
||||
private:
|
||||
static std::map<GLuint, GLuint> handler_count; // Счетчик использований дескриптора
|
||||
};
|
||||
|
||||
#endif // BUFFERS_H
|
|
@ -0,0 +1,8 @@
|
|||
#version 330 core
|
||||
|
||||
out vec3 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = vec3(1, 0, 0);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#version 330 core
|
||||
|
||||
layout(location = 0) in vec3 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position.xyz = pos;
|
||||
gl_Position.w = 1.0;
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
#include "Buffers.h"
|
||||
|
||||
// Счетчики использований дескрипторов
|
||||
std::map<GLuint, GLuint> VAO::handler_count;
|
||||
std::map<GLuint, GLuint> BO::handler_count;
|
||||
|
||||
// Создает VAO и активирует его
|
||||
VAO::VAO()
|
||||
{
|
||||
glGenVertexArrays(1, &handler); // Генерация одного объекта массива вершин
|
||||
glBindVertexArray(handler); // Привязка для использования
|
||||
handler_count[handler] = 1; // Инициализация счетчика для дескриптора
|
||||
}
|
||||
|
||||
// Уничтожает VAO
|
||||
VAO::~VAO()
|
||||
{
|
||||
// Если дескриптор никем не используется - освободим его
|
||||
if (!--handler_count[handler])
|
||||
{
|
||||
glDeleteVertexArrays(1, &handler);
|
||||
handler_count.erase(handler); // Удаление из словаря
|
||||
}
|
||||
}
|
||||
|
||||
// Конструктор копирования
|
||||
VAO::VAO(const VAO & copy) : handler(copy.handler)
|
||||
{
|
||||
handler_count[handler]++;
|
||||
}
|
||||
|
||||
// Оператор присваивания
|
||||
VAO& VAO::operator=(const VAO & other)
|
||||
{
|
||||
// Если это разные дескрипторы
|
||||
if (handler != other.handler)
|
||||
{ // то следуюет удалить текущий перед заменой
|
||||
this->~VAO();
|
||||
handler = other.handler;
|
||||
handler_count[handler]++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Активация VAO
|
||||
void VAO::use()
|
||||
{
|
||||
glBindVertexArray(handler); // Привязка VAO для использования
|
||||
}
|
||||
|
||||
// Деактивация активного VAO
|
||||
void VAO::disable()
|
||||
{
|
||||
glBindVertexArray(0); // Отключение VAO
|
||||
}
|
||||
|
||||
// Создает пустой буфер заданного типа
|
||||
BO::BO(BUFFER_TYPE t) : type(t)
|
||||
{
|
||||
glGenBuffers(1, &handler); // Генерация одного объекта буфера
|
||||
handler_count[handler] = 1;
|
||||
use(); // Привязка буфера
|
||||
}
|
||||
|
||||
// Создает и загружает туда данные
|
||||
BO::BO(BUFFER_TYPE t, const void *data, int size) : BO(t)
|
||||
{
|
||||
load(data, size);
|
||||
}
|
||||
|
||||
// Уничтожает буфер
|
||||
BO::~BO()
|
||||
{
|
||||
if (handler) // Если буфер был создан
|
||||
{
|
||||
// Если дескриптор никем не используется - освободим его
|
||||
if (!--handler_count[handler])
|
||||
{
|
||||
glDeleteBuffers(1, &handler);
|
||||
handler_count.erase(handler); // Удаление из словаря
|
||||
}
|
||||
handler = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Конструктор копирования
|
||||
BO::BO(const BO & copy) : handler(copy.handler), type(copy.type)
|
||||
{
|
||||
handler_count[handler]++;
|
||||
}
|
||||
|
||||
// Оператор присваивания
|
||||
BO& BO::operator=(const BO & other)
|
||||
{
|
||||
// Если это разные дескрипторы
|
||||
if (handler != other.handler)
|
||||
{ // то следуюет удалить текущий перед заменой
|
||||
this->~BO();
|
||||
handler = other.handler;
|
||||
handler_count[handler]++;
|
||||
}
|
||||
// Изменим тип
|
||||
type = other.type;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Загрузка вершин в буфер
|
||||
void BO::load(const void *data, int size, GLuint mode)
|
||||
{
|
||||
use(); // Привязка буфера
|
||||
glBufferData(type, size, data, mode);
|
||||
}
|
||||
|
||||
void BO::use()
|
||||
{
|
||||
glBindBuffer(type, handler); // Привязка элементного буфера
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <GLM/glm.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Buffers.h"
|
||||
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
#define WINDOW_CAPTION "OPENGL notes on rekovalev.site"
|
||||
|
||||
// Функция-callback для изменения размеров буфера кадра в случае изменения размеров поверхности окна
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
// Функция чтения шейдера из файла
|
||||
std::string readFile(const char* filename)
|
||||
{
|
||||
std::string text;
|
||||
std::ifstream file(filename, std::ios::in); // Открываем файл на чтение
|
||||
// Если файл доступен и успешно открыт
|
||||
if (file.is_open())
|
||||
{
|
||||
std::stringstream sstr; // Буфер для чтения
|
||||
sstr << file.rdbuf(); // Считываем файл
|
||||
text = sstr.str(); // Преобразуем буфер к строке
|
||||
file.close(); // Закрываем файл
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
// Функция для загрузки шейдеров
|
||||
// Принимает два адреса вершинного и фрагментного шейдеров
|
||||
// Возвращает дескриптор шейдерной программы
|
||||
GLuint LoadShaders(const char *vertex_file, const char *fragment_file)
|
||||
{
|
||||
// Создание дескрипторов вершинного и фрагментного шейдеров
|
||||
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
// Переменные под результат компиляции
|
||||
GLint result = GL_FALSE;
|
||||
int infoLogLength;
|
||||
|
||||
// Считываем текст вершинного шейдера
|
||||
std::string code = readFile(vertex_file);
|
||||
const char* pointer = code.c_str(); // Преобразование к указателю на const char, так как функция принимает массив си-строк
|
||||
|
||||
// Компиляция кода вершинного шейдера
|
||||
glShaderSource(vertexShaderID, 1, &pointer, NULL);
|
||||
glCompileShader(vertexShaderID);
|
||||
|
||||
// Проверка результата компиляции
|
||||
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &result);
|
||||
glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
if (infoLogLength > 0)
|
||||
{
|
||||
char* errorMessage = new char[infoLogLength + 1];
|
||||
glGetShaderInfoLog(vertexShaderID, infoLogLength, NULL, errorMessage);
|
||||
std::cout << errorMessage;
|
||||
delete[] errorMessage;
|
||||
}
|
||||
|
||||
// Считываем текст вершинного шейдера
|
||||
code = readFile(fragment_file);
|
||||
pointer = code.c_str(); // Преобразование к указателю на const char, так как функция принимает массив си-строк
|
||||
|
||||
// Компиляция кода фрагментного шейдера
|
||||
glShaderSource(fragmentShaderID, 1, &pointer, NULL);
|
||||
glCompileShader(fragmentShaderID);
|
||||
|
||||
// Проверка результата компиляции
|
||||
glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &result);
|
||||
glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
if (infoLogLength > 0)
|
||||
{
|
||||
char* errorMessage = new char[infoLogLength + 1];
|
||||
glGetShaderInfoLog(fragmentShaderID, infoLogLength, NULL, errorMessage);
|
||||
std::cout << errorMessage;
|
||||
delete[] errorMessage;
|
||||
}
|
||||
|
||||
// Привязка скомпилированных шейдеров
|
||||
GLuint programID = glCreateProgram();
|
||||
glAttachShader(programID, vertexShaderID);
|
||||
glAttachShader(programID, fragmentShaderID);
|
||||
glLinkProgram(programID);
|
||||
|
||||
// Проверка программы
|
||||
glGetProgramiv(programID, GL_LINK_STATUS, &result);
|
||||
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
if (infoLogLength > 0)
|
||||
{
|
||||
char* errorMessage = new char[infoLogLength + 1];
|
||||
glGetProgramInfoLog(programID, infoLogLength, NULL, errorMessage);
|
||||
std::cout << errorMessage;
|
||||
delete[] errorMessage;
|
||||
}
|
||||
|
||||
// Освобождение дескрипторов шейдеров
|
||||
glDeleteShader(vertexShaderID);
|
||||
glDeleteShader(fragmentShaderID);
|
||||
|
||||
return programID;
|
||||
}
|
||||
|
||||
// Функция для конфигурации атрибутов
|
||||
void attrib_config()
|
||||
{
|
||||
// Определим спецификацию атрибута
|
||||
glVertexAttribPointer( 0 // индекс атрибута, должен совпадать с Layout шейдера
|
||||
, 3 // количество компонент одного элемента
|
||||
, GL_FLOAT // тип
|
||||
, GL_FALSE // необходимость нормировать значения
|
||||
, 0 // шаг
|
||||
, (void *)0 // отступ с начала массива
|
||||
);
|
||||
// Включаем необходимый атрибут у выбранного VAO
|
||||
glEnableVertexAttribArray(0);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
GLFWwindow* window; // Указатель на окно GLFW3
|
||||
|
||||
// Инициализация GLFW3
|
||||
if (!glfwInit())
|
||||
{
|
||||
std::cout << "GLFW init error\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Завершение работы с GLFW3 перед выходом
|
||||
atexit(glfwTerminate);
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); // Мажорная версия спецификаций OpenGL
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); // Минорная версия спецификаций OpenGL
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Контекст OpenGL, который поддерживает только основные функции
|
||||
|
||||
// Создание окна GLFW3 с заданными шириной, высотой и заголовком окна
|
||||
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_CAPTION, NULL, NULL);
|
||||
if (!window)
|
||||
{
|
||||
std::cout << "GLFW create window error\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Установка основного контекста окна
|
||||
glfwMakeContextCurrent(window);
|
||||
// Установка callback-функции для изменения размеров окна и буфера кадра
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
glfwSwapInterval(1); // Вертикальная синхронизация
|
||||
|
||||
// Загрузка функций OpenGL с помощью GLAD
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||
{
|
||||
std::cout << "GLAD load GL error\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Компиляция шейдеров
|
||||
GLuint shaderProgram = LoadShaders("shaders/shader.vert", "shaders/shader.frag");
|
||||
// Активация шейдера
|
||||
glUseProgram(shaderProgram);
|
||||
|
||||
// Вершины треугольника
|
||||
glm::vec3 verticies[] = { {-0.5f, -0.5f, 0.0f}
|
||||
, { 0.5f, -0.5f, 0.0f}
|
||||
, { 0.5f, 0.5f, 0.0f}
|
||||
, {-0.5f, 0.5f, 0.0f}
|
||||
};
|
||||
|
||||
// VAO
|
||||
VAO vao;
|
||||
// VBO вершинный
|
||||
BO vbo_vert(VERTEX);
|
||||
attrib_config(); // Конфигурация аттрибутов
|
||||
// Загрузка вершин в используемый буфер вершин
|
||||
vbo_vert.load(verticies, sizeof(verticies));
|
||||
|
||||
// индексы вершин
|
||||
GLuint indices[] = {0, 1, 2, 2, 3, 0};
|
||||
|
||||
// VBO элементный (индексы вершин)
|
||||
BO vbo_elem(ELEMENT);
|
||||
|
||||
// Загрузка индексов в используемый элементный буфер
|
||||
vbo_elem.load(indices, sizeof(indices));
|
||||
|
||||
// Установка цвета очистки буфера цвета
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
|
||||
// Пока не произойдет событие запроса закрытия окна
|
||||
while(!glfwWindowShouldClose(window))
|
||||
{
|
||||
// Очистка буфера цвета
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Тут производится рендер
|
||||
vao.use();
|
||||
glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(GLuint), GL_UNSIGNED_INT, (void*)0);
|
||||
vao.disable();
|
||||
|
||||
// Представление содержимого буфера цепочки показа на окно
|
||||
glfwSwapBuffers(window);
|
||||
// Обработка системных событий
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
// Удаление шейдерной программы
|
||||
glDeleteProgram(shaderProgram);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue