VoxelEngine/Client/Client.py

251 lines
9.3 KiB
Python
Raw Permalink Normal View History

2020-11-08 10:20:23 +01:00
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
2020-11-30 19:15:08 +01:00
FRICTION_COEFFICENT = 1
2020-11-08 10:20:23 +01:00
EPSILON = 0.00001
2020-11-30 19:15:08 +01:00
2020-11-08 10:20:23 +01:00
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))
2020-11-30 19:15:08 +01:00
l = np.sqrt((r * r + b * b + g * g))
2020-11-08 10:20:23 +01:00
r /= l
g /= l
b /= l
return r, g, b
2020-11-30 19:15:08 +01:00
2020-11-08 10:20:23 +01:00
class Client:
def __init__(self, test=False, pos=[0, 0, 0], world_class=WorldProvider):
2020-12-12 10:32:27 +01:00
self.state = 0
2020-11-08 10:20:23 +01:00
with open('./config.json', 'r') as f:
self.config = json.load(f)
self.init_shaders()
self.world_provider = world_class(self.normal_program)
self.draw_world()
self.pos = pos
self.time = time.time()
2022-08-12 15:48:30 +02:00
self.projMatrix = perspectiveMatrix(45.0, 400 / 400, 0.01, MAX_DISTANCE)
glutReshapeFunc(self.resize)
glutDisplayFunc(self.display)
glutKeyboardFunc(self.keyboardHandler)
glutSpecialFunc(self.funcKeydHandler)
if not test:
glutMainLoop()
else:
self.display()
self.resize(100, 100)
def init_shaders(self):
2020-11-08 10:20:23 +01:00
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])
2020-11-30 19:15:08 +01:00
self.depth_program[self.normal_program[key]] = Spotlight.getDepthProgram(self.vertex_shader_id,
key.GeometryShaderId)
2020-11-08 10:20:23 +01:00
def draw_world(self):
2020-11-08 10:20:23 +01:00
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))
2021-12-20 17:21:46 +01:00
colors = {}
for plate in range(int(np.max(self.world_provider.world.plates))):
colors[plate + 1] = (random.randint(0, 100) / 100.0,
random.randint(0, 100) / 100.0,
random.randint(0, 100) / 100.0)
for x_pos in range(0, 100):
for y_pos in range(0, 100):
for z_pos in range(0, 1):
if self.world_provider.world.plates[x_pos, y_pos] == -1:
r, g, b, = 0, 0, 1 #0.5, 0.5, 0.5
else:
r, g, b = colors[int(self.world_provider.world.plates[x_pos, y_pos])]
self.world_provider.world.set_color(x_pos, y_pos, z_pos, r, g, b)
2020-11-08 10:20:23 +01:00
self.projMatrix = perspectiveMatrix(45.0, 400 / 400, 0.01, MAX_DISTANCE)
self.rx = self.cx = self.cy = 0
self.opening = 45
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)
2020-11-30 19:15:08 +01:00
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))
2020-11-08 10:20:23 +01:00
glFlush()
glutSwapBuffers()
2022-08-12 15:48:30 +02:00
# print('fps', 1.0 / (time.time() - self.time))
2020-11-08 10:20:23 +01:00
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
2020-12-12 10:32:27 +01:00
if key == b'+':
self.state = (self.state +1) % 3
2020-11-08 10:20:23 +01:00
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)
2020-11-30 19:15:08 +01:00
2020-11-08 10:20:23 +01:00
if __name__ == '__main__':
client = Client(pos=[-50, -50, -200])