Initial commit of Ps1Engine project with basic renderer and OBJ/MTL loading functionality. Added CMake configuration, GLFW integration, and basic cube rendering with textures. Included necessary header files and implemented core rendering logic.

This commit is contained in:
ExilProductions
2025-04-23 15:25:04 +02:00
parent 348e03dd39
commit 5ccf861eaa
13 changed files with 929 additions and 7227 deletions

21
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -0,0 +1,21 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/Ps1Engine/renderer",
"${workspaceFolder}/Ps1Engine/loader",
"${workspaceFolder}/Ps1Engine",
"${workspaceFolder}/external/**",
"/usr/include",
"/usr/local/include"
],
"defines": [],
"compilerPath": "/usr/bin/g++",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}

68
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,68 @@
{
"files.associations": {
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"cfenv": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"source_location": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"format": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"span": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stdfloat": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp",
"variant": "cpp"
}
}

30
CMakeLists.txt Normal file
View File

@@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 3.10)
# Project name
project(Ps1Engine)
# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Include directories
include_directories(${CMAKE_SOURCE_DIR}/renderer)
include_directories(${CMAKE_SOURCE_DIR}/loader)
include_directories(${CMAKE_SOURCE_DIR}/external/stb)
# Source files
set(SOURCES
${CMAKE_SOURCE_DIR}/renderer/renderer.cpp
${CMAKE_SOURCE_DIR}/loader/mesh.cpp
${CMAKE_SOURCE_DIR}/../cube.cpp
)
# Executable
add_executable(Ps1Engine ${SOURCES})
# Link libraries
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(glfw3 REQUIRED)
target_link_libraries(Ps1Engine OpenGL::GL GLEW::GLEW glfw)

121
Ps1Engine/loader/mesh.cpp Normal file
View File

@@ -0,0 +1,121 @@
#include "mesh.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <stdexcept>
#include <filesystem>
namespace fs = std::filesystem;
std::map<std::string, Color> load_mtl_colors(const std::string& mtl_path)
{
std::map<std::string, Color> material_colors;
std::ifstream file(mtl_path);
if (!file.is_open()) {
std::cerr << "Warning: could not open MTL file: " << mtl_path << std::endl;
return material_colors;
}
std::string line, current_mtl;
while (std::getline(file, line)) {
std::istringstream ss(line);
std::string keyword;
ss >> keyword;
if (keyword == "newmtl") {
ss >> current_mtl;
} else if (keyword == "Kd") {
float r, g, b;
ss >> r >> g >> b;
material_colors[current_mtl] = Color(
static_cast<uint8_t>(r * 255),
static_cast<uint8_t>(g * 255),
static_cast<uint8_t>(b * 255)
);
}
}
return material_colors;
}
std::vector<Triangle> load_obj(const std::string& obj_path)
{
std::ifstream file(obj_path);
if (!file.is_open()) {
throw std::runtime_error("Failed to open OBJ file: " + obj_path);
}
std::vector<Vec3> positions;
std::vector<Vec2> texcoords;
std::map<std::string, Color> materials;
std::vector<Triangle> triangles;
std::string current_material = "";
fs::path base_path = fs::path(obj_path).parent_path();
std::string line;
while (std::getline(file, line)) {
std::istringstream ss(line);
std::string keyword;
ss >> keyword;
if (keyword == "v") {
float x, y, z;
ss >> x >> y >> z;
positions.emplace_back((int)(x * 4096), (int)(y * 4096), (int)(z * 4096));
} else if (keyword == "vt") {
float u, v;
ss >> u >> v;
texcoords.emplace_back(u, 1.0f - v); // flip v
} else if (keyword == "f") {
std::vector<std::string> tokens;
std::string token;
while (ss >> token) tokens.push_back(token);
std::vector<int> v_idx, t_idx;
for (const auto& t : tokens) {
std::stringstream ts(t);
std::string part;
int vi = -1, ti = -1;
std::getline(ts, part, '/');
if (!part.empty()) vi = std::stoi(part) - 1;
if (std::getline(ts, part, '/') && !part.empty())
ti = std::stoi(part) - 1;
v_idx.push_back(vi);
t_idx.push_back(ti);
}
// Triangulate face
for (size_t i = 1; i + 1 < v_idx.size(); ++i) {
Triangle tri;
tri.v0 = positions[v_idx[0]];
tri.v1 = positions[v_idx[i]];
tri.v2 = positions[v_idx[i + 1]];
tri.uv0 = (t_idx[0] >= 0 && t_idx[0] < (int)texcoords.size()) ? texcoords[t_idx[0]] : Vec2(0, 0);
tri.uv1 = (t_idx[i] >= 0 && t_idx[i] < (int)texcoords.size()) ? texcoords[t_idx[i]] : Vec2(0, 0);
tri.uv2 = (t_idx[i + 1] >= 0 && t_idx[i + 1] < (int)texcoords.size()) ? texcoords[t_idx[i + 1]] : Vec2(0, 0);
if (materials.count(current_material)) {
tri.color = materials[current_material];
} else {
tri.color = Color(255, 255, 255); // fallback white
}
triangles.push_back(tri);
}
} else if (keyword == "mtllib") {
std::string mtl_file;
ss >> mtl_file;
fs::path mtl_path = base_path / mtl_file;
materials = load_mtl_colors(mtl_path.string());
} else if (keyword == "usemtl") {
ss >> current_material;
}
}
return triangles;
}

