VoxelEngine/Client/Client.py
2020-12-12 10:32:27 +01:00

300 lines
11 KiB
Python

from OpenGL.GL import *
import numpy as np
from OpenGL.GL.ARB.vertex_array_object import glDeleteVertexArrays
from OpenGL.GL.framebufferobjects import glBindRenderbuffer
from OpenGL.GLUT import *
import OpenGL.GLUT.freeglut
from OpenGL.GLU import *
from OpenGL.GL import *
from ctypes import sizeof, c_float, c_void_p, c_uint
from Lights.Spotlight.Spotlight import Spotlight
from WorldProvider.WorldProvider import WorldProvider
from MatrixStuff.Transformations import perspectiveMatrix, lookAt, translate, rotate
from Objects.Cube.Cube import Cube
from Objects.Cuboid.Cuboid import Cuboid
from Objects.World import World
import json
import random
import time
from scipy.signal import convolve
MAX_DISTANCE = 200.0
FRICTION_COEFFICENT = 1
EPSILON = 0.00001
def value_to_color(v, min_value, max_value):
r = g = b = 0.0
scope = max_value - min_value
normalized = (v - min_value) / (max_value - min_value)
if 0.5 * scope + min_value != 0:
b = max(0, 1.0 - abs(2.0 * normalized))
g = max(0, 1.0 - abs(2.0 * normalized - 1.0))
r = max(0, 1.0 - abs(2.0 * normalized - 2.0))
l = np.sqrt((r * r + b * b + g * g))
r /= l
g /= l
b /= l
return r, g, b
class Client:
def __init__(self, test=False, pos=[0, 0, 0]):
self.state = 0
with open('./config.json', 'r') as f:
self.config = json.load(f)
glutInit(sys.argv)
self.width = 1920
self.height = 1080
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
glutInitWindowSize(self.width, self.height)
glutCreateWindow(b'Voxelengine')
with open('passthroughvertex.glsl', 'r') as f:
vertex_shader_string = f.read()
self.passthrough_vertex_shader_id = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(self.passthrough_vertex_shader_id, vertex_shader_string)
glCompileShader(self.passthrough_vertex_shader_id)
if glGetShaderiv(self.passthrough_vertex_shader_id, GL_COMPILE_STATUS) != GL_TRUE:
raise RuntimeError(glGetShaderInfoLog(self.passthrough_vertex_shader_id))
with open('vertex.glsl', 'r') as f:
vertex_shader_string = f.read()
self.vertex_shader_id = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(self.vertex_shader_id, vertex_shader_string)
glCompileShader(self.vertex_shader_id)
if glGetShaderiv(self.vertex_shader_id, GL_COMPILE_STATUS) != GL_TRUE:
raise RuntimeError(glGetShaderInfoLog(self.vertex_shader_id))
with open('fragment.glsl', 'r') as f:
fragment_shader_string = f.read()
self.fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(self.fragment_shader_id, fragment_shader_string)
glCompileShader(self.fragment_shader_id)
if glGetShaderiv(self.fragment_shader_id, GL_COMPILE_STATUS) != GL_TRUE:
raise RuntimeError(glGetShaderInfoLog(self.fragment_shader_id))
Cube.initializeShader()
Cuboid.initializeShader()
self.geometry_shaders = {
Cube: Cube.GeometryShaderId,
Cuboid: Cuboid.GeometryShaderId
}
self.normal_program = {}
self.depth_program = {}
for key in self.geometry_shaders.keys():
self.normal_program[key] = glCreateProgram()
glAttachShader(self.normal_program[key], self.vertex_shader_id)
glAttachShader(self.normal_program[key], key.GeometryShaderId)
glAttachShader(self.normal_program[key], self.fragment_shader_id)
glLinkProgram(self.normal_program[key])
self.depth_program[self.normal_program[key]] = Spotlight.getDepthProgram(self.vertex_shader_id,
key.GeometryShaderId)
self.world_provider = WorldProvider(self.normal_program)
for x_pos in range(0, 100):
for y_pos in range(0, 100):
for z_pos in range(0, 1):
self.world_provider.world.put_object(x_pos, y_pos, z_pos, Cuboid().setColor(
random.randint(0, 100) / 100.0, random.randint(0, 100) / 100.0, random.randint(0, 100) / 100.0))
self.projMatrix = perspectiveMatrix(45.0, 400 / 400, 0.01, MAX_DISTANCE)
self.rx = self.cx = self.cy = 0
self.opening = 45
glutReshapeFunc(self.resize)
glutDisplayFunc(self.display)
glutKeyboardFunc(self.keyboardHandler)
glutSpecialFunc(self.funcKeydHandler)
self.pos = pos
self.time = time.time()
self.field = (100, 100, 1)
self.e_a = np.array([
[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[0, 1, 0],
[-1, 1, 0],
[-1, 0, 0],
[-1, -1, 0],
[0, -1, 0],
[1, -1, 0],
])
self.relaxation_time = 0.55 # 0.55
self.w_a = [
4.0 / 9.0,
1.0 / 9.0,
1.0 / 36.0,
1.0 / 9.0,
1.0 / 36.0,
1.0 / 9.0,
1.0 / 36.0,
1.0 / 9.0,
1.0 / 36.0
]
self.n_a = np.zeros((len(self.e_a),) + self.field)
self.n_a_eq = np.zeros(self.n_a.shape)
self.n = np.zeros(self.field)
self.n[:, :, :] += 1.0
self.gravity_applies = np.zeros(self.field)
# self.n /= np.sum(self.n)
self.n_a[0] = np.array(self.n)
self.u = np.zeros(self.field + (self.e_a.shape[1],))
self.compressible = True
self.max_n = self.w_a[0]
self.test_pixel = [40, 50, 0]
if not test:
glutMainLoop()
else:
self.display()
self.resize(100, 100)
def display(self):
glClearColor(0, 0, 0, 0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
projMatrix = perspectiveMatrix(45, float(self.width) / float(self.height), 0.01, MAX_DISTANCE)
world: World = self.world_provider.world
lights = world.get_lights_to_render(self.pos, self.config['render_light_distance'])
for light in lights:
light.prepareForDepthMapping()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
light_mat = translate(light.pos[0], light.pos[1], light.pos[2]) * \
lookAt(0, 0, 0, -light.pos[0], -light.pos[1], -light.pos[2], 0, 1, 0) * \
perspectiveMatrix(90, float(light.map_size) / float(light.map_size), 0.01, MAX_DISTANCE)
for obj_type, program_id in self.depth_program.items():
glUseProgram(program_id)
widthid = glGetUniformLocation(program_id, 'width')
heightid = glGetUniformLocation(program_id, 'height')
nearid = glGetUniformLocation(program_id, 'near')
farid = glGetUniformLocation(program_id, 'far')
glUniform1f(nearid, 0.01)
glUniform1f(farid, 100)
glUniform1f(widthid, light.map_size)
glUniform1f(heightid, light.map_size)
world.render(light_mat, rotate(0, 0, 0), self.depth_program)
glFlush()
light.finishDepthMapping()
glClearColor(0, 0, 0, 0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glClearColor(0, 0, 0, 0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
for obj_type, program_id in self.normal_program.items():
glUseProgram(program_id)
widthid = glGetUniformLocation(program_id, 'width')
heightid = glGetUniformLocation(program_id, 'height')
nearid = glGetUniformLocation(program_id, 'near')
farid = glGetUniformLocation(program_id, 'far')
glUniform1f(nearid, 0.01)
glUniform1f(farid, 100)
glUniform1f(widthid, self.width)
glUniform1f(heightid, self.height)
world.render(translate(self.pos[0], self.pos[1], self.pos[2]) * lookAt(0, 0, 0, 0, 0, -self.pos[2], 0, 1,
0) * projMatrix, rotate(0, 0, 0))
glFlush()
glutSwapBuffers()
min_value = 0
max_value_n = np.max(self.n)
# max_value_n = 1.0
vel = np.sqrt(np.sum(np.square(self.u), axis=3)) *self.n
max_value_vel = np.max(vel)
# max_value_vel = np.sqrt(3)
print('round')
print('sum n: %f' % np.sum(self.n))
print('max n: %f' % np.max(self.n))
print('min n: %f' % np.min(self.n))
print('sum vel: %f' % np.sum(vel))
print('max vel: %f' % np.max(vel))
print('min vel: %f' % np.min(vel))
for x_pos in range(0, 100):
for y_pos in range(0, 100):
for z_pos in range(0, 1):
if self.state == 2:
r, g, b = value_to_color(int(self.gravity_applies[x_pos, y_pos, z_pos]), 0, 1)
if self.state == 1:
r, g, b = value_to_color(vel[x_pos, y_pos, z_pos], min_value, max_value_vel)
if self.state == 0:
r, g, b = value_to_color(self.n[x_pos, y_pos, z_pos], min_value, max_value_n)
self.world_provider.world.set_color(x_pos, y_pos, z_pos, r, g, b)
self.world_provider.world.set_color(int(round(self.test_pixel[0])),
int(round(self.test_pixel[1])),
int(round(self.test_pixel[2])), 1.0, 1.0, 1.0)
# print(1.0 / (time.time() - self.time))
self.time = time.time()
glutPostRedisplay()
def resize(self, w, h):
w = max(w, 1)
h = max(h, 1)
glViewport(0, 0, w, h)
self.projMatrix = perspectiveMatrix(45.0, float(w) / float(h), 0.01, MAX_DISTANCE)
self.width = w
self.height = h
def keyboardHandler(self, key: int, x: int, y: int):
if key == b'\x1b':
exit()
if key == b'+':
self.rx += 0.25
if key == b'-':
self.rx -= 0.25
if key == b'w':
self.cy += 0.25
if key == b's':
self.cy -= 0.25
if key == b'a':
self.cx -= 0.25
if key == b'd':
self.cx += 0.25
if key == b'q':
self.opening -= 0.25
if key == b'e':
self.opening += 0.25
if key == b'+':
self.state = (self.state +1) % 3
if key == b'r':
print(self.cx, self.cy, self.opening)
# glutPostRedisplay()
# print(key,x,y)
def funcKeydHandler(self, key: int, x: int, y: int):
if key == 11:
glutFullScreenToggle()
# print(key)
if __name__ == '__main__':
client = Client(pos=[-50, -50, -200])