Add ghosts

This commit is contained in:
2023-10-13 01:13:57 -04:00
parent 3422fafbff
commit b6b83e9328
6 changed files with 246 additions and 6 deletions

View File

@@ -2,8 +2,8 @@ CC := g++
CFLAGS := -std=c++17 -O3
LDFLAGS := -ldl -lglfw
ghostland: glad.o ghostland.o stb_image.o collisions.o player.o shader.o
$(CC) -o ghostland glad.o ghostland.o stb_image.o collisions.o player.o shader.o $(LDFLAGS) $(CFLAGS)
ghostland: glad.o ghostland.o stb_image.o collisions.o player.o shader.o ghost.o
$(CC) -o ghostland glad.o ghostland.o stb_image.o collisions.o player.o shader.o ghost.o $(LDFLAGS) $(CFLAGS)
glad.o: glad.c
$(CC) -c -o glad.o glad.c $(CFLAGS)
@@ -23,5 +23,8 @@ player.o: player.cpp player.h
shader.o: shader.cpp shader.h
$(CC) -c -o shader.o shader.cpp $(CFLAGS)
ghost.o: ghost.cpp ghost.h
$(CC) -c -o ghost.o ghost.cpp $(CFLAGS)
clean:
rm -f *.o ghostland

90
ghost.cpp Normal file
View File

@@ -0,0 +1,90 @@
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
#include <stdio.h>
#include "ghost.h"
int counter = 0;
Ghost::Ghost(float xmin, float xmax, float zmin, float zmax) {
ghost_id = counter;
counter++;
this->xmin = xmin;
this->xmax = xmax;
this->zmin = zmin;
this->zmax = zmax;
pos.x = rand_float(xmin, xmax);
pos.y = 2.5;
pos.z = rand_float(zmin, zmax);
y_offset = rand_float(0.0, 3.14);
yawr = rand_float(0.0, 6.28);
first_frame = false;
}
void Ghost::apply_movement() {
float curr_time = static_cast<float>(glfwGetTime());
if (!first_frame) {
first_frame = true;
prev_move_time = curr_time;
return;
}
float diff_time = curr_time - prev_move_time;
prev_move_time = curr_time;
glm::vec3 moved;
moved.x = pos.x + (-sin(yawr) + cos(yawr)) * diff_time;
moved.y = 2.5 + sin(curr_time + y_offset);
moved.z = pos.z + (cos(yawr) + sin(yawr)) * diff_time;
bool reset_yaw = false;
if (moved.x < xmin) {
reset_yaw = true;
moved.x = xmin;
} else if (moved.x > xmax) {
reset_yaw = true;
moved.x = xmax;
}
if (moved.z < zmin) {
reset_yaw = true;
moved.z = zmin;
} else if (moved.z > zmax) {
reset_yaw = true;
moved.z = zmax;
}
if (reset_yaw) {
yawr = rand_float(0.0, 6.28);
} else {
yawr += rand_float(-0.3, 0.3);
}
pos = moved;
}
glm::mat4 Ghost::get_model(glm::vec3 &camera_pos) {
glm::mat4 ghost_model = glm::mat4(1.0f);
ghost_model = glm::translate(ghost_model, pos);
glm::vec3 ghost_direction = pos - camera_pos;
ghost_model = glm::rotate(ghost_model, atan2f(ghost_direction.x, ghost_direction.z), glm::vec3(0.0f, 1.0f, 0.0f));
return ghost_model;
}
float rand_float(float rmin, float rmax) {
float rdiff = rmax - rmin;
float res = (float)rand()/(float)RAND_MAX;
return res * rdiff + rmin;
}

27
ghost.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef GHOST_H
#define GHOST_H
#include <glm/glm.hpp>
class Ghost {
public:
Ghost(float xmin, float xmax, float zmin, float zmax);
void apply_movement();
glm::mat4 get_model(glm::vec3 &camera_pos);
private:
int ghost_id;
bool first_frame;
glm::vec3 pos;
float yawr;
float xmin;
float xmax;
float zmin;
float zmax;
float y_offset;
float prev_move_time;
};
float rand_float(float rmin, float rmax);
#endif

15
ghostfragshader.glsl Normal file
View File

@@ -0,0 +1,15 @@
#version 460 core
out vec4 FragColor;
in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoord;
uniform sampler2D texture0;
void main() {
vec4 outcolor = texture(texture0, TexCoord);
outcolor.a = outcolor.a * 0.3;
FragColor = outcolor;
}

View File

