Rough first draft of maze game in c++

This commit is contained in:
2023-10-08 22:46:04 -04:00
parent aa39c6d844
commit 38dc495d36
7 changed files with 51596 additions and 0 deletions

7
.gitignore vendored
View File

@@ -19,3 +19,10 @@
# Go workspace file
go.work
*.o
*.swp
# you can download these from the internet
stb_image.c
glad.c

14
Makefile Normal file
View File

@@ -0,0 +1,14 @@
snowland: glad.o snowland.o stb_image.o
g++ -o snowland glad.o snowland.o stb_image.o -ldl -lglfw -std=c++17
glad.o: glad.c
g++ -c -o glad.o glad.c
snowland.o: snowland.cpp
g++ -c -o snowland.o snowland.cpp -std=c++17
stb_image.o: stb_image.c
g++ -c -o stb_image.o stb_image.c -std=c++17
clean:
rm -f *.o snowland

38
fragmentshader.txt Normal file
View File

@@ -0,0 +1,38 @@
#version 460 core
out vec4 FragColor;
in vec3 Normal;
in vec3 FragPos;
uniform vec3 viewPos;
uniform vec3 lightColor;
uniform vec3 objectColor;
void main()
{
// ambient
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
vec3 vecDist = viewPos - FragPos;
vec3 normDist = normalize(vecDist);
// diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normDist;
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
// specular
float specularStrength = 0.5;
vec3 viewDir = normDist;
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * lightColor;
float dist = distance(viewPos, FragPos);
float att = 1.0 / (1.0 + 0.1*dist + 0.01*dist*dist);
vec3 result = (ambient + diffuse + specular) * att * objectColor;
FragColor = vec4(result, 1.0);
}

5658
glad/glad.h Normal file

File diff suppressed because it is too large Load Diff

45494
maze.txt Normal file

File diff suppressed because it is too large Load Diff

367
snowland.cpp Normal file
View File

