everything

This commit is contained in:
Tarion 2026-07-02 04:02:29 +02:00
parent 79fa59c3aa
commit 8998bc3936
No known key found for this signature in database
19 changed files with 855 additions and 7504 deletions

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View file

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View file

@ -5,48 +5,80 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
find_package(OpenGL REQUIRED) # ------------------------------------------------------------------------------
find_package(glfw3 3.3 QUIET) # 1. Source and Header Files
# ------------------------------------------------------------------------------
if(NOT glfw3_FOUND) set(SOURCES
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
main.cpp main.cpp
vendor/glad/glad.c
vendor/stb/stb_image.cpp
)
set(HEADERS
engine/shader.h engine/shader.h
engine/texture.h engine/texture.h
engine/mesh.h engine/mesh.h
vendor/glad/glad.c
engine/camera.h 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}
${CMAKE_CURRENT_SOURCE_DIR}/vendor ${CMAKE_CURRENT_SOURCE_DIR}/vendor
${CMAKE_CURRENT_SOURCE_DIR}/vendor/assimp/include
) )
if(glfw3_FOUND) # ------------------------------------------------------------------------------
target_link_libraries(Engine2026 PRIVATE glfw OpenGL::GL) # 3. Dependencies & Linking
else() # ------------------------------------------------------------------------------
target_link_libraries(Engine2026 PRIVATE
${GLFW_LIB}
opengl32
gdi32
user32
)
endif()
# Copy assets to build dir # -- OpenGL --
add_custom_command( find_package(OpenGL REQUIRED)
TARGET Engine2026 POST_BUILD 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 COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/assets "${CMAKE_CURRENT_SOURCE_DIR}/assets"
$<TARGET_FILE_DIR:Engine2026>/assets "${CMAKE_CURRENT_BINARY_DIR}/assets"
COMMENT "Copying assets to output directory" 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)

View file

@ -1,56 +1,204 @@
#version 330 core #version 330 core
out vec4 FragColor; 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 FragPos;
in vec3 Normal; in vec3 Normal;
in vec2 TexCoord; in vec2 TexCoords;
uniform sampler2D ourTexture; #define MAX_POINT_LIGHTS 4
uniform sampler2D decal; #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; uniform vec3 viewPos;
vec4 calcTextures(){ // Lights
vec4 tex1 = texture(ourTexture, TexCoord); uniform DirectionalLight dirLight;
vec4 tex2 = texture(decal, TexCoord);
vec4 textures = mix(tex1, tex2, 0.2f);
return textures; uniform PointLight pointLights[MAX_POINT_LIGHTS];
} uniform int numberOfPointLights;
vec4 calcDirectLight(norm, viewDir){ uniform SpotLight spotLights[MAX_SPOT_LIGHTS];
// Ambient Lighting uniform int numberOfSpotLights;
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
// Diffuse Lighting // func declarations
vec3 lightDir = normalize(lightPos - FragPos); vec3 calcTextures();
vec4 calcDirectLight(DirectionalLight light, vec3 normal, vec3 viewDir, vec3 albedo);
float diff = max(dot(norm, lightDir), 0.0); vec4 calcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 albedo);
vec3 diffuse = diff * lightColor; vec4 calcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 albedo);
// 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;
}
void main() void main()
{ {
vec4 result = vec4(0.0f);
vec3 norm = normalize(Normal); vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPos - FragPos); vec3 viewDir = normalize(viewPos - FragPos);
vec4 result = calcTextures(); vec3 albedo = calcTextures();
result += calcDirectLight(norm, viewDir); 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; 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);
}

View file

@ -5,7 +5,7 @@ layout (location = 2) in vec2 aTexCoord;
out vec3 FragPos; out vec3 FragPos;
out vec3 Normal; out vec3 Normal;
out vec2 TexCoord; out vec2 TexCoords;
uniform mat4 model; uniform mat4 model;
uniform mat4 view; uniform mat4 view;
@ -13,9 +13,9 @@ uniform mat4 projection;
void main() void main()
{ {
FragPos = vec3(model * vec4(aPos, 1.0)); FragPos = vec3(model * vec4(aPos, 1.0f));
Normal = mat3(transpose(inverse(model))) * aNormal; Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoord = aTexCoord; TexCoords = aTexCoord;
gl_Position = projection * view * model * vec4(aPos, 1.0f); gl_Position = projection * view * model * vec4(aPos, 1.0f);
} }

View file

@ -0,0 +1,4 @@
import bpy
import sys
bpy.ops.export_scene.fbx(filepath=sys.argv[-1], path_mode='COPY', embed_textures=True)

View file