@@ -16,6 +16,7 @@
#include "collisions.h"
#include "player.h"
#include "shader.h"
#include "ghost.h"
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
@@ -87,6 +88,7 @@ int main(int argc, char *argv[])
// num surfaces * 6 (vertices per point) * 6 (floats per point)
int num_wall_vertices = num_walls * 6 * 6;
wall_vertices = (float *)calloc(sizeof(float), num_wall_vertices);
int xmin_wall, xmax_wall, zmin_wall, zmax_wall;
// read walls
for (int i = 0; i < num_walls; i++) {
for (int j = 0; j < 6; j++) {
@@ -104,6 +106,16 @@ int main(int argc, char *argv[])
printf("3rd fscanf failed.\n");
return -1;
}
if (wall_vertices[vix] < xmin_wall) {
xmin_wall = wall_vertices[vix];
} else if (wall_vertices[vix] > xmax_wall) {
xmax_wall = wall_vertices[vix];
}
if (wall_vertices[vix + 2] < zmin_wall) {
zmin_wall = wall_vertices[vix + 2];
} else if (wall_vertices[vix + 2] > zmax_wall) {
zmax_wall = wall_vertices[vix + 2];
}
}
if (fscanf(fp, "\n") == EOF) {
printf("4th fscanf failed.\n");
@@ -145,7 +157,7 @@ int main(int argc, char *argv[])
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
//glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
@@ -159,6 +171,9 @@ int main(int argc, char *argv[])
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
int wall_program = create_shader_program("vertexshader.glsl", "fragmentshader.glsl");
if (wall_program < 0) {
glfwTerminate();
@@ -246,6 +261,57 @@ int main(int argc, char *argv[])
int trail_ix = 0;
int trail_sz = 0;
// do stuff for ghosts
// create program
int ghost_program = create_shader_program("ghostshader.glsl", "ghostfragshader.glsl");
if (ghost_program < 0) {
glfwTerminate();
return -1;
}
// ghost vertices
float ghost_vertices[] = {
-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,
};
unsigned int ghostVBO, ghostVAO;
glGenVertexArrays(1, &ghostVAO);
glBindVertexArray(ghostVAO);
glGenBuffers(1, &ghostVBO);
glBindBuffer(GL_ARRAY_BUFFER, ghostVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(ghost_vertices), ghost_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
// ghost texture
unsigned int ghost_texture;
glGenTextures(1, &ghost_texture);
glBindTexture(GL_TEXTURE_2D, ghost_texture);
// set the texture wrapping parameters
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, numberChannels;
//stbi_set_flip_vertically_on_load(true);
unsigned char *ghost_data = stbi_load("ghost_facing_right.png", &width, &height, &numberChannels, 0);
printf("Num channels: %d\n", numberChannels);
if (!ghost_data) {
printf("Failed to load texture!\n");
glfwTerminate();
return -1;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ghost_data);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(ghost_data);
// TODO move these into config file??
int time_secI = 0, num_frames = 1;
float time_sec;
@@ -260,6 +326,11 @@ int main(int argc, char *argv[])
float largecutoff = glm::cos(glm::radians(30.0f));
float smallcutoff = glm::cos(glm::radians(7.5f));
std::vector<Ghost *> ghosts;
for (int i = 0; i < 4000; i++) {
ghosts.push_back(new Ghost(xmin_wall, xmax_wall, zmin_wall, zmax_wall));
}
while (!glfwWindowShouldClose(window))
{
float current_frame = static_cast<float>(glfwGetTime());
@@ -368,10 +439,24 @@ int main(int argc, char *argv[])
model = glm::rotate(model, glm::radians(trail_angles[i]), glm::vec3(0.0f, -1.0f, 0.0f));
set_uniform(trail_program, modelC, model);
glBindVertexArray(trailVAO);
glDrawArrays(GL_TRIANGLES, 0, 3 * 3 * 3);
}
glUseProgram(ghost_program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, ghost_texture);
set_uniform(ghost_program, projectionC, projection);
set_uniform(ghost_program, viewC, view);
for (int i = 0; i < ghosts.size(); i++) {
glm::mat4 ghost_model = ghosts[i]->get_model(camera_pos);
ghosts[i]->apply_movement();
set_uniform(ghost_program, modelC, ghost_model);
glBindVertexArray(ghostVAO);
glDrawArrays(GL_TRIANGLES, 0, (3 + 3 + 2) * 6);
}
player->apply_movement();
glfwSwapBuffers(window);
@@ -389,8 +474,7 @@ int main(int argc, char *argv[])
return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}

21
ghostshader.glsl Normal file
View File

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