@@ -0,0 +1,367 @@
#include <stdlib.h>
#include <stdio.h>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stb_image.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "shader_m.h"
#include <iostream>
#include <filesystem>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void processInput(GLFWwindow *window);
// settings
const unsigned int WINDOWWIDTH = 1280;
const unsigned int WINDOWHEIGHT = 720;
// camera
glm::vec3 player_pos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 camera_front = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 camera_up = glm::vec3(0.0f, 1.0f, 0.0f);
bool first_mouse = true;
float yaw = -90.0f;
float pitch = 0.0f;
float lastX = WINDOWWIDTH / 2.0;
float lastY = WINDOWHEIGHT / 2.0;
float fov = 60.0f;
float timed = 0.0f;
float last_frame = 0.0f;
float camera_speed = 10.0f;
const char *projectionC = "projection";
const char *viewC = "view";
const char *modelC = "model";
const char *viewposC = "viewPos";
const char *lightcolorC = "lightColor";
const char *objectcolorC = "objectColor";
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(WINDOWWIDTH, WINDOWHEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
printf("Failed to create GLFW window.\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
printf("Failed to initialize GLAD.\n");
return -1;
}
glEnable(GL_DEPTH_TEST);
FILE* fp = fopen("vertexshader.txt", "r");
if (!fp) {
printf("failed to open vertex shader!\n");
return -1;
}
fseek(fp, 0L, SEEK_END);
unsigned int vertex_sz = ftell(fp);
rewind(fp);
char *vertex_buffer = (char *)calloc(sizeof(char), vertex_sz + 1);
if (fread(vertex_buffer, vertex_sz, 1, fp) != 1) {
printf("failed to read vertex shader!\n");
return -1;
}
fclose(fp);
int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_buffer, NULL);
glCompileShader(vertex_shader);
int success;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[1024];
glGetShaderInfoLog(vertex_shader, 1024, NULL, infoLog);
printf("Vertex shader compile error: %s\n", infoLog);
glfwTerminate();
return -1;
}
fp = fopen("fragmentshader.txt", "r");
if (!fp) {
printf("failed to open fragment shader!\n");
return -1;
}
fseek(fp, 0L, SEEK_END);
unsigned int fragment_sz = ftell(fp);
rewind(fp);
char *fragment_buffer = (char *)calloc(sizeof(char), fragment_sz + 1);
if (fread(fragment_buffer, fragment_sz, 1, fp) != 1) {
printf("failed to read fragment shader!\n");
return -1;
}
fclose(fp);
int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_buffer, NULL);
glCompileShader(fragment_shader);
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[1024];
glGetShaderInfoLog(fragment_shader, 1024, NULL, infoLog);
printf("Fragment shader compile error: %s\n", infoLog);
glfwTerminate();
return -1;
}
int program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success) {
char infoLog[1024];
glGetProgramInfoLog(program, 1024, NULL, infoLog);
printf("Shader program link error: %s\n", infoLog);
glfwTerminate();
return -1;
}
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
free(vertex_buffer);
free(fragment_buffer);
fp = fopen("maze.txt", "r");
fscanf(fp, "%f %f %f %f\n", &player_pos.x, &player_pos.y, &player_pos.z, &yaw);
int num_surfaces;
fscanf(fp, "%d\n", &num_surfaces);
// num surfaces * 6 (vertices per point) * 6 (floats per point)
// add 1 for floor
int num_walls = (num_surfaces) * 6 * 6;
float *wall_vertices = (float *)calloc(sizeof(float), num_surfaces * 6 * 6);
// read walls
for (int i = 0; i < num_surfaces; i++) {
for (int j = 0; j < 6; j++) {
int vix = i*6*6 + j*6;
fscanf(
fp,
"%f %f %f %f %f %f\n",
&wall_vertices[vix],
&wall_vertices[vix+1],
&wall_vertices[vix+2],
&wall_vertices[vix+3],
&wall_vertices[vix+4],
&wall_vertices[vix+5]
);
}
fscanf(fp, "\n");
}
// read floor
float *floor_vertices = (float *)calloc(sizeof(float), 6*6);
for (int j = 0; j < 6; j++) {
int vix = j*6;
fscanf(
fp,
"%f %f %f %f %f %f\n",
&floor_vertices[vix],
&floor_vertices[vix+1],
&floor_vertices[vix+2],
&floor_vertices[vix+3],
&floor_vertices[vix+4],
&floor_vertices[vix+5]
);
}
fclose(fp);
// do stuff for walls
unsigned int wallsVBO, wallsVAO;
glGenVertexArrays(1, &wallsVAO);
glGenBuffers(1, &wallsVBO);
glBindVertexArray(wallsVAO);
glBindBuffer(GL_ARRAY_BUFFER, wallsVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * num_walls, wall_vertices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// normal attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// do stuff for floor
unsigned int floorVBO, floorVAO;
glGenVertexArrays(1, &floorVAO);
glGenBuffers(1, &floorVBO);
glBindVertexArray(floorVAO);
glBindBuffer(GL_ARRAY_BUFFER, floorVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 6 * 1, floor_vertices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// normal attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
int time_sec = 0, num_frames = 0;
while (!glfwWindowShouldClose(window))
{
float current_frame = static_cast<float>(glfwGetTime());
int current_frameI = (int)current_frame;
if (current_frameI != time_sec) {
printf("FPS: %d\n", num_frames);
time_sec = current_frameI;
num_frames = 0;
} else {
num_frames++;
}
timed = current_frame - last_frame;
last_frame = current_frame;
processInput(window);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
glm::mat4 projection = glm::perspective(glm::radians(fov), (float)WINDOWWIDTH / (float)WINDOWHEIGHT, 0.1f, 256.0f);
glUniformMatrix4fv(glGetUniformLocation(program, projectionC), 1, GL_FALSE, &projection[0][0]);
glm::mat4 view = glm::lookAt(player_pos, player_pos + camera_front, camera_up);
glUniformMatrix4fv(glGetUniformLocation(program, viewC), 1, GL_FALSE, &view[0][0]);
glm::vec3 wall_color = glm::vec3(0.5f, 0.5f, 0.5f);
glUniform3fv(glGetUniformLocation(program, objectcolorC), 1, &wall_color[0]);
glm::vec3 light_color = glm::vec3(1.0f, 1.0f, 1.0f);
glUniform3fv(glGetUniformLocation(program, lightcolorC), 1, &light_color[0]);
glUniform3fv(glGetUniformLocation(program, viewposC), 1, &player_pos[0]);
glm::mat4 model = glm::mat4(1.0f);
glUniformMatrix4fv(glGetUniformLocation(program, modelC), 1, GL_FALSE, &model[0][0]);
glBindVertexArray(wallsVAO);
glDrawArrays(GL_TRIANGLES, 0, num_walls);
glm::vec3 floor_color = glm::vec3(0.1f, 0.1f, 0.1f);
glUniform3fv(glGetUniformLocation(program, objectcolorC), 1, &floor_color[0]);
glBindVertexArray(floorVAO);
glDrawArrays(GL_TRIANGLES, 0, 6 * 6 * 1);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &wallsVAO);
glDeleteBuffers(1, &wallsVBO);
glDeleteVertexArrays(1, &floorVAO);
glDeleteBuffers(1, &floorVBO);
glfwTerminate();
return 0;
}
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
float camera_speed_adjusted = static_cast<float>(camera_speed * timed);
glm::vec3 movement;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
movement = glm::vec3(camera_front.x, 0.0, camera_front.z);
player_pos += glm::normalize(movement) * camera_speed_adjusted;
} else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
movement = glm::vec3(-camera_front.x, 0.0, -camera_front.z);
player_pos += glm::normalize(movement) * camera_speed_adjusted;
} else if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
glm::vec3 right = glm::cross(camera_front, camera_up);
movement = glm::vec3(right.x, 0.0, right.z);
player_pos -= glm::normalize(movement) * camera_speed_adjusted;
} else if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
glm::vec3 right = glm::cross(camera_front, camera_up);
movement = glm::vec3(right.x, 0.0, right.z);
player_pos += glm::normalize(movement) * camera_speed_adjusted;
}
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
void mouse_callback(GLFWwindow* window, double xpos_in, double ypos_in)
{
float xpos = static_cast<float>(xpos_in);
float ypos = static_cast<float>(ypos_in);
if (first_mouse)
{
lastX = xpos;
lastY = ypos;
first_mouse = false;
}
float xoffset = xpos - lastX;
float yoffset = lastY - ypos;
lastX = xpos;
lastY = ypos;
float sensitivity = 0.1f;
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
glm::vec3 front;
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
camera_front = glm::normalize(front);
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
fov -= (float)yoffset;
if (fov < 1.0f)
fov = 1.0f;
if (fov > 90.0f)
fov = 90.0f;
}

18
vertexshader.txt Normal file
View File

@@ -0,0 +1,18 @@
#version 460 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
out vec3 FragPos;
out vec3 Normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
gl_Position = projection * view * vec4(FragPos, 1.0);
}