9
Ps1Engine/loader/mesh.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
#include <string>
#include <vector>
#include <map>
#include "renderer.h" // includes Vec3, Vec2, Triangle, Color
std::vector<Triangle> load_obj(const std::string& obj_path);
std::map<std::string, Color> load_mtl_colors(const std::string& mtl_path);

View File

@@ -0,0 +1,310 @@
#include "renderer.h"
#include <stdexcept>
#include <algorithm>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define FIXED_POINT_PRECISION 4096
#define FIXED_POINT_SHIFT 12
Vec3::Vec3(int x_, int y_, int z_) : x(x_), y(y_), z(z_) {}
Vec2::Vec2(float x_, float y_) : x(x_), y(y_) {}
Color::Color(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
Matrix4::Matrix4()
{
for (int i = 0; i < 16; i++)
m[i] = (i % 5 == 0) ? FIXED_POINT_PRECISION : 0;
}
Vec3 matrix_multiply(const Matrix4 &mat, const Vec3 &v)
{
int x = (mat.m[0] * v.x + mat.m[1] * v.y + mat.m[2] * v.z + mat.m[3] * FIXED_POINT_PRECISION) / FIXED_POINT_PRECISION;
int y = (mat.m[4] * v.x + mat.m[5] * v.y + mat.m[6] * v.z + mat.m[7] * FIXED_POINT_PRECISION) / FIXED_POINT_PRECISION;
int z = (mat.m[8] * v.x + mat.m[9] * v.y + mat.m[10] * v.z + mat.m[11] * FIXED_POINT_PRECISION) / FIXED_POINT_PRECISION;
return Vec3(x, y, z);
}
Matrix4 matrix_multiply(const Matrix4 &a, const Matrix4 &b)
{
Matrix4 result;
for (int row = 0; row < 4; ++row)
{
for (int col = 0; col < 4; ++col)
{
result.m[row * 4 + col] =
(a.m[row * 4 + 0] * b.m[col + 0]) +
(a.m[row * 4 + 1] * b.m[col + 4]) +
(a.m[row * 4 + 2] * b.m[col + 8]) +
(a.m[row * 4 + 3] * b.m[col + 12]);
result.m[row * 4 + col] /= 4096;
}
}
return result;
}
Color convert_color(const Color &color)
{
uint8_t r = (color.r >> 3) << 3;
uint8_t g = (color.g >> 3) << 3;
uint8_t b = (color.b >> 3) << 3;
return Color(r, g, b);
}
Renderer::Renderer(int width_, int height_, const std::string &title_)
: width(width_), height(height_), title(title_),
internal_width(320), internal_height(240)
{
if (!glfwInit())
{
throw std::runtime_error("Failed to initialize GLFW");
}
window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);
if (!window)
{
glfwTerminate();
throw std::runtime_error("Failed to create GLFW window");
}
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
{
throw std::runtime_error("Failed to initialize GLEW");
}
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, 0, height, -32768, 32767);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_TEXTURE_2D);
}
Renderer::~Renderer()
{
glfwDestroyWindow(window);
glfwTerminate();
}
void Renderer::set_view_matrix(const Matrix4 &view)
{
view_matrix = view;
}
void Renderer::begin_frame()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void Renderer::render(const std::vector<Triangle> &triangles, GLuint texture)
{
std::vector<Triangle> transformed_triangles;
for (const auto &tri : triangles)
{
Triangle t;
t.v0 = matrix_multiply(view_matrix, tri.v0);
t.v1 = matrix_multiply(view_matrix, tri.v1);
t.v2 = matrix_multiply(view_matrix, tri.v2);
t.uv0 = tri.uv0;
t.uv1 = tri.uv1;
t.uv2 = tri.uv2;
t.color = tri.color;
Vec3 edge1(t.v1.x - t.v0.x, t.v1.y - t.v0.y, t.v1.z - t.v0.z);
Vec3 edge2(t.v2.x - t.v0.x, t.v2.y - t.v0.y, t.v2.z - t.v0.z);
Vec3 normal(
edge1.y * edge2.z - edge1.z * edge2.y,
edge1.z * edge2.x - edge1.x * edge2.z,
edge1.x * edge2.y - edge1.y * edge2.x);
if (normal.z > 0)
{
transformed_triangles.push_back(t);
}
}
std::sort(transformed_triangles.begin(), transformed_triangles.end(),
[](const Triangle &a, const Triangle &b)
{
int z_a = (a.v0.z + a.v1.z + a.v2.z) / 3;
int z_b = (b.v0.z + b.v1.z + b.v2.z) / 3;
return z_a > z_b;
});
std::vector<Triangle> screen_triangles;
for (const auto &tri : transformed_triangles)
{
Triangle screen_tri;
float scale_x = (float)width / internal_width;
float scale_y = (float)height / internal_height;
screen_tri.v0 = Vec3(
((tri.v0.x * internal_width / 32) / FIXED_POINT_PRECISION) * scale_x + width / 2,
((tri.v0.y * internal_height / 32) / FIXED_POINT_PRECISION) * scale_y + height / 2,
tri.v0.z);
screen_tri.v1 = Vec3(
((tri.v1.x * internal_width / 32) / FIXED_POINT_PRECISION) * scale_x + width / 2,
((tri.v1.y * internal_height / 32) / FIXED_POINT_PRECISION) * scale_y + height / 2,
tri.v1.z);
screen_tri.v2 = Vec3(
((tri.v2.x * internal_width / 32) / FIXED_POINT_PRECISION) * scale_x + width / 2,
((tri.v2.y * internal_height / 32) / FIXED_POINT_PRECISION) * scale_y + height / 2,
tri.v2.z);
int snap_factor = 4;
screen_tri.v0.x = (screen_tri.v0.x / snap_factor) * snap_factor;
screen_tri.v0.y = (screen_tri.v0.y / snap_factor) * snap_factor;
screen_tri.v1.x = (screen_tri.v1.x / snap_factor) * snap_factor;
screen_tri.v1.y = (screen_tri.v1.y / snap_factor) * snap_factor;
screen_tri.v2.x = (screen_tri.v2.x / snap_factor) * snap_factor;
screen_tri.v2.y = (screen_tri.v2.y / snap_factor) * snap_factor;
if (rand() % 10 == 0)
{
screen_tri.v0.x += (rand() % 3) - 1;
screen_tri.v0.y += (rand() % 3) - 1;
}
screen_tri.uv0 = tri.uv0;
screen_tri.uv1 = tri.uv1;
screen_tri.uv2 = tri.uv2;
screen_tri.color = convert_color(tri.color);
screen_triangles.push_back(screen_tri);
}
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glDisable(GL_BLEND);
for (const auto &tri : screen_triangles)
{
glBegin(GL_TRIANGLES);
Color c = tri.color;
glColor3ub(c.r, c.g, c.b);
glTexCoord2f(tri.uv0.x, tri.uv0.y);
glVertex3f(static_cast<float>(tri.v0.x), static_cast<float>(tri.v0.y), static_cast<float>(tri.v0.z) / 32767.0f);
glTexCoord2f(tri.uv1.x, tri.uv1.y);
glVertex3f(static_cast<float>(tri.v1.x), static_cast<float>(tri.v1.y), static_cast<float>(tri.v1.z) / 32767.0f);
glTexCoord2f(tri.uv2.x, tri.uv2.y);
glVertex3f(static_cast<float>(tri.v2.x), static_cast<float>(tri.v2.y), static_cast<float>(tri.v2.z) / 32767.0f);
glEnd();
if (rand() % 5 == 0)
{
glDisable(GL_TEXTURE_2D);
glColor3f(0.0f, 0.0f, 0.0f);
glBegin(GL_LINE_LOOP);
glVertex3f(static_cast<float>(tri.v0.x), static_cast<float>(tri.v0.y), static_cast<float>(tri.v0.z) / 32767.0f);
glVertex3f(static_cast<float>(tri.v1.x), static_cast<float>(tri.v1.y), static_cast<float>(tri.v1.z) / 32767.0f);
glVertex3f(static_cast<float>(tri.v2.x), static_cast<float>(tri.v2.y), static_cast<float>(tri.v2.z) / 32767.0f);
glEnd();
glEnable(GL_TEXTURE_2D);
}
}
}
void Renderer::end_frame()
{
glfwSwapBuffers(window);
glfwPollEvents();
}
bool Renderer::should_close()
{
return glfwWindowShouldClose(window);
}
GLuint Renderer::load_texture(const std::string &filepath)
{
int width, height, channels;
unsigned char *image = stbi_load(filepath.c_str(), &width, &height, &channels, 3);
if (!image)
{
throw std::runtime_error("Failed to load texture: " + filepath);
}
int new_width = std::min(width, 256);
int new_height = std::min(height, 256);
if (new_width > 128)
new_width = 256;
else if (new_width > 64)
new_width = 128;
else if (new_width > 32)
new_width = 64;
else if (new_width > 16)
new_width = 32;
else
new_width = 16;
if (new_height > 128)
new_height = 256;
else if (new_height > 64)
new_height = 128;
else if (new_height > 32)
new_height = 64;
else if (new_height > 16)
new_height = 32;
else
new_height = 16;
unsigned char *resized = new unsigned char[new_width * new_height * 3];
for (int y = 0; y < new_height; y++)
{
for (int x = 0; x < new_width; x++)
{
int src_x = x * width / new_width;
int src_y = y * height / new_height;
int src_idx = (src_y * width + src_x) * 3;
int dst_idx = (y * new_width + x) * 3;
resized[dst_idx] = (image[src_idx] >> 3) << 3;
resized[dst_idx + 1] = (image[src_idx + 1] >> 3) << 3;
resized[dst_idx + 2] = (image[src_idx + 2] >> 3) << 3;
}
}
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, new_width, new_height, 0, GL_RGB, GL_UNSIGNED_BYTE, resized);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
stbi_image_free(image);
delete[] resized;
return texture;
}

