Add ghosts
This commit is contained in:
7
Makefile
7
Makefile
@@ -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
90
ghost.cpp
Normal 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
27
ghost.h
Normal 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
15
ghostfragshader.glsl
Normal 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;
|
||||
}
|
||||
@@ -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
21
ghostshader.glsl
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user