@ -11,13 +11,14 @@ enum Camera_Movement {
FORWARD, FORWARD,
BACKWARD, BACKWARD,
LEFT, LEFT,
RIGHT RIGHT,
SPRINT
}; };
// Default camera values // Default camera values
const float YAW = -90.0f; const float YAW = -90.0f;
const float PITCH = 0.0f; const float PITCH = 0.0f;
const float SPEED = 2.5f; const float SPEED = 5.5f;
const float SENSITIVITY = 0.1f; const float SENSITIVITY = 0.1f;
const float ZOOM = 45.0f; const float ZOOM = 45.0f;
@ -27,6 +28,7 @@ public:
glm::vec3 position, front, up, right, worldUp; glm::vec3 position, front, up, right, worldUp;
float yaw, pitch; float yaw, pitch;
float movementSpeed, mouseSensitivity, zoom; float movementSpeed, mouseSensitivity, zoom;
bool sprinting = false;
// constructor with vectors // 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) 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) void processKeyboard(Camera_Movement direction, float deltaTime)
{ {
float velocity = movementSpeed * deltaTime; float velocity = movementSpeed * deltaTime;
if (sprinting)
velocity *= 8;
if (direction == FORWARD) if (direction == FORWARD)
position += front * velocity; position += front * velocity;
if (direction == BACKWARD) if (direction == BACKWARD)
@ -65,6 +70,8 @@ public:
position -= right * velocity; position -= right * velocity;
if (direction == RIGHT) if (direction == RIGHT)
position += right * velocity; 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. // 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; 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: private:
// calculates the front vector from the Camera's (updated) Euler Angles // calculates the front vector from the Camera's (updated) Euler Angles

View file

@ -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 <vector>
#include <glad/glad.h> using namespace std;
#define MAX_BONE_INFLUENCE 4
struct Vertex { struct Vertex {
float x, y, z; // position // position
float nX, nY, zY; // normal glm::vec3 Position;
float u, v; // texcoord // 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;
public: string type;
unsigned int VBO, VAO, EBO; string path;
std::size_t indexCount = 0; };
Mesh(const std::vector<Vertex>& vertices, const std::vector<unsigned int>& indices) : indexCount(indices.size()) class Mesh {
public:
// mesh Data
vector<Vertex> vertices;
vector<unsigned int> indices;
vector<Texture> textures;
unsigned int VAO;
// constructor
Mesh(vector<Vertex> vertices, vector<unsigned int> indices, vector<Texture> textures)
{ {
if (vertices.empty() || indices.empty()) { this->vertices = vertices;
throw std::runtime_error("Mesh created with empty vertices or indices"); this->indices = indices;
this->textures = textures;
// now that we have all the required data, set the vertex buffers and its attribute pointers.
setupMesh();
} }
try // 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
// 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);
}
// draw mesh
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, static_cast<unsigned int>(indices.size()), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
// always good practice to set everything back to defaults once configured.
glActiveTexture(GL_TEXTURE0);
}
private:
// render data
unsigned int VBO, EBO;
// initializes all the buffer objects/arrays
void setupMesh()
{
// create buffers/arrays
glGenVertexArrays(1, &VAO); glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO); glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO); glGenBuffers(1, &EBO);
glBindVertexArray(VAO); glBindVertexArray(VAO);
// load data into vertex buffers
glBindBuffer(GL_ARRAY_BUFFER, VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW); // 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); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
// Position // set the vertex attribute pointers
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x)); // vertex Positions
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
// Normals // vertex normals
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, nX));
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
// Texcoords // vertex texture coords
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, u));
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
} glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));
catch (...) // vertex tangent
{ glEnableVertexAttribArray(3);
std::cout << "Failed to load mesh" << std::endl; 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));
void Draw() const // weights
{ glEnableVertexAttribArray(6);
//glDrawArrays(GL_TRIANGLES, 0, 36); glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, m_Weights));
glBindVertexArray(VAO); glBindVertexArray(0);
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indexCount),
GL_UNSIGNED_INT, 0);
} }
}; };
#endif //ENGINE2026_MESH_H

260
engine/model.h Normal file
View 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

View file