View File

@@ -0,0 +1,69 @@
#ifndef RENDERER_H
#define RENDERER_H
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <vector>
#include <string>
#include <cstdint>
struct Vec3
{
int x, y, z;
Vec3(int x_ = 0, int y_ = 0, int z_ = 0);
};
struct Vec2
{
float x, y;
Vec2(float x_ = 0.0f, float y_ = 0.0f);
};
struct Color
{
uint8_t r, g, b;
Color(uint8_t r_ = 255, uint8_t g_ = 255, uint8_t b_ = 255);
};
struct Matrix4
{
int m[16];
Matrix4();
};
struct Triangle
{
Vec3 v0, v1, v2;
Vec2 uv0, uv1, uv2;
Color color;
};
Vec3 matrix_multiply(const Matrix4 &mat, const Vec3 &v);
Matrix4 matrix_multiply(const Matrix4 &a, const Matrix4 &b);
Color convert_color(const Color &color);
class Renderer
{
private:
GLFWwindow *window;
Matrix4 view_matrix;
int width;
int height;
int internal_width;
int internal_height;
std::string title;
public:
Renderer(int width_, int height_, const std::string &title_);
~Renderer();
void set_view_matrix(const Matrix4 &view);
void begin_frame();
void render(const std::vector<Triangle> &triangles, GLuint texture);
void end_frame();
bool should_close();
GLuint load_texture(const std::string &filepath);
};
#endif

