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:
21
.vscode/c_cpp_properties.json
vendored
Normal file
21
.vscode/c_cpp_properties.json
vendored
Normal 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
68
.vscode/settings.json
vendored
Normal 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
30
CMakeLists.txt
Normal 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
121
Ps1Engine/loader/mesh.cpp
Normal 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
9
Ps1Engine/loader/mesh.h
Normal 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);
|
||||||
310
Ps1Engine/renderer/renderer.cpp
Normal file
310
Ps1Engine/renderer/renderer.cpp
Normal 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;
|
||||||
|
}
|
||||||
69
Ps1Engine/renderer/renderer.h
Normal file
69
Ps1Engine/renderer/renderer.h
Normal 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
301
cube.cpp
Normal 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
@@ -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
Reference in New Issue
Block a user