everything
This commit is contained in:
parent
79fa59c3aa
commit
8998bc3936
19 changed files with 855 additions and 7504 deletions
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
||||
|
|
@ -5,48 +5,80 @@ set(CMAKE_CXX_STANDARD 20)
|
|||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(glfw3 3.3 QUIET)
|
||||
|
||||
if(NOT glfw3_FOUND)
|
||||
message(STATUS "glfw3 not found via find_package")
|
||||
if(WIN32)
|
||||
set(GLFW_LIB "${CMAKE_CURRENT_SOURCE_DIR}/vendor/glfw/libglfw3.a")
|
||||
else()
|
||||
message(FATAL_ERROR "GLFW not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_executable(Engine2026
|
||||
# ------------------------------------------------------------------------------
|
||||
# 1. Source and Header Files
|
||||
# ------------------------------------------------------------------------------
|
||||
set(SOURCES
|
||||
main.cpp
|
||||
vendor/glad/glad.c
|
||||
vendor/stb/stb_image.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
engine/shader.h
|
||||
engine/texture.h
|
||||
engine/mesh.h
|
||||
vendor/glad/glad.c
|
||||
engine/camera.h
|
||||
game/game.cpp
|
||||
game/game.h
|
||||
)
|
||||
|
||||
target_include_directories(Engine2026 PRIVATE
|
||||
# Create the executable
|
||||
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# 2. Include Directories
|
||||
# ------------------------------------------------------------------------------
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vendor
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vendor/assimp/include
|
||||
)
|
||||
|
||||
if(glfw3_FOUND)
|
||||
target_link_libraries(Engine2026 PRIVATE glfw OpenGL::GL)
|
||||
else()
|
||||
target_link_libraries(Engine2026 PRIVATE
|
||||
${GLFW_LIB}
|
||||
opengl32
|
||||
gdi32
|
||||
user32
|
||||
)
|
||||
endif()
|
||||
# ------------------------------------------------------------------------------
|
||||
# 3. Dependencies & Linking
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Copy assets to build dir
|
||||
add_custom_command(
|
||||
TARGET Engine2026 POST_BUILD
|
||||
# -- OpenGL --
|
||||
find_package(OpenGL REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE OpenGL::GL)
|
||||
|
||||
# -- GLFW (Built from source) --
|
||||
# Turn off extra GLFW targets to speed up your compile times
|
||||
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
|
||||
# Add the GLFW source directory.
|
||||
# NOTE: This automatically handles all underlying OS dependencies (gdi32, X11, Cocoa, etc.)
|
||||
add_subdirectory(vendor/glfw)
|
||||
|
||||
# Link the GLFW target
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE glfw)
|
||||
|
||||
# -- Assimp (Built from source) --
|
||||
# Turn off extra Assimp targets to speed up compile times
|
||||
set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||
set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE BOOL "" FORCE)
|
||||
|
||||
# Add the Assimp source directory
|
||||
add_subdirectory(vendor/assimp)
|
||||
# Link the GLFW and Assimp targets
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE glfw assimp)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# 4. Asset Synchronization (Runs Every Single Compile)
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
add_custom_target(refresh_assets
|
||||
# Step 1: Wipe the assets folder using a static configuration path
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -rf "${CMAKE_CURRENT_BINARY_DIR}/assets"
|
||||
# Step 2: Copy them fresh
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/assets
|
||||
$<TARGET_FILE_DIR:Engine2026>/assets
|
||||
COMMENT "Copying assets to output directory"
|
||||
)
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/assets"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/assets"
|
||||
COMMENT "Force-syncing assets to build directory..."
|
||||
)
|
||||
|
||||
# This now safely runs BEFORE the executable compiles, without the dependency loop
|
||||
add_dependencies(${PROJECT_NAME} refresh_assets)
|
||||
|
|
@ -1,56 +1,204 @@
|
|||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
|
||||
struct Material {
|
||||
sampler2D diffuse;
|
||||
sampler2D specular;
|
||||
float shininess;
|
||||
};
|
||||
|
||||
struct DirectionalLight {
|
||||
vec3 direction;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
struct PointLight {
|
||||
bool disabled;
|
||||
|
||||
vec3 position;
|
||||
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
struct SpotLight {
|
||||
bool disabled;
|
||||
|
||||
vec3 position;
|
||||
vec3 direction;
|
||||
float cutOff;
|
||||
float outerCutOff;
|
||||
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
|
||||
struct Decal {
|
||||
sampler2D tex;
|
||||
float opacity;
|
||||
vec4 uvCoords;
|
||||
};
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
in vec2 TexCoord;
|
||||
in vec2 TexCoords;
|
||||
|
||||
uniform sampler2D ourTexture;
|
||||
uniform sampler2D decal;
|
||||
#define MAX_POINT_LIGHTS 4
|
||||
#define MAX_SPOT_LIGHTS 4
|
||||
#define MAX_DECALS 4
|
||||
|
||||
// Texture & Decals
|
||||
uniform Material material;
|
||||
uniform sampler2D mainTexture;
|
||||
uniform Decal decals[MAX_DECALS];
|
||||
uniform int numberOfDecals;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 lightColor;
|
||||
uniform vec3 viewPos;
|
||||
|
||||
vec4 calcTextures(){
|
||||
vec4 tex1 = texture(ourTexture, TexCoord);
|
||||
vec4 tex2 = texture(decal, TexCoord);
|
||||
vec4 textures = mix(tex1, tex2, 0.2f);
|
||||
// Lights
|
||||
uniform DirectionalLight dirLight;
|
||||
|
||||
return textures;
|
||||
}
|
||||
uniform PointLight pointLights[MAX_POINT_LIGHTS];
|
||||
uniform int numberOfPointLights;
|
||||
|
||||
vec4 calcDirectLight(norm, viewDir){
|
||||
// Ambient Lighting
|
||||
float ambientStrength = 0.1;
|
||||
vec3 ambient = ambientStrength * lightColor;
|
||||
uniform SpotLight spotLights[MAX_SPOT_LIGHTS];
|
||||
uniform int numberOfSpotLights;
|
||||
|
||||
// Diffuse Lighting
|
||||
vec3 lightDir = normalize(lightPos - FragPos);
|
||||
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = diff * lightColor;
|
||||
|
||||
// Specular Lighting
|
||||
float specularStrength = 0.5;
|
||||
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
|
||||
vec3 specular = specularStrength * spec * lightColor;
|
||||
|
||||
vec4 result = vec4(ambient.rgb + diffuse.rgb + specular.rgb, 1.0f);
|
||||
|
||||
return result;
|
||||
}
|
||||
// func declarations
|
||||
vec3 calcTextures();
|
||||
vec4 calcDirectLight(DirectionalLight light, vec3 normal, vec3 viewDir, vec3 albedo);
|
||||
vec4 calcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 albedo);
|
||||
vec4 calcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 albedo);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 result = vec4(0.0f);
|
||||
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
|
||||
vec4 result = calcTextures();
|
||||
result += calcDirectLight(norm, viewDir);
|
||||
vec3 albedo = calcTextures();
|
||||
albedo = vec3(1,1,1);
|
||||
|
||||
//result += calcDirectLight(dirLight, norm, viewDir, albedo);
|
||||
|
||||
for(int i = 0; i < numberOfPointLights; i++){
|
||||
if (pointLights[i].disabled) continue;
|
||||
result += calcPointLight(pointLights[i], norm, FragPos, viewDir, albedo);
|
||||
}
|
||||
|
||||
for(int i = 0; i < numberOfSpotLights; i++){
|
||||
if (spotLights[i].disabled) continue;
|
||||
result += calcSpotLight(spotLights[i], norm, FragPos, viewDir, albedo);
|
||||
}
|
||||
|
||||
FragColor = result;
|
||||
}
|
||||
|
||||
|
||||
vec3 calcTextures(){
|
||||
vec4 textureAsVec = texture(mainTexture, TexCoords);
|
||||
|
||||
vec4 decalMix;
|
||||
for(int i = 0; i < numberOfDecals; i++){
|
||||
// We invert the 2nd one to make uv scaling easier
|
||||
vec2 decalCoords = TexCoords * (1.0 / decals[i].uvCoords.xy) + decals[i].uvCoords.zw;;
|
||||
|
||||
vec4 decal = texture(decals[i].tex, decalCoords);
|
||||
|
||||
decalMix += mix(decalMix, decal, 0.2f);
|
||||
}
|
||||
|
||||
vec4 finalMix = mix(textureAsVec, decalMix, 0.2f);
|
||||
|
||||
return vec3(finalMix);
|
||||
}
|
||||
|
||||
// calculates the color when using a directional light.
|
||||
vec4 calcDirectLight(DirectionalLight light, vec3 norm, vec3 viewDir, vec3 albedo)
|
||||
{
|
||||
vec3 lightDir = normalize(-light.direction);
|
||||
|
||||
// diffuse shading
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
|
||||
// specular shading
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
|
||||
// combine results
|
||||
vec3 ambient = light.ambient * albedo;
|
||||
vec3 diffuse = light.diffuse * diff * albedo;
|
||||
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
|
||||
|
||||
return vec4(ambient + diffuse + specular, 1.0f);
|
||||
}
|
||||
|
||||
vec4 calcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 albedo)
|
||||
{
|
||||
vec3 lightDir = normalize(light.position - fragPos);
|
||||
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
|
||||
// specular shading
|
||||
vec3 reflectDir = reflect(-lightDir, normal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
|
||||
// attenuation
|
||||
float distance = length(light.position - fragPos);
|
||||
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
|
||||
|
||||
// combine results
|
||||
vec3 ambient = light.ambient * albedo;
|
||||
vec3 diffuse = light.diffuse * diff * albedo;
|
||||
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
|
||||
ambient *= attenuation;
|
||||
diffuse *= attenuation;
|
||||
specular *= attenuation;
|
||||
|
||||
return vec4(ambient + diffuse + specular, 1.0f);
|
||||
}
|
||||
|
||||
vec4 calcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 albedo)
|
||||
{
|
||||
vec3 lightDir = normalize(light.position - fragPos);
|
||||
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
|
||||
// specular shading
|
||||
vec3 reflectDir = reflect(-lightDir, normal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
|
||||
// attenuation
|
||||
float distance = length(light.position - fragPos);
|
||||
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
|
||||
|
||||
// spotlight intensity
|
||||
float theta = dot(lightDir, normalize(-light.direction));
|
||||
float epsilon = light.cutOff - light.outerCutOff;
|
||||
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
|
||||
|
||||
// combine results
|
||||
vec3 ambient = light.ambient * albedo;
|
||||
vec3 diffuse = light.diffuse * diff * albedo;
|
||||
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
|
||||
ambient *= attenuation * intensity;
|
||||
diffuse *= attenuation * intensity;
|
||||
specular *= attenuation * intensity;
|
||||
|
||||
return vec4(ambient + diffuse + specular, 1.0f);
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ layout (location = 2) in vec2 aTexCoord;
|
|||
|
||||
out vec3 FragPos;
|
||||
out vec3 Normal;
|
||||
out vec2 TexCoord;
|
||||
out vec2 TexCoords;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
|
|
@ -13,9 +13,9 @@ uniform mat4 projection;
|
|||
|
||||
void main()
|
||||
{
|
||||
FragPos = vec3(model * vec4(aPos, 1.0));
|
||||
FragPos = vec3(model * vec4(aPos, 1.0f));
|
||||
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||
TexCoord = aTexCoord;
|
||||
TexCoords = aTexCoord;
|
||||
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0f);
|
||||
}
|
||||
}
|
||||
4
engine/blend_importer/export_embedded_fbx.py
Normal file
4
engine/blend_importer/export_embedded_fbx.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import bpy
|
||||
import sys
|
||||
|
||||
bpy.ops.export_scene.fbx(filepath=sys.argv[-1], path_mode='COPY', embed_textures=True)
|
||||
|
|
@ -11,13 +11,14 @@ enum Camera_Movement {
|
|||
FORWARD,
|
||||
BACKWARD,
|
||||
LEFT,
|
||||
RIGHT
|
||||
RIGHT,
|
||||
SPRINT
|
||||
};
|
||||
|
||||
// Default camera values
|
||||
const float YAW = -90.0f;
|
||||
const float PITCH = 0.0f;
|
||||
const float SPEED = 2.5f;
|
||||
const float SPEED = 5.5f;
|
||||
const float SENSITIVITY = 0.1f;
|
||||
const float ZOOM = 45.0f;
|
||||
|
||||
|
|
@ -27,6 +28,7 @@ public:
|
|||
glm::vec3 position, front, up, right, worldUp;
|
||||
float yaw, pitch;
|
||||
float movementSpeed, mouseSensitivity, zoom;
|
||||
bool sprinting = false;
|
||||
|
||||
// constructor with vectors
|
||||
Camera(glm::vec3 newPosition = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float newYaw = YAW, float newPitch = PITCH) : front(glm::vec3(0.0f, 0.0f, -1.0f)), movementSpeed(SPEED), mouseSensitivity(SENSITIVITY), zoom(ZOOM)
|
||||
|
|
@ -57,6 +59,9 @@ public:
|
|||
void processKeyboard(Camera_Movement direction, float deltaTime)
|
||||
{
|
||||
float velocity = movementSpeed * deltaTime;
|
||||
if (sprinting)
|
||||
velocity *= 8;
|
||||
|
||||
if (direction == FORWARD)
|
||||
position += front * velocity;
|
||||
if (direction == BACKWARD)
|
||||
|
|
@ -65,6 +70,8 @@ public:
|
|||
position -= right * velocity;
|
||||
if (direction == RIGHT)
|
||||
position += right * velocity;
|
||||
if (direction == SPRINT)
|
||||
sprinting = !sprinting;
|
||||
}
|
||||
|
||||
// processes input received from a mouse input system. Expects the offset value in both the x and y direction.
|
||||
|
|
@ -100,6 +107,14 @@ public:
|
|||
zoom = 45.0f;
|
||||
}
|
||||
|
||||
void Update(Shader shader, int screenWidth, int screenHeight)
|
||||
{
|
||||
glm::mat4 projection = glm::perspective(glm::radians(zoom), (float)screenWidth / (float)screenHeight, 0.1f, 100.0f);
|
||||
|
||||
shader.setMat4("projection", projection);
|
||||
shader.setMat4("view", GetViewMatrix());
|
||||
shader.setVec3("viewPos", position);
|
||||
}
|
||||
|
||||
private:
|
||||
// calculates the front vector from the Camera's (updated) Euler Angles
|
||||
|
|
|
|||
178
engine/mesh.h
178
engine/mesh.h
|
|
@ -1,63 +1,147 @@
|
|||
|
||||
#include <exception>
|
||||
#ifndef ENGINE2026_MESH_H
|
||||
#define ENGINE2026_MESH_H
|
||||
|
||||
#include <glad/glad.h> // holds all OpenGL type declarations
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <engine/shader.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <glad/glad.h>
|
||||
using namespace std;
|
||||
|
||||
#define MAX_BONE_INFLUENCE 4
|
||||
|
||||
struct Vertex {
|
||||
float x, y, z; // position
|
||||
float nX, nY, zY; // normal
|
||||
float u, v; // texcoord
|
||||
// position
|
||||
glm::vec3 Position;
|
||||
// normal
|
||||
glm::vec3 Normal;
|
||||
// texCoords
|
||||
glm::vec2 TexCoords;
|
||||
// tangent
|
||||
glm::vec3 Tangent;
|
||||
// bitangent
|
||||
glm::vec3 Bitangent;
|
||||
//bone indexes which will influence this vertex
|
||||
int m_BoneIDs[MAX_BONE_INFLUENCE];
|
||||
//weights from each bone
|
||||
float m_Weights[MAX_BONE_INFLUENCE];
|
||||
};
|
||||
|
||||
class Mesh
|
||||
{
|
||||
struct Texture {
|
||||
unsigned int id;
|
||||
string type;
|
||||
string path;
|
||||
};
|
||||
|
||||
class Mesh {
|
||||
public:
|
||||
unsigned int VBO, VAO, EBO;
|
||||
std::size_t indexCount = 0;
|
||||
// mesh Data
|
||||
vector<Vertex> vertices;
|
||||
vector<unsigned int> indices;
|
||||
vector<Texture> textures;
|
||||
unsigned int VAO;
|
||||
|
||||
Mesh(const std::vector<Vertex>& vertices, const std::vector<unsigned int>& indices) : indexCount(indices.size())
|
||||
{
|
||||
if (vertices.empty() || indices.empty()) {
|
||||
throw std::runtime_error("Mesh created with empty vertices or indices");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
// constructor
|
||||
Mesh(vector<Vertex> vertices, vector<unsigned int> indices, vector<Texture> textures)
|
||||
{
|
||||
this->vertices = vertices;
|
||||
this->indices = indices;
|
||||
this->textures = textures;
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
// now that we have all the required data, set the vertex buffers and its attribute pointers.
|
||||
setupMesh();
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW);
|
||||
// render the mesh
|
||||
void Draw(Shader &shader)
|
||||
{
|
||||
// bind appropriate textures
|
||||
unsigned int diffuseNr = 1;
|
||||
unsigned int specularNr = 1;
|
||||
unsigned int normalNr = 1;
|
||||
unsigned int heightNr = 1;
|
||||
for(unsigned int i = 0; i < textures.size(); i++)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding
|
||||
// retrieve texture number (the N in diffuse_textureN)
|
||||
string number;
|
||||
string name = textures[i].type;
|
||||
if(name == "texture_diffuse")
|
||||
number = std::to_string(diffuseNr++);
|
||||
else if(name == "texture_specular")
|
||||
number = std::to_string(specularNr++); // transfer unsigned int to string
|
||||
else if(name == "texture_normal")
|
||||
number = std::to_string(normalNr++); // transfer unsigned int to string
|
||||
else if(name == "texture_height")
|
||||
number = std::to_string(heightNr++); // transfer unsigned int to string
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
|
||||
// now set the sampler to the correct texture unit
|
||||
glUniform1i(glGetUniformLocation(shader.ID, (name + number).c_str()), i);
|
||||
// and finally bind the texture
|
||||
glBindTexture(GL_TEXTURE_2D, textures[i].id);
|
||||
}
|
||||
|
||||
// Position
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x));
|
||||
glEnableVertexAttribArray(0);
|
||||
// draw mesh
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<unsigned int>(indices.size()), GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
// Normals
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, nX));
|
||||
glEnableVertexAttribArray(1);
|
||||
// always good practice to set everything back to defaults once configured.
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
// Texcoords
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, u));
|
||||
glEnableVertexAttribArray(2);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "Failed to load mesh" << std::endl;
|
||||
}
|
||||
}
|
||||
private:
|
||||
// render data
|
||||
unsigned int VBO, EBO;
|
||||
|
||||
void Draw() const
|
||||
{
|
||||
//glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indexCount),
|
||||
GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
// initializes all the buffer objects/arrays
|
||||
void setupMesh()
|
||||
{
|
||||
// create buffers/arrays
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
// load data into vertex buffers
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
// A great thing about structs is that their memory layout is sequential for all its items.
|
||||
// The effect is that we can simply pass a pointer to the struct and it translates perfectly to a glm::vec3/2 array which
|
||||
// again translates to 3/2 floats which translates to a byte array.
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
||||
|
||||
// set the vertex attribute pointers
|
||||
// vertex Positions
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
|
||||
// vertex normals
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
|
||||
// vertex texture coords
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));
|
||||
// vertex tangent
|
||||
glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Tangent));
|
||||
// vertex bitangent
|
||||
glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Bitangent));
|
||||
// ids
|
||||
glEnableVertexAttribArray(5);
|
||||
glVertexAttribIPointer(5, 4, GL_INT, sizeof(Vertex), (void*)offsetof(Vertex, m_BoneIDs));
|
||||
|
||||
// weights
|
||||
glEnableVertexAttribArray(6);
|
||||
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, m_Weights));
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
};
|
||||
#endif //ENGINE2026_MESH_H
|
||||
|
|
|
|||
260
engine/model.h
Normal file
260
engine/model.h
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
|
||||
#ifndef ENGINE2026_MODEL_H
|
||||
#define ENGINE2026_MODEL_H
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <stb/stb_image.h>
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#include <engine/mesh.h>
|
||||
#include <engine/shader.h>
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
using namespace std;
|
||||
|
||||
unsigned int TextureFromFile(const char *path, const string &directory, bool gamma = false);
|
||||
|
||||
class Model
|
||||
{
|
||||
public:
|
||||
// model data
|
||||
vector<Texture> textures_loaded; // stores all the textures loaded so far, optimization to make sure textures aren't loaded more than once.
|
||||
vector<Mesh> meshes;
|
||||
string directory;
|
||||
bool gammaCorrection;
|
||||
|
||||
// constructor, expects a filepath to a 3D model.
|
||||
Model(string const &path, bool gamma = false) : gammaCorrection(gamma)
|
||||
{
|
||||
loadModel(path);
|
||||
}
|
||||
|
||||
// draws the model, and thus all its meshes
|
||||
void Draw(Shader &shader)
|
||||
{
|
||||
for(unsigned int i = 0; i < meshes.size(); i++)
|
||||
meshes[i].Draw(shader);
|
||||
}
|
||||
|
||||
private:
|
||||
// loads a model with supported ASSIMP extensions from file and stores the resulting meshes in the meshes vector.
|
||||
void loadModel(string const &path)
|
||||
{
|
||||
// read file via ASSIMP
|
||||
Assimp::Importer importer;
|
||||
const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_CalcTangentSpace);
|
||||
// check for errors
|
||||
if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) // if is Not Zero
|
||||
{
|
||||
cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << endl;
|
||||
return;
|
||||
}
|
||||
// retrieve the directory path of the filepath
|
||||
directory = path.substr(0, path.find_last_of('/'));
|
||||
|
||||
// process ASSIMP's root node recursively
|
||||
processNode(scene->mRootNode, scene);
|
||||
}
|
||||
|
||||
// processes a node in a recursive fashion. Processes each individual mesh located at the node and repeats this process on its children nodes (if any).
|
||||
void processNode(aiNode *node, const aiScene *scene)
|
||||
{
|
||||
// process each mesh located at the current node
|
||||
for(unsigned int i = 0; i < node->mNumMeshes; i++)
|
||||
{
|
||||
// the node object only contains indices to index the actual objects in the scene.
|
||||
// the scene contains all the data, node is just to keep stuff organized (like relations between nodes).
|
||||
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
|
||||
meshes.push_back(processMesh(mesh, scene));
|
||||
}
|
||||
// after we've processed all of the meshes (if any) we then recursively process each of the children nodes
|
||||
for(unsigned int i = 0; i < node->mNumChildren; i++)
|
||||
{
|
||||
processNode(node->mChildren[i], scene);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Mesh processMesh(aiMesh *mesh, const aiScene *scene)
|
||||
{
|
||||
// data to fill
|
||||
vector<Vertex> vertices;
|
||||
vector<unsigned int> indices;
|
||||
vector<Texture> textures;
|
||||
|
||||
// walk through each of the mesh's vertices
|
||||
for(unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
Vertex vertex;
|
||||
glm::vec3 vector; // we declare a placeholder vector since assimp uses its own vector class that doesn't directly convert to glm's vec3 class so we transfer the data to this placeholder glm::vec3 first.
|
||||
// positions
|
||||
vector.x = mesh->mVertices[i].x;
|
||||
vector.y = mesh->mVertices[i].y;
|
||||
vector.z = mesh->mVertices[i].z;
|
||||
vertex.Position = vector;
|
||||
// normals
|
||||
if (mesh->HasNormals())
|
||||
{
|
||||
vector.x = mesh->mNormals[i].x;
|
||||
vector.y = mesh->mNormals[i].y;
|
||||
vector.z = mesh->mNormals[i].z;
|
||||
vertex.Normal = vector;
|
||||
}
|
||||
// texture coordinates
|
||||
if(mesh->mTextureCoords[0]) // does the mesh contain texture coordinates?
|
||||
{
|
||||
glm::vec2 vec;
|
||||
// a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't
|
||||
// use models where a vertex can have multiple texture coordinates so we always take the first set (0).
|
||||
vec.x = mesh->mTextureCoords[0][i].x;
|
||||
vec.y = mesh->mTextureCoords[0][i].y;
|
||||
vertex.TexCoords = vec;
|
||||
// tangent
|
||||
vector.x = mesh->mTangents[i].x;
|
||||
vector.y = mesh->mTangents[i].y;
|
||||
vector.z = mesh->mTangents[i].z;
|
||||
vertex.Tangent = vector;
|
||||
// bitangent
|
||||
vector.x = mesh->mBitangents[i].x;
|
||||
vector.y = mesh->mBitangents[i].y;
|
||||
vector.z = mesh->mBitangents[i].z;
|
||||
vertex.Bitangent = vector;
|
||||
}
|
||||
else
|
||||
vertex.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
// now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.
|
||||
for(unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||
{
|
||||
aiFace face = mesh->mFaces[i];
|
||||
// retrieve all indices of the face and store them in the indices vector
|
||||
for(unsigned int j = 0; j < face.mNumIndices; j++)
|
||||
indices.push_back(face.mIndices[j]);
|
||||
}
|
||||
// process materials
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
// we assume a convention for sampler names in the shaders. Each diffuse texture should be named
|
||||
// as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER.
|
||||
// Same applies to other texture as the following list summarizes:
|
||||
// diffuse: texture_diffuseN
|
||||
// specular: texture_specularN
|
||||
// normal: texture_normalN
|
||||
|
||||
// 1. diffuse maps
|
||||
vector<Texture> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse", true);
|
||||
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
|
||||
// 2. specular maps
|
||||
vector<Texture> specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular");
|
||||
textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
|
||||
// 3. normal maps
|
||||
std::vector<Texture> normalMaps = loadMaterialTextures(material, aiTextureType_HEIGHT, "texture_normal");
|
||||
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
|
||||
// 4. height maps
|
||||
std::vector<Texture> heightMaps = loadMaterialTextures(material, aiTextureType_AMBIENT, "texture_height");
|
||||
textures.insert(textures.end(), heightMaps.begin(), heightMaps.end());
|
||||
|
||||
// return a mesh object created from the extracted mesh data
|
||||
return Mesh(vertices, indices, textures);
|
||||
}
|
||||
|
||||
// checks all material textures of a given type and loads the textures if they're not loaded yet.
|
||||
// the required info is returned as a Texture struct.
|
||||
vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, string typeName, bool fallback = false)
|
||||
{
|
||||
vector<Texture> textures;
|
||||
for(unsigned int i = 0; i < mat->GetTextureCount(type); i++)
|
||||
{
|
||||
aiString str;
|
||||
mat->GetTexture(type, i, &str);
|
||||
// check if texture was loaded before and if so, continue to next iteration: skip loading a new texture
|
||||
bool skip = false;
|
||||
for(unsigned int j = 0; j < textures_loaded.size(); j++)
|
||||
{
|
||||
if(std::strcmp(textures_loaded[j].path.data(), str.C_Str()) == 0)
|
||||
{
|
||||
textures.push_back(textures_loaded[j]);
|
||||
skip = true; // a texture with the same filepath has already been loaded, continue to next one. (optimization)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!skip)
|
||||
{ // if texture hasn't been loaded already, load it
|
||||
Texture texture;
|
||||
texture.id = TextureFromFile(str.C_Str(), this->directory);
|
||||
texture.type = typeName;
|
||||
texture.path = str.C_Str();
|
||||
textures.push_back(texture);
|
||||
textures_loaded.push_back(texture); // store it as texture loaded for entire model, to ensure we won't unnecessary load duplicate textures.
|
||||
}
|
||||
}
|
||||
|
||||
// Load DefaultTexture if there isn't one already
|
||||
if (mat->GetTextureCount(type) == 0) {
|
||||
string defaultPath = "DefaultTexture.jpg";
|
||||
|
||||
Texture texture;
|
||||
texture.id = TextureFromFile(defaultPath.c_str(), "assets/");
|
||||
texture.type = typeName;
|
||||
texture.path = defaultPath;
|
||||
textures.push_back(texture);
|
||||
textures_loaded.push_back(texture);
|
||||
}
|
||||
|
||||
return textures;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
unsigned int TextureFromFile(const char *path, const string &directory, bool gamma)
|
||||
{
|
||||
string filename = string(path);
|
||||
filename = directory + '/' + filename;
|
||||
|
||||
unsigned int textureID;
|
||||
glGenTextures(1, &textureID);
|
||||
|
||||
int width, height, nrComponents;
|
||||
unsigned char *data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0);
|
||||
if (data)
|
||||
{
|
||||
GLenum format;
|
||||
if (nrComponents == 1)
|
||||
format = GL_RED;
|
||||
else if (nrComponents == 3)
|
||||
format = GL_RGB;
|
||||
else if (nrComponents == 4)
|
||||
format = GL_RGBA;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
stbi_image_free(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Texture failed to load at path: " << path << std::endl;
|
||||
stbi_image_free(data);
|
||||
}
|
||||
|
||||
return textureID;
|
||||
}
|
||||
#endif //ENGINE2026_MODEL_H
|
||||
|
|
@ -42,8 +42,8 @@ public:
|
|||
fragmentCode = fragmentStream.str();
|
||||
|
||||
// Fix encoding issues, specifically for Linux
|
||||
vertexCode.erase(std::remove(vertexCode.begin(), vertexCode.end(), '\r'), vertexCode.end());
|
||||
fragmentCode.erase(std::remove(fragmentCode.begin(), fragmentCode.end(), '\r'), fragmentCode.end());
|
||||
//vertexCode.erase(std::remove(vertexCode.begin(), vertexCode.end(), '\r'), vertexCode.end());
|
||||
//fragmentCode.erase(std::remove(fragmentCode.begin(), fragmentCode.end(), '\r'), fragmentCode.end());
|
||||
}
|
||||
catch (std::ifstream::failure& e)
|
||||
{
|
||||
|
|
@ -112,6 +112,11 @@ public:
|
|||
void setVec3(const std::string &name, float x, float y, float z) const
|
||||
{
|
||||
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void setArr(const std::string &name, const GLint value[], const int &count) const
|
||||
{
|
||||
glUniform1iv(glGetUniformLocation(ID, name.c_str()), count, value);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void setVec4(const std::string &name, const glm::vec4 &value) const
|
||||
|
|
@ -137,7 +142,21 @@ public:
|
|||
{
|
||||
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
|
||||
|
||||
void setDecal(int index, GLint tex, float opacity, const glm::vec4& uvCoords) const {
|
||||
std::string indexStr = std::to_string(index);
|
||||
|
||||
GLint texLoc = glGetUniformLocation(ID, ("decals[" + indexStr + "].tex").c_str());
|
||||
if (texLoc != -1) glUniform1i(texLoc, tex);
|
||||
|
||||
GLint opLoc = glGetUniformLocation(ID, ("decals[" + indexStr + "].opacity").c_str());
|
||||
if (opLoc != -1) glUniform1f(opLoc, opacity);
|
||||
|
||||
GLint uvLoc = glGetUniformLocation(ID, ("decals[" + indexStr + "].uvCoords").c_str());
|
||||
if (uvLoc != -1) {
|
||||
glUniform4fv(uvLoc, 1, &uvCoords[0]);
|
||||
}
|
||||
}
|
||||
private:
|
||||
void checkCompileErrors(unsigned int shader, std::string type)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include <glad/glad.h>
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
unsigned int ID;
|
||||
int width, height, nrChannels;
|
||||
|
||||
Texture(const char* texturePath, bool flip = false)
|
||||
{
|
||||
// Create the Texture and set our ID
|
||||
glGenTextures(1, &ID);
|
||||
glBindTexture(GL_TEXTURE_2D, ID);
|
||||
|
||||
// set the texture wrapping/filtering options (on the currently bound texture object)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
// Grab the texture from our path
|
||||
if (flip)
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
|
||||
unsigned char *data = stbi_load(texturePath, &width, &height, &nrChannels, 0);
|
||||
if (data)
|
||||
{
|
||||
GLenum format = (nrChannels == 4) ? GL_RGBA : GL_RGB;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Failed to load texture" << std::endl;
|
||||
}
|
||||
|
||||
if (flip)
|
||||
stbi_set_flip_vertically_on_load(false);
|
||||
|
||||
stbi_image_free(data);
|
||||
}
|
||||
|
||||
void Draw() const
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, ID);
|
||||
}
|
||||
};
|
||||
3
game/game.cpp
Normal file
3
game/game.cpp
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
//
|
||||
// Created by claire on 28/06/2026.
|
||||
//
|
||||
9
game/game.h
Normal file
9
game/game.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
namespace Game {
|
||||
void Init();
|
||||
|
||||
void Update();
|
||||
void Render();
|
||||
void PreRender();
|
||||
void PostRender();
|
||||
}
|
||||
268
main.cpp
268
main.cpp
|
|
@ -3,15 +3,13 @@
|
|||
#include <iostream>
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glfw/include/GLFW/glfw3.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include "stb/stb_easy_font.h"
|
||||
|
||||
#include <engine/mesh.h>
|
||||
#include <engine/shader.h>
|
||||
#include <engine/texture.h>
|
||||
#include <engine/model.h>
|
||||
#include <engine/camera.h>
|
||||
|
||||
void window_resize_callback(GLFWwindow* window, int width, int height);
|
||||
|
|
@ -19,11 +17,12 @@ void mouse_callback(GLFWwindow* window, double xpos, double ypos);
|
|||
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
void processInput(GLFWwindow *window);
|
||||
|
||||
const int SCREEN_WIDTH = 1920;
|
||||
const int SCREEN_HEIGHT = 1080;
|
||||
int SCREEN_WIDTH = 1920;
|
||||
int SCREEN_HEIGHT = 1080;
|
||||
|
||||
static bool drawWireframe = false;
|
||||
static bool wireframeHeld = false;
|
||||
static bool flashlight = true;
|
||||
|
||||
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
|
||||
float lastX = SCREEN_WIDTH / 2.0f;
|
||||
|
|
@ -65,6 +64,8 @@ int main(int argc, char* argv[])
|
|||
glfwSetCursorPosCallback(window, mouse_callback);
|
||||
glfwSetScrollCallback(window, scroll_callback);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// Hide & Lock Cursor
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
|
||||
|
|
@ -73,145 +74,167 @@ int main(int argc, char* argv[])
|
|||
Testing
|
||||
*/
|
||||
|
||||
// Load Shader
|
||||
std::vector<Vertex> vertices = {
|
||||
// Front face (-z) – normal: (0, 0, -1)
|
||||
{ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f },
|
||||
{ 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
|
||||
{ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f },
|
||||
{ 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f },
|
||||
{ -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
|
||||
{ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f },
|
||||
|
||||
// Back face (+z) – normal: (0, 0, +1)
|
||||
{ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f },
|
||||
{ 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f },
|
||||
{ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f },
|
||||
{ 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f },
|
||||
{ -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
|
||||
{ -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f },
|
||||
|
||||
// Left face (-x) – normal: (-1, 0, 0)
|
||||
{ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f },
|
||||
{ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f },
|
||||
{ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f },
|
||||
{ -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
|
||||
// Right face (+x) – normal: (+1, 0, 0)
|
||||
{ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f },
|
||||
{ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f },
|
||||
{ 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f },
|
||||
{ 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
|
||||
// Bottom face (-y) – normal: (0, -1, 0)
|
||||
{ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f },
|
||||
{ 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f },
|
||||
{ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f },
|
||||
|
||||
// Top face (+y) – normal: (0, +1, 0)
|
||||
{ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
|
||||
{ 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
|
||||
{ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }
|
||||
};
|
||||
std::vector<unsigned int> indices = {
|
||||
0, 1, 2, 2, 4, 0,
|
||||
6, 7, 8, 8, 10, 6,
|
||||
12, 13, 14, 14, 16, 12,
|
||||
18, 19, 20, 20, 22, 18,
|
||||
24, 25, 26, 26, 28, 24,
|
||||
30, 31, 32, 32, 34, 30
|
||||
};
|
||||
|
||||
Mesh testMesh(vertices, indices);
|
||||
|
||||
Texture texture1("assets/wall.jpg");
|
||||
Texture texture2("assets/awesomeface.png", true);
|
||||
|
||||
Shader shaderTest("assets/shaders/basicVertex.vert", "assets/shaders/basicFragment.frag");
|
||||
shaderTest.Use(); // don't forget to activate/use the shader before setting uniforms!
|
||||
shaderTest.setInt("ourTexture", 0);
|
||||
shaderTest.setInt("decal", 1);
|
||||
|
||||
Shader lightingShader("assets/shaders/basicVertex.vert", "assets/shaders/lightFragment.frag");
|
||||
Mesh lightMesh(vertices, indices);
|
||||
Model ourModel("assets/models/sponza/Sponza.gltf");
|
||||
|
||||
shaderTest.Use();
|
||||
shaderTest.setInt("ourTexture", 0);
|
||||
shaderTest.setInt("material.diffuse", 0);
|
||||
shaderTest.setInt("material.specular", 1);
|
||||
|
||||
// Set decals - TODO: Shift this to mesh.h with helpers
|
||||
shaderTest.setDecal(0, 2, 1, glm::vec4(0.5, 0.5, 0, 0));
|
||||
shaderTest.setDecal(1, 2, 1, glm::vec4(0.5, 0.5, -0.75, -0.75));
|
||||
shaderTest.setInt("numberOfDecals", 2);
|
||||
|
||||
shaderTest.setInt("numberOfPointLights", 1);
|
||||
shaderTest.setInt("numberOfSpotLights", 1);
|
||||
|
||||
glm::vec3 pointLightPositions[] = {
|
||||
glm::vec3( 0.7f, 0.2f, 2.0f),
|
||||
glm::vec3( 2.3f, -3.3f, -4.0f),
|
||||
glm::vec3(-4.0f, 2.0f, -12.0f),
|
||||
glm::vec3( 0.0f, 0.0f, -3.0f)
|
||||
};
|
||||
|
||||
// Render Loop
|
||||
float lastUpdate = 0;
|
||||
glm::vec3 lightPos = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
glm::vec3 orbitCenter = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
// per-frame time logic
|
||||
// --------------------
|
||||
float currentFrame = static_cast<float>(glfwGetTime());
|
||||
deltaTime = currentFrame - lastFrame;
|
||||
lastFrame = currentFrame;
|
||||
|
||||
// crappy fps printout
|
||||
if (currentFrame - lastUpdate >= 1.0) {
|
||||
std::cout << 1.0f / deltaTime << std::endl;
|
||||
// std::cout << 1.0f / deltaTime << std::endl;
|
||||
lastUpdate += 1.0f;
|
||||
}
|
||||
|
||||
// Input processing
|
||||
processInput(window);
|
||||
|
||||
// Rendering
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture1.ID);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, texture2.ID);
|
||||
|
||||
shaderTest.Use();
|
||||
shaderTest.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setVec3("lightPos", orbitCenter);
|
||||
shaderTest.setVec3("viewPos", camera.position);
|
||||
|
||||
// pass projection matrix to shader (note that in this case it could change every frame)
|
||||
glm::mat4 projection = glm::perspective(glm::radians(camera.zoom), (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.1f, 100.0f);
|
||||
shaderTest.setMat4("projection", projection);
|
||||
camera.Update(shaderTest, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
|
||||
// camera/view transformation
|
||||
glm::mat4 view = camera.GetViewMatrix();
|
||||
shaderTest.setMat4("view", view);
|
||||
shaderTest.setFloat("material.shininess", 32.0f);
|
||||
|
||||
shaderTest.setVec3("dirLight.direction", -0.2f, -1.0f, -0.3f);
|
||||
shaderTest.setVec3("dirLight.ambient", 0.05f, 0.05f, 0.05f);
|
||||
shaderTest.setVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f);
|
||||
shaderTest.setVec3("dirLight.specular", 0.8f, 0.8f, 0.8f);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Ground Floor - Right Corridor (Warm Light)
|
||||
// Placed halfway down the right hallway behind the arches
|
||||
// -----------------------------------------------------------------------------
|
||||
shaderTest.setVec3("pointLights[0].position", -1.88f, 8.45f, -0.98f);
|
||||
shaderTest.setVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f);
|
||||
shaderTest.setVec3("pointLights[0].diffuse", 1.0f, 0.7f, 0.4f);
|
||||
shaderTest.setVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setFloat("pointLights[0].constant", 1.0f);
|
||||
shaderTest.setFloat("pointLights[0].linear", 0.09f);
|
||||
shaderTest.setFloat("pointLights[0].quadratic", 0.032f);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Ground Floor - Right Corridor, opposite end (Warm Light)
|
||||
// -----------------------------------------------------------------------------
|
||||
shaderTest.setVec3("pointLights[1].position", -15.0f, 2.5f, 7.5f);
|
||||
shaderTest.setVec3("pointLights[1].ambient", 0.05f, 0.05f, 0.05f);
|
||||
shaderTest.setVec3("pointLights[1].diffuse", 1.0f, 0.7f, 0.4f);
|
||||
shaderTest.setVec3("pointLights[1].specular", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setFloat("pointLights[1].constant", 1.0f);
|
||||
shaderTest.setFloat("pointLights[1].linear", 0.09f);
|
||||
shaderTest.setFloat("pointLights[1].quadratic", 0.032f);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Ground Floor - Left Corridor (Warm Light)
|
||||
// Placed halfway down the left hallway behind the arches
|
||||
// -----------------------------------------------------------------------------
|
||||
shaderTest.setVec3("pointLights[2].position", 15.0f, 2.5f, -7.5f);
|
||||
shaderTest.setVec3("pointLights[2].ambient", 0.05f, 0.05f, 0.05f);
|
||||
shaderTest.setVec3("pointLights[2].diffuse", 1.0f, 0.7f, 0.4f);
|
||||
shaderTest.setVec3("pointLights[2].specular", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setFloat("pointLights[2].constant", 1.0f);
|
||||
shaderTest.setFloat("pointLights[2].linear", 0.09f);
|
||||
shaderTest.setFloat("pointLights[2].quadratic", 0.032f);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Ground Floor - Left Corridor, opposite end (Warm Light)
|
||||
// -----------------------------------------------------------------------------
|
||||
shaderTest.setVec3("pointLights[3].position", -15.0f, 2.5f, -7.5f);
|
||||
shaderTest.setVec3("pointLights[3].ambient", 0.05f, 0.05f, 0.05f);
|
||||
shaderTest.setVec3("pointLights[3].diffuse", 1.0f, 0.7f, 0.4f);
|
||||
shaderTest.setVec3("pointLights[3].specular", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setFloat("pointLights[3].constant", 1.0f);
|
||||
shaderTest.setFloat("pointLights[3].linear", 0.09f);
|
||||
shaderTest.setFloat("pointLights[3].quadratic", 0.032f);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Upper Balcony - East Atrium Edge (Cool Light)
|
||||
// Hovering above the balcony floor, shining into the main atrium
|
||||
// -----------------------------------------------------------------------------
|
||||
shaderTest.setVec3("pointLights[4].position", 22.0f, 9.0f, 0.0f);
|
||||
shaderTest.setVec3("pointLights[4].ambient", 0.05f, 0.05f, 0.05f);
|
||||
shaderTest.setVec3("pointLights[4].diffuse", 0.7f, 0.8f, 1.0f);
|
||||
shaderTest.setVec3("pointLights[4].specular", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setFloat("pointLights[4].constant", 1.0f);
|
||||
shaderTest.setFloat("pointLights[4].linear", 0.09f);
|
||||
shaderTest.setFloat("pointLights[4].quadratic", 0.032f);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Upper Balcony - West Atrium Edge (Cool Light)
|
||||
// Hovering above the balcony floor, shining into the main atrium
|
||||
// -----------------------------------------------------------------------------
|
||||
shaderTest.setVec3("pointLights[5].position", -22.0f, 9.0f, 0.0f);
|
||||
shaderTest.setVec3("pointLights[5].ambient", 0.05f, 0.05f, 0.05f);
|
||||
shaderTest.setVec3("pointLights[5].diffuse", 0.7f, 0.8f, 1.0f);
|
||||
shaderTest.setVec3("pointLights[5].specular", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setFloat("pointLights[5].constant", 1.0f);
|
||||
shaderTest.setFloat("pointLights[5].linear", 0.09f);
|
||||
shaderTest.setFloat("pointLights[5].quadratic", 0.032f);
|
||||
|
||||
// spotLight1
|
||||
shaderTest.setBool("spotLights[0].disabled", flashlight);
|
||||
shaderTest.setVec3("spotLights[0].position", camera.position);
|
||||
shaderTest.setVec3("spotLights[0].direction", camera.front);
|
||||
shaderTest.setVec3("spotLights[0].ambient", 0.0f, 0.0f, 0.0f);
|
||||
shaderTest.setVec3("spotLights[0].diffuse", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setVec3("spotLights[0].specular", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setFloat("spotLights[0].constant", 1.0f);
|
||||
shaderTest.setFloat("spotLights[0].linear", 0.09f);
|
||||
shaderTest.setFloat("spotLights[0].quadratic", 0.032f);
|
||||
shaderTest.setFloat("spotLights[0].cutOff", glm::cos(glm::radians(12.5f)));
|
||||
shaderTest.setFloat("spotLights[0].outerCutOff", glm::cos(glm::radians(15.0f)));
|
||||
// spotLight2
|
||||
shaderTest.setVec3("spotLights[1].position", -1.5441f, -0.294683f, 0.211498f);
|
||||
shaderTest.setVec3("spotLights[1].direction", 1, 0, 0);
|
||||
shaderTest.setVec3("spotLights[1].ambient", 0.0f, 0.0f, 0.0f);
|
||||
shaderTest.setVec3("spotLights[1].diffuse", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setVec3("spotLights[1].specular", 1.0f, 1.0f, 1.0f);
|
||||
shaderTest.setFloat("spotLights[1].constant", 1.0f);
|
||||
shaderTest.setFloat("spotLights[1].linear", 0.09f);
|
||||
shaderTest.setFloat("spotLights[1].quadratic", 0.032f);
|
||||
shaderTest.setFloat("spotLights[1].cutOff", glm::cos(glm::radians(12.5f)));
|
||||
shaderTest.setFloat("spotLights[1].outerCutOff", glm::cos(glm::radians(15.0f)));
|
||||
|
||||
// render the loaded model
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
model = glm::scale(model, glm::vec3(0.02f, 0.02f, 0.02f));
|
||||
shaderTest.setMat4("model", model);
|
||||
ourModel.Draw(shaderTest);
|
||||
|
||||
testMesh.Draw();
|
||||
|
||||
|
||||
lightingShader.Use();
|
||||
lightingShader.setMat4("projection", projection);
|
||||
lightingShader.setMat4("view", view);
|
||||
model = glm::mat4(1.0f);
|
||||
|
||||
glm::vec3 offset = glm::vec3(
|
||||
2.0f * cos(glfwGetTime() * 1.0f),
|
||||
0.0f,
|
||||
sin(glfwGetTime() * 1.0f) * 2.0f
|
||||
);
|
||||
orbitCenter = lightPos + offset;
|
||||
model = glm::translate(model, orbitCenter);
|
||||
|
||||
model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube
|
||||
lightingShader.setMat4("model", model);
|
||||
|
||||
lightMesh.Draw();
|
||||
std::cout << "start" << std::endl;
|
||||
std::cout << camera.position.x << std::endl;
|
||||
std::cout << camera.position.y << std::endl;
|
||||
std::cout << camera.position.z << std::endl;
|
||||
|
||||
// Call events & swap buffers
|
||||
glfwSwapBuffers(window);
|
||||
|
|
@ -227,6 +250,8 @@ int main(int argc, char* argv[])
|
|||
void window_resize_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
SCREEN_WIDTH = width;
|
||||
SCREEN_HEIGHT = height;
|
||||
}
|
||||
|
||||
void processInput(GLFWwindow* window)
|
||||
|
|
@ -252,6 +277,15 @@ void processInput(GLFWwindow* window)
|
|||
if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_RELEASE)
|
||||
wireframeHeld = false;
|
||||
|
||||
// Flashlight toggle
|
||||
if (glfwGetKey(window, GLFW_KEY_F) == GLFW_PRESS && !wireframeHeld)
|
||||
{
|
||||
wireframeHeld = true;
|
||||
flashlight = !flashlight;
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_F) == GLFW_RELEASE)
|
||||
wireframeHeld = false;
|
||||
|
||||
// Camera
|
||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
camera.processKeyboard(FORWARD, deltaTime);
|
||||
|
|
@ -261,6 +295,8 @@ void processInput(GLFWwindow* window)
|
|||
camera.processKeyboard(LEFT, deltaTime);
|
||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
camera.processKeyboard(RIGHT, deltaTime);
|
||||
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
||||
camera.processKeyboard(SPRINT, deltaTime);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
BIN
vendor/glfw/glfw3.dll
vendored
BIN
vendor/glfw/glfw3.dll
vendored
Binary file not shown.
6547
vendor/glfw/glfw3.h
vendored
6547
vendor/glfw/glfw3.h
vendored
File diff suppressed because it is too large
Load diff
663
vendor/glfw/glfw3native.h
vendored
663
vendor/glfw/glfw3native.h
vendored
|
|
@ -1,663 +0,0 @@
|
|||
/*************************************************************************
|
||||
* GLFW 3.4 - 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_ */
|
||||
|
||||
BIN
vendor/glfw/libglfw3.a
vendored
BIN
vendor/glfw/libglfw3.a
vendored
Binary file not shown.
BIN
vendor/glfw/libglfw3dll.a
vendored
BIN
vendor/glfw/libglfw3dll.a
vendored
Binary file not shown.
3
vendor/stb/stb_image.cpp
vendored
3
vendor/stb/stb_image.cpp
vendored
|
|
@ -1,3 +1,2 @@
|
|||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
Loading…
Add table
Add a link
Reference in a new issue