@ -42,8 +42,8 @@ public:
fragmentCode = fragmentStream.str(); fragmentCode = fragmentStream.str();
// Fix encoding issues, specifically for Linux // Fix encoding issues, specifically for Linux
vertexCode.erase(std::remove(vertexCode.begin(), vertexCode.end(), '\r'), vertexCode.end()); //vertexCode.erase(std::remove(vertexCode.begin(), vertexCode.end(), '\r'), vertexCode.end());
fragmentCode.erase(std::remove(fragmentCode.begin(), fragmentCode.end(), '\r'), fragmentCode.end()); //fragmentCode.erase(std::remove(fragmentCode.begin(), fragmentCode.end(), '\r'), fragmentCode.end());
} }
catch (std::ifstream::failure& e) catch (std::ifstream::failure& e)
{ {
@ -112,6 +112,11 @@ public:
void setVec3(const std::string &name, float x, float y, float z) const void setVec3(const std::string &name, float x, float y, float z) const
{ {
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); 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 void setVec4(const std::string &name, const glm::vec4 &value) const
@ -138,6 +143,20 @@ public:
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); 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: private:
void checkCompileErrors(unsigned int shader, std::string type) void checkCompileErrors(unsigned int shader, std::string type)
{ {

View file

@ -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
View file

@ -0,0 +1,3 @@
//
// Created by claire on 28/06/2026.
//

9
game/game.h Normal file
View file

@ -0,0 +1,9 @@
namespace Game {
void Init();
void Update();
void Render();
void PreRender();
void PostRender();
}

268
main.cpp
View file

@ -3,15 +3,13 @@
#include <iostream> #include <iostream>
#include <glad/glad.h> #include <glad/glad.h>
#include <GLFW/glfw3.h> #include <glfw/include/GLFW/glfw3.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include "stb/stb_easy_font.h"
#include <engine/mesh.h>
#include <engine/shader.h> #include <engine/shader.h>
#include <engine/texture.h> #include <engine/model.h>
#include <engine/camera.h> #include <engine/camera.h>
void window_resize_callback(GLFWwindow* window, int width, int height); 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 scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void processInput(GLFWwindow *window); void processInput(GLFWwindow *window);
const int SCREEN_WIDTH = 1920; int SCREEN_WIDTH = 1920;
const int SCREEN_HEIGHT = 1080; int SCREEN_HEIGHT = 1080;
static bool drawWireframe = false; static bool drawWireframe = false;
static bool wireframeHeld = false; static bool wireframeHeld = false;
static bool flashlight = true;
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = SCREEN_WIDTH / 2.0f; float lastX = SCREEN_WIDTH / 2.0f;
@ -65,6 +64,8 @@ int main(int argc, char* argv[])
glfwSetCursorPosCallback(window, mouse_callback); glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback); glfwSetScrollCallback(window, scroll_callback);
glEnable(GL_DEPTH_TEST);
// Hide & Lock Cursor // Hide & Lock Cursor
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
@ -73,145 +74,167 @@ int main(int argc, char* argv[])
Testing 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"); 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"); Model ourModel("assets/models/sponza/Sponza.gltf");
Mesh lightMesh(vertices, indices);
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 // Render Loop
float lastUpdate = 0; 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)) while (!glfwWindowShouldClose(window))
{ {
// per-frame time logic // per-frame time logic
// --------------------
float currentFrame = static_cast<float>(glfwGetTime()); float currentFrame = static_cast<float>(glfwGetTime());
deltaTime = currentFrame - lastFrame; deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame; lastFrame = currentFrame;
// crappy fps printout // crappy fps printout
if (currentFrame - lastUpdate >= 1.0) { if (currentFrame - lastUpdate >= 1.0) {
std::cout << 1.0f / deltaTime << std::endl; // std::cout << 1.0f / deltaTime << std::endl;
lastUpdate += 1.0f; lastUpdate += 1.0f;
} }
// Input processing // Input processing
processInput(window); processInput(window);
// Rendering glClearColor(0, 0, 0, 1);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 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.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) camera.Update(shaderTest, SCREEN_WIDTH, SCREEN_HEIGHT);
glm::mat4 projection = glm::perspective(glm::radians(camera.zoom), (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.1f, 100.0f);
shaderTest.setMat4("projection", projection);
// camera/view transformation shaderTest.setFloat("material.shininess", 32.0f);
glm::mat4 view = camera.GetViewMatrix();
shaderTest.setMat4("view", view);
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); 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); shaderTest.setMat4("model", model);
ourModel.Draw(shaderTest);
testMesh.Draw(); std::cout << "start" << std::endl;
std::cout << camera.position.x << std::endl;
std::cout << camera.position.y << std::endl;
lightingShader.Use(); std::cout << camera.position.z << std::endl;
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();
// Call events & swap buffers // Call events & swap buffers
glfwSwapBuffers(window); glfwSwapBuffers(window);
@ -227,6 +250,8 @@ int main(int argc, char* argv[])
void window_resize_callback(GLFWwindow* window, int width, int height) void window_resize_callback(GLFWwindow* window, int width, int height)
{ {
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
SCREEN_WIDTH = width;
SCREEN_HEIGHT = height;
} }
void processInput(GLFWwindow* window) void processInput(GLFWwindow* window)
@ -252,6 +277,15 @@ void processInput(GLFWwindow* window)
if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_RELEASE) if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_RELEASE)
wireframeHeld = false; 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 // Camera
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera.processKeyboard(FORWARD, deltaTime); camera.processKeyboard(FORWARD, deltaTime);
@ -261,6 +295,8 @@ void processInput(GLFWwindow* window)
camera.processKeyboard(LEFT, deltaTime); camera.processKeyboard(LEFT, deltaTime);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera.processKeyboard(RIGHT, deltaTime); camera.processKeyboard(RIGHT, deltaTime);
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
camera.processKeyboard(SPRINT, deltaTime);
} }

BIN
vendor/glfw/glfw3.dll vendored

Binary file not shown.

6547
vendor/glfw/glfw3.h vendored

File diff suppressed because it is too large Load diff

View file

@ -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

Binary file not shown.

Binary file not shown.

View file

@ -1,3 +1,2 @@
 #define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stb_image.h"