Fixes for rendering and add maze parser
This commit is contained in:
@@ -1,2 +1,6 @@
|
||||
# snowland-game
|
||||
My experiments with go, sdl and opengl.
|
||||
This is a continuation of my [goland-game](https://github.com/five-hundred-eleven/goland-game) project.
|
||||
|
||||
While the previous project was implemented in go, for this project I was not able to get the go bindings for OpenGL working, and so I went with C++.
|
||||
|
||||

|
||||
|
||||
@@ -27,7 +27,7 @@ void main()
|
||||
float specularStrength = 0.5;
|
||||
vec3 viewDir = normDist;
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 8);
|
||||
vec3 specular = specularStrength * spec * lightColor;
|
||||
|
||||
float dist = distance(viewPos, FragPos);
|
||||
|
||||
145
mazeparser.py
Normal file
145
mazeparser.py
Normal file
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import matplotlib.image as mpimage
|
||||
|
||||
img = mpimage.imread("/home/cowley/Pictures/maze.png")
|
||||
rows = len(img)
|
||||
cols = len(img[0])
|
||||
|
||||
|
||||
def isfilled(val):
|
||||
return all(x > 0.2 for x in val)
|
||||
|
||||
|
||||
def getval(img, x, y):
|
||||
if y < 0 or y >= len(img):
|
||||
return False
|
||||
if x < 0 or x >= len(img[y]):
|
||||
return False
|
||||
return isfilled(img[y][x])
|
||||
|
||||
|
||||
segments = []
|
||||
for iy in range(-1, rows + 1):
|
||||
seg_start = None
|
||||
for ix in range(-1, cols + 1):
|
||||
if getval(img, ix, iy) and not getval(img, ix, iy - 1):
|
||||
if seg_start is None:
|
||||
seg_start = (ix - 0.5, iy - 0.5)
|
||||
else:
|
||||
if seg_start is not None:
|
||||
segments.append((seg_start, (ix - 0.5, iy - 0.5), (0.0, 0.0, 1.0)))
|
||||
seg_start = None
|
||||
if seg_start is not None:
|
||||
segments.append((seg_start, (cols - 0.5, iy - 0.5), (0.0, 0.0, 1.0)))
|
||||
|
||||
|
||||
for iy in range(-1, rows + 1):
|
||||
seg_start = None
|
||||
for ix in range(-1, cols + 1):
|
||||
if getval(img, ix, iy) and not getval(img, ix, iy + 1):
|
||||
if seg_start is None:
|
||||
seg_start = (ix - 0.5, iy + 0.5)
|
||||
else:
|
||||
if seg_start is not None:
|
||||
segments.append((seg_start, (ix - 0.5, iy + 0.5), (0.0, 0.0, -1.0)))
|
||||
seg_start = None
|
||||
if seg_start is not None:
|
||||
segments.append((seg_start, (cols - 0.5, iy + 0.5), (0.0, 0.0, -1.0)))
|
||||
|
||||
for ix in range(-1, cols + 1):
|
||||
seg_start = None
|
||||
for iy in range(-1, rows + 1):
|
||||
if getval(img, ix, iy) and not getval(img, ix - 1, iy):
|
||||
if seg_start is None:
|
||||
seg_start = (ix - 0.5, iy - 0.5)
|
||||
else:
|
||||
if seg_start is not None:
|
||||
segments.append((seg_start, (ix - 0.5, iy - 0.5), (-1.0, 0.0, 0.0)))
|
||||
seg_start = None
|
||||
if seg_start is not None:
|
||||
segments.append((seg_start, (ix - 0.5, rows - 0.5), (-1.0, 0.0, 0.0)))
|
||||
|
||||
for ix in range(-1, cols + 1):
|
||||
seg_start = None
|
||||
for iy in range(-1, rows + 1):
|
||||
if getval(img, ix, iy) and not getval(img, ix + 1, iy):
|
||||
if seg_start is None:
|
||||
seg_start = (ix + 0.5, iy - 0.5)
|
||||
else:
|
||||
if seg_start is not None:
|
||||
segments.append((seg_start, (ix + 0.5, iy - 0.5), (1.0, 0.0, 0.0)))
|
||||
seg_start = None
|
||||
if seg_start is not None:
|
||||
segments.append((seg_start, (ix + 0.5, rows - 0.5), (1.0, 0.0, 0.0)))
|
||||
|
||||
print(segments[:10])
|
||||
|
||||
res = {}
|
||||
res["players"] = []
|
||||
player = {
|
||||
"y": 2.5,
|
||||
"x": 845.0,
|
||||
"z": -5.0,
|
||||
"yaw": 270.0,
|
||||
}
|
||||
res["players"].append(player)
|
||||
res["surfaces"] = []
|
||||
for segment in segments:
|
||||
p1 = {"x": segment[0][0], "z": -segment[0][1], "y": 0.0}
|
||||
p2 = {
|
||||
"x": segment[1][0],
|
||||
"z": -segment[1][1],
|
||||
"y": 0.0,
|
||||
}
|
||||
p3 = {
|
||||
"x": segment[1][0],
|
||||
"z": -segment[1][1],
|
||||
"y": 5.0,
|
||||
}
|
||||
p4 = {
|
||||
"x": segment[0][0],
|
||||
"z": -segment[0][1],
|
||||
"y": 5.0,
|
||||
}
|
||||
surface = [p1, p2, p3, p4, segment[2]]
|
||||
res["surfaces"].append(surface)
|
||||
|
||||
xmin = 0.0
|
||||
xmax = 0.0
|
||||
zmin = 0.0
|
||||
zmax = 0.0
|
||||
|
||||
with open("maze.txt", "w") as f:
|
||||
f.write(f"{player['x']} {player['y']} {player['z']} {player['yaw']}\n")
|
||||
f.write(f"{len(res['surfaces'])}\n")
|
||||
for segment in res["surfaces"]:
|
||||
for point in segment[:4]:
|
||||
if point["x"] < xmin:
|
||||
xmin = point["x"]
|
||||
if point["x"] > xmax:
|
||||
xmax = point["x"]
|
||||
if point["z"] < zmin:
|
||||
zmin = point["z"]
|
||||
if point["z"] > zmax:
|
||||
zmax = point["x"]
|
||||
point = segment[0]
|
||||
norm = f"{segment[4][0]} {segment[4][1]} {segment[4][2]}"
|
||||
f.write(f"{point['x']} {point['y']} {point['z']} {norm}\n")
|
||||
point = segment[1]
|
||||
f.write(f"{point['x']} {point['y']} {point['z']} {norm}\n")
|
||||
point = segment[2]
|
||||
f.write(f"{point['x']} {point['y']} {point['z']} {norm}\n")
|
||||
point = segment[3]
|
||||
f.write(f"{point['x']} {point['y']} {point['z']} {norm}\n")
|
||||
point = segment[2]
|
||||
f.write(f"{point['x']} {point['y']} {point['z']} {norm}\n")
|
||||
point = segment[0]
|
||||
f.write(f"{point['x']} {point['y']} {point['z']} {norm}\n")
|
||||
f.write("\n")
|
||||
f.write(f"{xmin} 0.0 {zmin} 0.0 1.0 0.0\n")
|
||||
f.write(f"{xmax} 0.0 {zmin} 0.0 1.0 0.0\n")
|
||||
f.write(f"{xmin} 0.0 {zmax} 0.0 1.0 0.0\n")
|
||||
f.write(f"{xmax} 0.0 {zmax} 0.0 1.0 0.0\n")
|
||||
f.write(f"{xmin} 0.0 {zmax} 0.0 1.0 0.0\n")
|
||||
f.write(f"{xmax} 0.0 {zmin} 0.0 1.0 0.0\n")
|
||||
77
snowland.cpp
77
snowland.cpp
@@ -22,8 +22,8 @@ void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
void processInput(GLFWwindow *window);
|
||||
|
||||
// settings
|
||||
const unsigned int WINDOWWIDTH = 1280;
|
||||
const unsigned int WINDOWHEIGHT = 720;
|
||||
const unsigned int WINDOWWIDTH = 1600;
|
||||
const unsigned int WINDOWHEIGHT = 900;
|
||||
|
||||
// camera
|
||||
glm::vec3 player_pos = glm::vec3(0.0f, 0.0f, 3.0f);
|
||||
@@ -31,7 +31,7 @@ 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 yaw = 0.0f;
|
||||
float pitch = 0.0f;
|
||||
float lastX = WINDOWWIDTH / 2.0;
|
||||
float lastY = WINDOWHEIGHT / 2.0;
|
||||
@@ -49,6 +49,7 @@ const char *modelC = "model";
|
||||
const char *viewposC = "viewPos";
|
||||
const char *lightcolorC = "lightColor";
|
||||
const char *objectcolorC = "objectColor";
|
||||
const char *lightstrengthC = "lightStrength";
|
||||
|
||||
int num_walls;
|
||||
float *wall_vertices;
|
||||
@@ -74,7 +75,7 @@ glm::vec3 checkIntersection(glm::vec3 movement) {
|
||||
glm::vec3 vec_start, vec_stop, p1, p2, p3, res;
|
||||
int gotX = 0, gotZ = 0;
|
||||
vec_start = player_pos;
|
||||
vec_stop = vec_start + movement * 10.0f;
|
||||
vec_stop = vec_start + movement * 20.0f;
|
||||
res.x = movement.x;
|
||||
res.y = movement.y;
|
||||
res.z = movement.z;
|
||||
@@ -119,7 +120,7 @@ int main()
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
GLFWwindow* window = glfwCreateWindow(WINDOWWIDTH, WINDOWHEIGHT, "LearnOpenGL", NULL, NULL);
|
||||
GLFWwindow* window = glfwCreateWindow(WINDOWWIDTH, WINDOWHEIGHT, "Snowland!", NULL, NULL);
|
||||
if (window == NULL)
|
||||
{
|
||||
printf("Failed to create GLFW window.\n");
|
||||
@@ -198,15 +199,28 @@ int main()
|
||||
return -1;
|
||||
}
|
||||
|
||||
int program = glCreateProgram();
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
||||
int wall_program = glCreateProgram();
|
||||
glAttachShader(wall_program, vertex_shader);
|
||||
glAttachShader(wall_program, fragment_shader);
|
||||
glLinkProgram(wall_program);
|
||||
glGetProgramiv(wall_program, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
char infoLog[1024];
|
||||
glGetProgramInfoLog(program, 1024, NULL, infoLog);
|
||||
printf("Shader program link error: %s\n", infoLog);
|
||||
glGetProgramInfoLog(wall_program, 1024, NULL, infoLog);
|
||||
printf("Shader wall_program link error: %s\n", infoLog);
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int floor_program = glCreateProgram();
|
||||
glAttachShader(floor_program, vertex_shader);
|
||||
glAttachShader(floor_program, fragment_shader);
|
||||
glLinkProgram(floor_program);
|
||||
glGetProgramiv(floor_program, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
char infoLog[1024];
|
||||
glGetProgramInfoLog(floor_program, 1024, NULL, infoLog);
|
||||
printf("Shader floor_program link error: %s\n", infoLog);
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
@@ -221,9 +235,8 @@ int main()
|
||||
fscanf(fp, "%f %f %f %f\n", &player_pos.x, &player_pos.y, &player_pos.z, &yaw);
|
||||
fscanf(fp, "%d\n", &num_walls);
|
||||
// num surfaces * 6 (vertices per point) * 6 (floats per point)
|
||||
// add 1 for floor
|
||||
int num_walls = (num_walls) * 6 * 6;
|
||||
wall_vertices = (float *)calloc(sizeof(float), num_walls * 6 * 6);
|
||||
int num_wall_vertices = num_walls * 6 * 6;
|
||||
wall_vertices = (float *)calloc(sizeof(float), num_wall_vertices);
|
||||
// read walls
|
||||
for (int i = 0; i < num_walls; i++) {
|
||||
for (int j = 0; j < 6; j++) {
|
||||
@@ -266,7 +279,7 @@ int main()
|
||||
glBindVertexArray(wallsVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, wallsVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * num_walls, wall_vertices, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * num_wall_vertices, wall_vertices, GL_STATIC_DRAW);
|
||||
|
||||
// position attribute
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
|
||||
@@ -314,30 +327,40 @@ int main()
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glUseProgram(program);
|
||||
glUseProgram(wall_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]);
|
||||
glUniformMatrix4fv(glGetUniformLocation(wall_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]);
|
||||
glUniformMatrix4fv(glGetUniformLocation(wall_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 wall_color = glm::vec3(0.61f, 0.6f, 0.59f);
|
||||
glUniform3fv(glGetUniformLocation(wall_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(wall_program, lightcolorC), 1, &light_color[0]);
|
||||
|
||||
glUniform3fv(glGetUniformLocation(program, viewposC), 1, &player_pos[0]);
|
||||
glUniform3fv(glGetUniformLocation(wall_program, viewposC), 1, &player_pos[0]);
|
||||
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, modelC), 1, GL_FALSE, &model[0][0]);
|
||||
glUniformMatrix4fv(glGetUniformLocation(wall_program, modelC), 1, GL_FALSE, &model[0][0]);
|
||||
|
||||
glBindVertexArray(wallsVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, num_walls);
|
||||
glDrawArrays(GL_TRIANGLES, 0, num_wall_vertices);
|
||||
|
||||
glm::vec3 floor_color = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
glUniform3fv(glGetUniformLocation(program, objectcolorC), 1, &floor_color[0]);
|
||||
glUseProgram(floor_program);
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(floor_program, projectionC), 1, GL_FALSE, &projection[0][0]);
|
||||
glUniformMatrix4fv(glGetUniformLocation(floor_program, viewC), 1, GL_FALSE, &view[0][0]);
|
||||
glUniformMatrix4fv(glGetUniformLocation(floor_program, modelC), 1, GL_FALSE, &model[0][0]);
|
||||
glUniform3fv(glGetUniformLocation(floor_program, viewposC), 1, &player_pos[0]);
|
||||
|
||||
glm::vec3 floor_color = glm::vec3(0.11f, 0.1f, 0.09f);
|
||||
glUniform3fv(glGetUniformLocation(floor_program, objectcolorC), 1, &floor_color[0]);
|
||||
|
||||
glm::vec3 floor_light_color = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
glUniform3fv(glGetUniformLocation(floor_program, lightcolorC), 1, &floor_light_color[0]);
|
||||
|
||||
glBindVertexArray(floorVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6 * 6 * 1);
|
||||
|
||||
Reference in New Issue
Block a user