301
cube.cpp Normal file
View File

@@ -0,0 +1,301 @@
#include "renderer.h"
#include <iostream>
#include <vector>
#include <cmath>
#include <chrono>
std::vector<Triangle> create_cube(int size = 4096)
{
std::vector<Triangle> triangles;
Vec3 v0(-size, -size, -size);
Vec3 v1(size, -size, -size);
Vec3 v2(size, size, -size);
Vec3 v3(-size, size, -size);
Vec3 v4(-size, -size, size);
Vec3 v5(size, -size, size);
Vec3 v6(size, size, size);
Vec3 v7(-size, size, size);
Vec2 t0(0.0f, 0.0f);
Vec2 t1(1.0f, 0.0f);
Vec2 t2(1.0f, 1.0f);
Vec2 t3(0.0f, 1.0f);
Triangle tri1;
tri1.v0 = v4;
tri1.v1 = v5;
tri1.v2 = v6;
tri1.uv0 = t0;
tri1.uv1 = t1;
tri1.uv2 = t2;
tri1.color = Color(255, 0, 0);
triangles.push_back(tri1);
Triangle tri2;
tri2.v0 = v4;
tri2.v1 = v6;
tri2.v2 = v7;
tri2.uv0 = t0;
tri2.uv1 = t2;
tri2.uv2 = t3;
tri2.color = Color(255, 0, 0);
triangles.push_back(tri2);
Triangle tri3;
tri3.v0 = v1;
tri3.v1 = v0;
tri3.v2 = v3;
tri3.uv0 = t0;
tri3.uv1 = t1;
tri3.uv2 = t2;
tri3.color = Color(0, 255, 0);
triangles.push_back(tri3);
Triangle tri4;
tri4.v0 = v1;
tri4.v1 = v3;
tri4.v2 = v2;
tri4.uv0 = t0;
tri4.uv1 = t2;
tri4.uv2 = t3;
tri4.color = Color(0, 255, 0);
triangles.push_back(tri4);
Triangle tri5;
tri5.v0 = v3;
tri5.v1 = v7;
tri5.v2 = v6;
tri5.uv0 = t0;
tri5.uv1 = t1;
tri5.uv2 = t2;
tri5.color = Color(0, 0, 255);
triangles.push_back(tri5);
Triangle tri6;
tri6.v0 = v3;
tri6.v1 = v6;
tri6.v2 = v2;
tri6.uv0 = t0;
tri6.uv1 = t2;
tri6.uv2 = t3;
tri6.color = Color(0, 0, 255);
triangles.push_back(tri6);
Triangle tri7;
tri7.v0 = v0;
tri7.v1 = v1;
tri7.v2 = v5;
tri7.uv0 = t0;
tri7.uv1 = t1;
tri7.uv2 = t2;
tri7.color = Color(255, 255, 0);
triangles.push_back(tri7);
Triangle tri8;
tri8.v0 = v0;
tri8.v1 = v5;
tri8.v2 = v4;
tri8.uv0 = t0;
tri8.uv1 = t2;
tri8.uv2 = t3;
tri8.color = Color(255, 255, 0);
triangles.push_back(tri8);
Triangle tri9;
tri9.v0 = v1;
tri9.v1 = v2;
tri9.v2 = v6;
tri9.uv0 = t0;
tri9.uv1 = t1;
tri9.uv2 = t2;
tri9.color = Color(255, 0, 255);
triangles.push_back(tri9);
Triangle tri10;
tri10.v0 = v1;
tri10.v1 = v6;
tri10.v2 = v5;
tri10.uv0 = t0;
tri10.uv1 = t2;
tri10.uv2 = t3;
tri10.color = Color(255, 0, 255);
triangles.push_back(tri10);
Triangle tri11;
tri11.v0 = v0;
tri11.v1 = v4;
tri11.v2 = v7;
tri11.uv0 = t0;
tri11.uv1 = t1;
tri11.uv2 = t2;
tri11.color = Color(0, 255, 255);
triangles.push_back(tri11);
Triangle tri12;
tri12.v0 = v0;
tri12.v1 = v7;
tri12.v2 = v3;
tri12.uv0 = t0;
tri12.uv1 = t2;
tri12.uv2 = t3;
tri12.color = Color(0, 255, 255);
triangles.push_back(tri12);
return triangles;
}
Matrix4 create_rotation_y(float angle)
{
Matrix4 mat;
int cos_val = static_cast<int>(std::cos(angle) * 4096);
int sin_val = static_cast<int>(std::sin(angle) * 4096);
mat.m[0] = cos_val;
mat.m[2] = -sin_val;
mat.m[8] = sin_val;
mat.m[10] = cos_val;
return mat;
}
Matrix4 create_rotation_x(float angle)
{
Matrix4 mat;
int cos_val = static_cast<int>(std::cos(angle) * 4096);
int sin_val = static_cast<int>(std::sin(angle) * 4096);
mat.m[5] = cos_val;
mat.m[6] = -sin_val;
mat.m[9] = sin_val;
mat.m[10] = cos_val;
return mat;
}
Matrix4 create_rotation_z(float angle)
{
Matrix4 mat;
int cos_val = static_cast<int>(std::cos(angle) * 4096);
int sin_val = static_cast<int>(std::sin(angle) * 4096);
mat.m[0] = cos_val;
mat.m[1] = -sin_val;
mat.m[4] = sin_val;
mat.m[5] = cos_val;
return mat;
}
Matrix4 create_translation(int x, int y, int z)
{
Matrix4 mat;
mat.m[3] = x;
mat.m[7] = y;
mat.m[11] = z;
return mat;
}
Matrix4 create_view_matrix(float camera_distance)
{
Matrix4 view;
view.m[11] = -camera_distance * 4096;
return view;
}
GLuint create_checkerboard_texture(int width, int height)
{
unsigned char *data = new unsigned char[width * height * 3];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int idx = (y * width + x) * 3;
bool is_white = ((x / 16) + (y / 16)) % 2 == 0;
unsigned char color = is_white ? 255 : 64;
data[idx] = color;
data[idx + 1] = color;
data[idx + 2] = color;
}
}
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
delete[] data;
return texture;
}
int main()
{
try
{
Renderer renderer(800, 600, "Cube");
std::vector<Triangle> cube = create_cube(4096 * 4);
GLuint texture = create_checkerboard_texture(128, 128);
float rotation = 0.0f;
float camera_distance = 0.7f;
auto last_time = std::chrono::high_resolution_clock::now();
while (!renderer.should_close())
{
auto current_time = std::chrono::high_resolution_clock::now();
float delta_time = std::chrono::duration<float>(current_time - last_time).count();
last_time = current_time;
rotation += delta_time * 2.0f;
Matrix4 view = create_view_matrix(camera_distance);
Matrix4 rot_x = create_rotation_x(rotation * 0.7f);
Matrix4 rot_y = create_rotation_y(rotation);
Matrix4 rot_z = create_rotation_z(rotation * 1.3f);
Matrix4 rotation_matrix = matrix_multiply(rot_z, matrix_multiply(rot_y, rot_x));
renderer.set_view_matrix(view);
renderer.begin_frame();
std::vector<Triangle> transformed_cube;
for (const auto &tri : cube)
{
Triangle t;
t.v0 = matrix_multiply(rotation_matrix, tri.v0);
t.v1 = matrix_multiply(rotation_matrix, tri.v1);
t.v2 = matrix_multiply(rotation_matrix, tri.v2);
t.uv0 = tri.uv0;
t.uv1 = tri.uv1;
t.uv2 = tri.uv2;
t.color = tri.color;
transformed_cube.push_back(t);
}
renderer.render(transformed_cube, texture);
renderer.end_frame();
}
}
catch (const std::exception &e)
{
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}

Submodule libs/glew deleted from 3da315c23a

Submodule libs/glfw deleted from e7ea71be03

File diff suppressed because it is too large Load Diff

View File

@@ -1,663 +0,0 @@
/*************************************************************************
* GLFW 3.5 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
* Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
*************************************************************************/
#ifndef _glfw3_native_h_
#define _glfw3_native_h_
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
* Doxygen documentation
*************************************************************************/
/*! @file glfw3native.h
* @brief The header of the native access functions.
*
* This is the header file of the native access functions. See @ref native for
* more information.
*/
/*! @defgroup native Native access
* @brief Functions related to accessing native handles.
*
* **By using the native access functions you assert that you know what you're
* doing and how to fix problems caused by using them. If you don't, you
* shouldn't be using them.**
*
* Before the inclusion of @ref glfw3native.h, you may define zero or more
* window system API macro and zero or more context creation API macros.
*
* The chosen backends must match those the library was compiled for. Failure
* to do this will cause a link-time error.
*
* The available window API macros are:
* * `GLFW_EXPOSE_NATIVE_WIN32`
* * `GLFW_EXPOSE_NATIVE_COCOA`
* * `GLFW_EXPOSE_NATIVE_X11`
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
*
* The available context API macros are:
* * `GLFW_EXPOSE_NATIVE_WGL`
* * `GLFW_EXPOSE_NATIVE_NSGL`
* * `GLFW_EXPOSE_NATIVE_GLX`
* * `GLFW_EXPOSE_NATIVE_EGL`
* * `GLFW_EXPOSE_NATIVE_OSMESA`
*
* These macros select which of the native access functions that are declared
* and which platform-specific headers to include. It is then up your (by
* definition platform-specific) code to handle which of these should be
* defined.
*
* If you do not want the platform-specific headers to be included, define
* `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header.
*
* @code
* #define GLFW_EXPOSE_NATIVE_WIN32
* #define GLFW_EXPOSE_NATIVE_WGL
* #define GLFW_NATIVE_INCLUDE_NONE
* #include <GLFW/glfw3native.h>
* @endcode
*/
/*************************************************************************
* System headers and types
*************************************************************************/
#if !defined(GLFW_NATIVE_INCLUDE_NONE)
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
/* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
* example to allow applications to correctly declare a GL_KHR_debug callback)
* but windows.h assumes no one will define APIENTRY before it does
*/
#if defined(GLFW_APIENTRY_DEFINED)
#undef APIENTRY
#undef GLFW_APIENTRY_DEFINED
#endif
#include <windows.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
#include <ApplicationServices/ApplicationServices.h>
#include <objc/objc.h>
#endif
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/* NSGL is declared by Cocoa.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, glx.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/glx.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, osmesa.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/osmesa.h>
#endif
#endif /*GLFW_NATIVE_INCLUDE_NONE*/
/*************************************************************************
* Functions
*************************************************************************/
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
/*! @brief Returns the adapter device name of the specified monitor.
*
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
/*! @brief Returns the display device name of the specified monitor.
*
* @return The UTF-8 encoded display device name (for example
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
/*! @brief Returns the `HWND` of the specified window.
*
* @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/*! @brief Returns the `HGLRC` of the specified window.
*
* @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
*
* @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
/*! @brief Returns the `NSWindow` of the specified window.
*
* @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
/*! @brief Returns the `NSView` of the specified window.
*
* @return The `NSView` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.4.
*
* @ingroup native
*/
GLFWAPI id glfwGetCocoaView(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/*! @brief Returns the `NSOpenGLContext` of the specified window.
*
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11)
/*! @brief Returns the `Display` used by GLFW.
*
* @return The `Display` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI Display* glfwGetX11Display(void);
/*! @brief Returns the `RRCrtc` of the specified monitor.
*
* @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
/*! @brief Returns the `RROutput` of the specified monitor.
*
* @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
/*! @brief Returns the `Window` of the specified window.
*
* @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
/*! @brief Sets the current primary selection to the specified string.
*
* @param[in] string A UTF-8 encoded string.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The specified string is copied before this function
* returns.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa glfwGetX11SelectionString
* @sa glfwSetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI void glfwSetX11SelectionString(const char* string);
/*! @brief Returns the contents of the current primary selection as a string.
*
* If the selection is empty or if its contents cannot be converted, `NULL`
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
*
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
* if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the next call to @ref
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
* library is terminated.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa glfwSetX11SelectionString
* @sa glfwGetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetX11SelectionString(void);
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/*! @brief Returns the `GLXContext` of the specified window.
*
* @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
/*! @brief Returns the `GLXWindow` of the specified window.
*
* @return The `GLXWindow` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
/*! @brief Returns the `struct wl_display*` used by GLFW.
*
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
/*! @brief Returns the `struct wl_output*` of the specified monitor.
*
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
/*! @brief Returns the main `struct wl_surface*` of the specified window.
*
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
* an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
/*! @brief Returns the `EGLDisplay` used by GLFW.
*
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark Because EGL is initialized on demand, this function will return
* `EGL_NO_DISPLAY` until the first context has been created via EGL.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
/*! @brief Returns the `EGLContext` of the specified window.
*
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
/*! @brief Returns the `EGLSurface` of the specified window.
*
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/*! @brief Retrieves the color buffer associated with the specified window.
*
* @param[in] window The window whose color buffer to retrieve.
* @param[out] width Where to store the width of the color buffer, or `NULL`.
* @param[out] height Where to store the height of the color buffer, or `NULL`.
* @param[out] format Where to store the OSMesa pixel format of the color
* buffer, or `NULL`.
* @param[out] buffer Where to store the address of the color buffer, or
* `NULL`.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
/*! @brief Retrieves the depth buffer associated with the specified window.
*
* @param[in] window The window whose depth buffer to retrieve.
* @param[out] width Where to store the width of the depth buffer, or `NULL`.
* @param[out] height Where to store the height of the depth buffer, or `NULL`.
* @param[out] bytesPerValue Where to store the number of bytes per depth
* buffer element, or `NULL`.
* @param[out] buffer Where to store the address of the depth buffer, or
* `NULL`.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
/*! @brief Returns the `OSMesaContext` of the specified window.
*
* @return The `OSMesaContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _glfw3_native_h_ */

Submodule libs/include/glfw deleted from e7ea71be03