def setup(self): super(GameControllerNode, self).setup() # set up window = WindowNode(name='window', parent=self) window.open() window.make_context_current() gl.init() err = gl.getError() if err: print("WINDOW OPEN ERROR:", err) scene = SceneNode(name='scene', parent=window) # scenenode.SceneNode(name='scene') debugdraw_renderer = debugdraw.RendererNode(name='debugdraw_renderer', parent=scene) sprite_renderer = spritenode.RendererNode(name="sprite_renderer", parent=scene) camera_transform = transformnode.TransformNode3D(name='camera_transform', parent=scene, m=Mat4.Translation(Vec3(0.0, 0.0, 3.0))) camera = debugdraw.CameraNode(name='camera', parent=camera_transform) camera.make_current() camera_controller = CameraController(input_map=InputMap(), parent=camera_transform) grid = debugdraw.ShapeNode.Grid(1.0, 100, 100, name='grid', parent=scene) aabb = AABB3() aabb.include_point(Vec3(0.0, 0.0, 0.0)) aabb.include_point(Vec3(1.0, 2.0, 3.0)) box = debugdraw.ShapeNode.AABB3(aabb, parent=scene, mode=gl.TRIANGLES) window.on('key', self.key_callback) gl.enable(gl.DEPTH_TEST) gl.enable(gl.BLEND) gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
def step(self): window = self.get_node('/window') scene = self.get_node('/window/scene') sprite_renderer = self.get_node('/window/scene/sprite_renderer') debugdraw_renderer = self.get_node('/window/scene/debugdraw_renderer') if window.should_close(): sys.exit() # trigger the callbacks glfw.pollEvents() window.make_context_current() framebuffer_width, framebuffer_height = window.get_framebuffer_size() gl.viewport(0, 0, framebuffer_width, framebuffer_height) gl.clearColor(0.2, 0.3, 0.3, 1.0) gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT) gl.enable(gl.BLEND) gl.enable(gl.DEPTH_TEST) # sprite_renderer.draw() gl.disable(gl.BLEND) gl.disable(gl.DEPTH_TEST) scene.emit('predraw') debugdraw_renderer.draw() # draw the debug draw scene on top of the other stuff. scene.emit('postdraw') scene.step() #print(scene.get_node('transform').position, scene.get_node('transform').angle) window.swap_buffers()
def setup(self): super(GameControllerNode, self).setup() # set up window = WindowNode(name='window', parent=self) window.open() window.make_context_current() gl.init() err = gl.getError() if err: print("WINDOW OPEN ERROR:", err) scene = physicsnode.SceneNode(name='scene', parent=window) # scenenode.SceneNode(name='scene') debugdraw_renderer = debugdraw.RendererNode(name='debugdraw_renderer', parent=scene) sprite_renderer = spritenode.RendererNode(name="sprite_renderer", parent=scene) camera_transform = transformnode.TransformNode3D(name='camera_transform', parent=scene, m=Mat4.Translation(Vec3(0.0, 0.0, 3.0))) camera = debugdraw.CameraNode(name='camera', parent=camera_transform) camera.make_current() # camera_controller = CameraController(input_map=InputMap(), parent=camera_transform) # create_wheelchair_guy(scene) create_ship(scene) window.on('key', self.key_callback) gl.enable(gl.DEPTH_TEST) gl.enable(gl.BLEND) gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
def setup(self): super(GameControllerNode, self).setup() # set up window = WindowNode(name='window', parent=self) window.open() window.make_context_current() gl.init() err = gl.getError() if err: print("WINDOW OPEN ERROR:", err) scene = SceneNode(name='scene', parent=window) # scenenode.SceneNode(name='scene') debugdraw_renderer = debugdraw.RendererNode(name='debugdraw_renderer', parent=scene) sprite_renderer = spritenode.RendererNode(name="sprite_renderer", parent=scene) camera_transform = transformnode.TransformNode3D(name='camera_transform', parent=scene, m=Mat4.Translation(Vec3(0.0, 0.0, 3.0))) camera = debugdraw.CameraNode(name='camera', parent=camera_transform) camera.make_current() # camera_controller = CameraController(input_map=InputMap(), parent=camera_transform) window.on('key', self.key_callback) gl.enable(gl.DEPTH_TEST) gl.enable(gl.BLEND) gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) updater = BoundsUpdater(parent=scene, name='updater') b0 = BodyNode(position=(0.0, -1.0), velocity=(0.0, 0.1), angle=0.0, angular_velocity=0.0, name="body0", parent=scene) b1 = BodyNode(position=(0.0, 1.0), velocity=(0.0, -0.1), angle=0.0, angular_velocity=0.0, name="body1", parent=scene) shape = CircleShapeNode(radius=0.1, center=(0.0, 0.0), name='shap0', parent=b0) shape_debugdraw = debugdraw.ShapeNode.Circle(radius=0.1, center=shape.center, nverts=8, name='draw_shape0', parent=shape) shape = CircleShapeNode(radius=0.1, center=(0.0, 0.0), name='shape1', parent=b1) shape_debugdraw = debugdraw.ShapeNode.Circle(radius=0.1, center=shape.center, nverts=8, name='draw_shape1', parent=shape) return # random scene NVERTS = 8 for i in range(5): ANGULAR_VELOCITY = 2.0 body = BodyNode( position=(random.uniform(-1.0, 1.0), random.uniform(-1.0, 1.0)), velocity=(random.uniform(-0.1, 0.1), random.uniform(-0.1, 0.1)), angle=random.uniform(-math.pi, math.pi), angular_velocity=random.uniform(-ANGULAR_VELOCITY*math.pi, ANGULAR_VELOCITY*math.pi), name='body%s' % i, parent=scene ) for j in range(3): if random.uniform(0.0, 1.0) < 1.0: shape = CircleShapeNode(radius=0.1, center=(random.uniform(-0.2, 0.2), random.uniform(-0.2, 0.2)), name='shape%i'%j, parent=body) shape_debugdraw = debugdraw.ShapeNode.Circle(radius=0.1, center=shape.center, nverts=NVERTS, name='draw_shape%i'%j, parent=shape) else: transform = Transform(Vec2(random.uniform(-0.2, 0.2), random.uniform(-0.2, 0.2)), random.uniform(-math.pi, math.pi)) w = random.uniform(0.1, 0.2) * 0.5 h = random.uniform(0.1, 0.2) * 0.5 vertices = [Vec2(w, h), Vec2(-w, h), Vec2(-w, -h), Vec2(w, -h)] radius = 0.1 nverts = 20 step = math.pi * 2.0 / nverts center = Vec2() #vertices = [Vec2(math.cos(step*i)*radius+center.x, math.sin(step*i)*radius+center.y) for i in range(nverts)] vertices = [transform.apply(v) for v in vertices] shape = PolygonShapeNode(vertices, name='shape%i'%j, parent=body) m = math.pi * radius * radius print("M:", shape.compute_mass(), m, m * 0.5 * math.pi * radius * radius) color = (1.0, 1.0, 1.0) #draw_vertices = [(Vec3(v.x, v.y, 0.0), color) for v in vertices] draw_vertices = [] for i, v in enumerate(vertices): v0 = vertices[(i-1)%len(vertices)] draw_vertices.append((Vec3(v0.x, v0.y, 0.0), color)) draw_vertices.append((Vec3(v.x, v.y, 0.0), color)) shape_debugdraw = debugdraw.ShapeNode(vertices=draw_vertices, name='draw_shape%i'%j, parent=body)
def main(): glfw.setErrorCallback(error_callback) glfw.init() glfw.windowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.windowHint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.windowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) glfw.windowHint(glfw.RESIZABLE, gl.FALSE) glfw.windowHint(glfw.OPENGL_FORWARD_COMPAT, 1) window = glfw.createWindow(WIDTH, HEIGHT, "LearnOpenGL") if window is None: # print('could not open window.') glfw.terminate() sys.exit() cursor = Vec2() window_size = Vec2(WIDTH, HEIGHT) ui = EventEmitter() def mouse_move_callback(window, x, y): nonlocal cursor # print('mouse move:', window, x, y) cursor = Vec2(x, window_size.y - y) ui.emit('mouse_move', window, cursor) def mouse_button_callback(window, button, action, mods): print('mouse button:', window, button, action, mods) ui.emit('mouse_button', window, button, action, mods) def window_size_callback(window, width, height): nonlocal window_size window_size.x = width window_size.y = height window.makeContextCurrent() # window.setInputMode(glfw.CURSOR, glfw.CURSOR_DISABLED) window.setKeyCallback(key_callback) window.setMouseButtonCallback(mouse_button_callback) window.setCursorPosCallback(mouse_move_callback) window.setWindowSizeCallback(window_size_callback) gl.init() err = gl.getError() if err: print("WINDOW OPEN ERROR:", err) # pre game-loop initialization scene = Scene() # construct the triangle triangle_points = Vector(Vec3) triangle_points.append(Vec3(-0.5, -0.5, 0.0)) triangle_points.append(Vec3( 0.5, -0.5, 0.0)) triangle_points.append(Vec3(-0.5, 0.5, 0.0)) triangle_indices = Vector(c_ubyte) triangle_indices.append(0) triangle_indices.append(1) triangle_indices.append(2) triangle_attribs = BufferAttribs(sizeof(Vec3)) triangle_attribs.add(BufferAttribs.POSITION_INDEX, 3, gl.FLOAT, gl.FALSE, 0) triangle_shader = ShaderProgram(VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE) triangle_draw_call = DrawCall(gl.UNSIGNED_BYTE, gl.LINE_LOOP, 0, len(triangle_indices)) triangle_material = {} triangle_mesh = Mesh(triangle_shader, triangle_draw_call, triangle_material) triangle_model = Model(triangle_indices.get_data(), triangle_points.get_data(), triangle_attribs, [triangle_mesh], InstanceData, ItemInstance) triangle_instance = scene.add(triangle_model, InstanceData(model_matrix=Mat4.Identity(), base_color=Vec3(1.0, 0.0, 0.0))) # construct the reticle RETICLE_SIZE = 0.01 reticle_points = Vector(Vec3) reticle_points.append(Vec3(-RETICLE_SIZE * 0.5, -RETICLE_SIZE * 0.5, 0.0)) reticle_points.append(Vec3(-RETICLE_SIZE * 0.5, RETICLE_SIZE * 0.5, 0.0)) reticle_points.append(Vec3( RETICLE_SIZE * 0.5, RETICLE_SIZE * 0.5, 0.0)) reticle_points.append(Vec3( RETICLE_SIZE * 0.5, -RETICLE_SIZE * 0.5, 0.0)) reticle_indices = Vector(c_ubyte) reticle_indices.append(0) reticle_indices.append(1) reticle_indices.append(2) reticle_indices.append(3) reticle_attribs = BufferAttribs(sizeof(Vec3)) reticle_attribs.add(BufferAttribs.POSITION_INDEX, 3, gl.FLOAT, gl.FALSE, 0) reticle_shader = triangle_shader reticle_draw_call = DrawCall(gl.UNSIGNED_BYTE, gl.LINE_LOOP, 0, len(reticle_indices)) reticle_material = {} reticle_mesh = Mesh(reticle_shader, reticle_draw_call, reticle_material) reticle_model = Model(reticle_indices.get_data(), reticle_points.get_data(), reticle_attribs, [reticle_mesh], InstanceData, ItemInstance) # construct the AABB model aabb = AABB3() aabb.include_point(Vec3(0.0, 0.0, 0.0)) aabb.include_point(Vec3(0.2, 0.2, 0.2)) aabb_points = Vector(Vec3) aabb_points.append(Vec3(aabb.min.x, aabb.min.y, aabb.min.z)) aabb_points.append(Vec3(aabb.max.x, aabb.min.y, aabb.min.z)) aabb_points.append(Vec3(aabb.min.x, aabb.max.y, aabb.min.z)) aabb_points.append(Vec3(aabb.max.x, aabb.max.y, aabb.min.z)) aabb_points.append(Vec3(aabb.min.x, aabb.min.y, aabb.max.z)) aabb_points.append(Vec3(aabb.max.x, aabb.min.y, aabb.max.z)) aabb_points.append(Vec3(aabb.min.x, aabb.max.y, aabb.max.z)) aabb_points.append(Vec3(aabb.max.x, aabb.max.y, aabb.max.z)) # lines aabb_indices = Vector(c_ubyte) aabb_indices.append(0) aabb_indices.append(1) aabb_indices.append(2) aabb_indices.append(3) aabb_indices.append(4) aabb_indices.append(5) aabb_indices.append(6) aabb_indices.append(7) aabb_indices.append(0) aabb_indices.append(4) aabb_indices.append(1) aabb_indices.append(5) aabb_indices.append(2) aabb_indices.append(6) aabb_indices.append(3) aabb_indices.append(7) aabb_indices.append(0) aabb_indices.append(2) aabb_indices.append(1) aabb_indices.append(3) aabb_indices.append(4) aabb_indices.append(6) aabb_indices.append(5) aabb_indices.append(7) aabb_attribs = BufferAttribs(sizeof(Vec3)) aabb_attribs.add(BufferAttribs.POSITION_INDEX, 3, gl.FLOAT, gl.FALSE, 0) aabb_shader = triangle_shader aabb_draw_call = DrawCall(gl.UNSIGNED_BYTE, gl.LINES, 0, len(aabb_indices)) aabb_material = {} aabb_mesh = Mesh(aabb_shader, aabb_draw_call, aabb_material) aabb_model = Model(aabb_indices.get_data(), aabb_points.get_data(), aabb_attribs, [aabb_mesh], InstanceData, ItemInstance) # reticle_instances = ModelInstances(reticle_model, InstanceData, ItemInstance) reticle_instance = scene.add(reticle_model, InstanceData(model_matrix=Mat4.Identity())) # aabb_instances = ModelInstances(aabb_model, InstanceData, ItemInstance) aabb_instance = scene.add(aabb_model, InstanceData(model_matrix=Mat4.Identity())) #reticle_instance.set_enabled(False) ray_scene = RayScene() # ui.on('mouse_move' lambda window, cursor: scene.mouse_move(camera, viewport, cursor)) camera = Camera(scene=scene) framebuffer_width, framebuffer_height = window.getFramebufferSize() # camera.projection_matrix = Mat4.Identity() camera.projection_matrix = Mat4.Perspective(45.0, framebuffer_width/framebuffer_height, 0.1, 100.0) camera.view_matrix = Mat4.Identity() t0 = time.perf_counter() frames = 0 while not window.shouldClose(): glfw.pollEvents() gl.enable(gl.DEPTH_TEST) gl.depthFunc(gl.LEQUAL) gl.enable(gl.CULL_FACE) gl.cullFace(gl.BACK) t = time.perf_counter() err = gl.getError() if err: print("ERROR:", err) # render the frame framebuffer_width, framebuffer_height = window.getFramebufferSize() # camera.view_matrix = Mat4.LookAt(Vec3(math.cos(time.clock() * 0.1), 1.0, math.sin(time.clock() * 0.1)) *15.0, Vec3(0.0, 0.0, 0.0), Vec3(0.0, 1.0, 0.0)) camera.view_matrix = Mat4.LookAt( Vec3(math.cos(time.clock() * 0.1), 1.0, math.sin(time.clock() * 0.1)) *2.0, Vec3(0.0, 0.0, 0.0), Vec3(0.0, 1.0, 0.0) ) viewport = (0, 0, framebuffer_width, framebuffer_height) camera.render_to_viewport(viewport) # not sure if this is correct when the viewport size doesn't match the framebuffer size. ray_origin, ray_direction = camera.get_ray(cursor, viewport) # print(ray) result = raytri.intersect_triangle(ray_origin, ray_direction, *triangle_points) if result: t, u, v = result hit_pos = triangle_points[0] * (1.0 - u - v) + triangle_points[1] * u + triangle_points[2] * v reticle_instance.set_enabled(True) reticle_instance.model_matrix = Mat4.Translation(hit_pos) reticle_instance.base_color = Vec3(1.0, 1.0, 1.0) triangle_instance.base_color = Vec3(1.0, 0.0, 0.0) else: reticle_instance.set_enabled(False) triangle_instance.base_color = Vec3(1.0, 1.0, 1.0) reticle_instance.base_color = Vec3(0.0, 0.0, 0.0) result = raytri.hit_aabb(ray_origin, ray_direction, aabb) if result: aabb_instance.base_color = Vec3(1.0, 0.0, 0.0) else: aabb_instance.base_color = Vec3(1.0, 1.0, 1.0) # print((ray_origin, ray_direction), result) # update buffers scene.update_instances() window.swapBuffers() frames += 1 if not frames % 100: print("FRAME RATE:", float(frames)/(time.perf_counter() - t0))
def main(): glfw.setErrorCallback(error_callback) glfw.init() glfw.windowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.windowHint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.windowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) # glfw.windowHint(glfw.RESIZABLE, gl.FALSE) glfw.windowHint(glfw.OPENGL_FORWARD_COMPAT, 1) window = glfw.createWindow(WIDTH, HEIGHT, "LearnOpenGL") if window is None: print('could not open window.') glfw.terminate() sys.exit() inputMap = InputMap() window.makeContextCurrent() window.setKeyCallback(inputMap.key_callback) window.setCursorPosCallback(inputMap.mouse_callback) #window.setScrollCallback(inputMap.scroll_callback) window.setInputMode(glfw.CURSOR, glfw.CURSOR_DISABLED) gl.init() err = gl.getError() if err: print("WINDOW OPEN ERROR:", err) camera = Camera(position=Vec3(0.0, 0.0, 3.0)) lastX = 400 lastY = 300 firstMouse = True deltaTime = 0.0 lastFrame = 0.0 gl.enable(gl.DEPTH_TEST) lampShaderProgram = Shader(LAMP_VERTEX_SHADER_SOURCE, LAMP_FRAGMENT_SHADER_SOURCE) lightingShaderProgram = Shader(LIGHTING_VERTEX_SHADER_SOURCE, LIGHTING_FRAGMENT_SHADER_SOURCE) lightingShaderProgram.use() lightVAO, containerVAO = gl.genVertexArrays(2) vbo = gl.genBuffers(1)[0] # 1. Bind Vertex Array Object gl.bindVertexArray(containerVAO) # 2. Copy our vertices array in a buffer for OpenGL to use gl.bindBuffer(gl.ARRAY_BUFFER, vbo) gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW) # Position attribute gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, sizeof(Vertex), Vertex.position.offset) gl.enableVertexAttribArray(0) # Normal attribute gl.vertexAttribPointer(1, 3, gl.FLOAT, gl.FALSE, sizeof(Vertex), Vertex.normal.offset) gl.enableVertexAttribArray(1) # 4. Unbind the VAO gl.bindVertexArray(0) # 1. Bind Vertex Array Object gl.bindVertexArray(lightVAO) # Position attribute gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, sizeof(Vertex), Vertex.position.offset) gl.enableVertexAttribArray(0) # 4. Unbind the VAO gl.bindVertexArray(0) # 4. unbind the vbo gl.bindBuffer(gl.ARRAY_BUFFER, 0) lightPos = Vec3(1.2, 1.0, 2.0) while not window.shouldClose(): inputMap.begin_frame() glfw.pollEvents() input = inputMap.get_input() camera.processInput(input, 1.0/30.0) framebuffer_width, framebuffer_height = window.getFramebufferSize() gl.viewport(0, 0, framebuffer_width, framebuffer_height) gl.clearColor(0.2, 0.3, 0.3, 1.0) gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT) lightingShaderProgram.use() lightingShaderProgram.uniforms.objectColor = Vec3(1.0, 0.5, 0.31) lightingShaderProgram.uniforms.lightColor = Vec3(1.0, 0.5, 1.0) lightingShaderProgram.uniforms.lightPos = lightPos lightingShaderProgram.uniforms.viewPos = camera.position # create transformations view = camera.getViewMatrix() projection = Mat4.Perspective(45.0, float(WIDTH) / float(HEIGHT), 0.1, 100.0) # assign the transformations lightingShaderProgram.uniforms.view = view lightingShaderProgram.uniforms.projection = projection # draw the container gl.bindVertexArray(containerVAO) model = Mat4.Identity() lightingShaderProgram.uniforms.model = model gl.drawArrays(gl.TRIANGLES, 0, 36) gl.bindVertexArray(0) # draw the lamp lampShaderProgram.use() lampShaderProgram.uniforms.view = view lampShaderProgram.uniforms.projection = projection model = Mat4.Translation(lightPos) * Mat4.Scale(0.2) lampShaderProgram.uniforms.model = model gl.bindVertexArray(lightVAO) gl.drawArrays(gl.TRIANGLES, 0, 36) gl.bindVertexArray(0) window.swapBuffers() lampShaderProgram.delete() lightingShaderProgram.delete() gl.deleteVertexArrays([containerVAO, lightVAO]) gl.deleteBuffers([vbo])
def main(): global lastFrame, planeVAO, planeVBO # Init GLFW glfw.setErrorCallback(error_callback) glfw.init() glfw.windowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.windowHint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.windowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) # glfw.windowHint(glfw.RESIZABLE, gl.FALSE) glfw.windowHint(glfw.OPENGL_FORWARD_COMPAT, 1) window = glfw.createWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL") if window is None: print('could not open window.') glfw.terminate() sys.exit() inputMap = InputMap() window.makeContextCurrent() window.setKeyCallback(inputMap.key_callback) window.setCursorPosCallback(inputMap.mouse_callback) #window.setScrollCallback(inputMap.scroll_callback) window.setInputMode(glfw.CURSOR, glfw.CURSOR_DISABLED) # some versions of glfw cause an opengl error when creating a window, make sure that's ignored. gl.init() err = gl.getError() if err: print("WINDOW OPEN ERROR:", err) # Define the viewport dimensions VP_WIDTH, VP_HEIGHT = window.getFramebufferSize() gl.viewport(0, 0, VP_WIDTH, VP_HEIGHT) # Setup some OpenGL options gl.enable(gl.DEPTH_TEST); # Setup and compile our shaders shaderProgram = Shader(SHADOW_MAPPING_VERT, SHADOW_MAPPING_FRAG); simpleDepthShader = Shader(SHADOW_MAPPING_DEPTH_VERT, SHADOW_MAPPING_DEPTH_FRAG); debugDepthQuad = Shader(DEBUG_QUAD_VERT, DEBUG_QUAD_FRAG); # Set texture samples shaderProgram.use(); # shaderProgram.uniforms.diffuseTexture = 0 # shaderProgram.uniforms.shadowMap = 1 # print(dir(Vertex)) planeVertices = (Vertex * 6)( # Positions # Normals # Texture Coords (( 25.0, -0.5, 25.0), (0.0, 1.0, 0.0), (25.0, 0.0)), ((-25.0, -0.5, -25.0), (0.0, 1.0, 0.0), ( 0.0, 25.0)), ((-25.0, -0.5, 25.0), (0.0, 1.0, 0.0), ( 0.0, 0.0)), (( 25.0, -0.5, 25.0), (0.0, 1.0, 0.0), (25.0, 0.0)), (( 25.0, -0.5, -25.0), (0.0, 1.0, 0.0), (25.0, 25.0)), ((-25.0, -0.5, -25.0), (0.0, 1.0, 0.0), ( 0.0, 25.0)) ) # Setup plane VAO planeVAO = gl.genVertexArrays(1)[0] planeVBO = gl.genBuffers(1)[0] gl.bindVertexArray(planeVAO) gl.bindBuffer(gl.ARRAY_BUFFER, planeVBO) gl.bufferData(gl.ARRAY_BUFFER, bytes(planeVertices), gl.STATIC_DRAW) gl.enableVertexAttribArray(0) gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, sizeof(Vertex), Vertex.position.offset) gl.enableVertexAttribArray(1) gl.vertexAttribPointer(1, 3, gl.FLOAT, gl.FALSE, sizeof(Vertex), Vertex.normal.offset) gl.enableVertexAttribArray(2) gl.vertexAttribPointer(2, 2, gl.FLOAT, gl.FALSE, sizeof(Vertex), Vertex.texcoord.offset) gl.bindVertexArray(0) # Light source lightPos = Vec3(-2.0, 4.0, -1.0) # Load textures woodTexture = load_texture("learningopengl/resources/textures/wood.png") # Configure depth map FBO SHADOW_WIDTH = SHADOW_HEIGHT = 4096 depthMapFBO = gl.genFramebuffers(1)[0] # - Create depth texture depthMap = gl.genTextures(1)[0] gl.bindTexture(gl.TEXTURE_2D, depthMap) gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, gl.DEPTH_COMPONENT, gl.FLOAT, None) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_BORDER) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_BORDER) borderColor = Vec4(1.0, 1.0, 1.0, 1.0) gl.texParameterfv(gl.TEXTURE_2D, gl.TEXTURE_BORDER_COLOR, borderColor) gl.bindFramebuffer(gl.FRAMEBUFFER, depthMapFBO) gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthMap, 0) gl.drawBuffer(gl.NONE) gl.readBuffer(gl.NONE); gl.bindFramebuffer(gl.FRAMEBUFFER, 0); gl.clearColor(0.1, 0.1, 0.1, 1.0) # Game loop while not window.shouldClose(): # Set frame time currentFrame = time.perf_counter() deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; # Check and call events inputMap.begin_frame() glfw.pollEvents() input = inputMap.get_input() camera.processInput(input, 1.0/30.0) # Change light position over time lightPos.z = math.cos(time.perf_counter()) * 2.0 # 1. Render depth of scene to texture (from light's perspective) # - Get light projection/view matrix. near_plane = 1.0 far_plane = 7.5 lightProjection = Mat4.Ortho(-10.0, 10.0, -10.0, 10.0, near_plane, far_plane) # lightProjection = glm::perspective(45.0f, (GLfloat)SHADOW_WIDTH / (GLfloat)SHADOW_HEIGHT, near_plane, far_plane); // Note that if you use a perspective projection matrix you'll have to change the light position as the current light position isn't enough to reflect the whole scene. lightView = Mat4.LookAt(lightPos, Vec3(0.0, 0.0, 0.0), Vec3(1.0, 1.0, 1.0)) lightSpaceMatrix = lightProjection * lightView; # - now render scene from light's point of view simpleDepthShader.use() simpleDepthShader.uniforms.lightSpaceMatrix = lightSpaceMatrix # glUniformMatrix4fv(glGetUniformLocation(simpleDepthShader.Program, "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix)); gl.viewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT) gl.bindFramebuffer(gl.FRAMEBUFFER, depthMapFBO) gl.clear(gl.DEPTH_BUFFER_BIT); RenderScene(simpleDepthShader); gl.bindFramebuffer(gl.FRAMEBUFFER, 0) # 2. Render scene as normal gl.viewport(0, 0, VP_WIDTH, VP_HEIGHT) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) shaderProgram.use() # TODO: use zoon projection = Mat4.Perspective(45.0, float(SCR_WIDTH) / float(SCR_HEIGHT), 0.1, 100.0) view = camera.getViewMatrix() shaderProgram.uniforms.projection = projection shaderProgram.uniforms.view = view shaderProgram.uniforms.lightPos = lightPos shaderProgram.uniforms.viewPos = camera.position shaderProgram.uniforms.lightSpaceMatrix = lightSpaceMatrix shaderProgram.uniforms.shadows = 1 shaderProgram.uniforms.diffuseTexture = woodTexture shaderProgram.uniforms.shadowMap = depthMap RenderScene(shaderProgram) # 3. DEBUG: visualize depth map by rendering it to plane debugDepthQuad.use() # these are not actually used. #debugDepthQuad.uniforms.near_plane = near_plane #debugDepthQuad.uniforms.far_plane = far_plane debugDepthQuad.uniforms.depthMap = depthMap # RenderQuad() # uncomment this line to see depth map # Swap the buffers window.swapBuffers() return 0
def main(): glfw.setErrorCallback(error_callback) glfw.init() glfw.windowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.windowHint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.windowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) # glfw.windowHint(glfw.RESIZABLE, gl.FALSE) glfw.windowHint(glfw.OPENGL_FORWARD_COMPAT, 1) window = glfw.createWindow(WIDTH, HEIGHT, "LearnOpenGL") if window is None: print('could not open window.') glfw.terminate() sys.exit() window.makeContextCurrent() # window.setInputMode(glfw.CURSOR, glfw.CURSOR_DISABLED) window.setKeyCallback(key_callback) gl.init() err = gl.getError() if err: print("WINDOW OPEN ERROR:", err) # set up the first model armored_plate_data = objloader.load_obj(os.path.join("springtangent-model-files", "armored_plate.75.75.decimation_test7.obj")) armored_plate_model = Model.FromJSON(armored_plate_data, InstanceData, PlateInstance) plane_plate_data = objloader.load_obj(os.path.join("springtangent-model-files", "plane_plate.75.75.decimation_test.00.obj")) plane_plate_model = Model.FromJSON(plane_plate_data, InstanceData, PlateInstance) angled_plate_data = objloader.load_obj(os.path.join("springtangent-model-files", "angled_plate_plane.75.25..25.decimated.obj")) angled_plate_model = Model.FromJSON(angled_plate_data, InstanceData, PlateInstance) models =[armored_plate_model, plane_plate_model, angled_plate_model] scene = Scene() camera = Camera(name='camera', parent=scene) # set up the data for the instances. # 30 x 30 array of tiles, which are randomly selected among the above models instances = {} transforms = {} n = 30 for i in range(n): for j in range(n): r = random.choice(range(4)) transform = Mat4.Translation(Vec3((i-n//2) * 2, 0.0, (j-n//2) * 2)) * Mat4.Rotation(math.pi/2.0 * r, Vec3(0.0, 1.0, 0.0)) transform_node = TransformNode3D(name='tranform.%i.%i' % (i, j), parent=scene, m=transform) transforms[i,j] = transform_node instance = ModelInstance(random.choice(models), model_matrix=transform, parent=transform_node, name='model.%i.%i' % (i,j)) instance.model_matrix = transform instances[i,j] = instance instance.r = r framebuffer_width, framebuffer_height = window.getFramebufferSize() camera.projection_matrix = Mat4.Perspective(45.0, framebuffer_width/framebuffer_height, 0.1, 100.0) camera.view_matrix = Mat4.LookAt(Vec3(math.cos(time.clock()), 1.0, math.sin(time.clock())) *15.0, Vec3(0.0, 0.0, 0.0), Vec3(0.0, 1.0, 0.0)) t0 = time.perf_counter() frames = 0 while not window.shouldClose(): glfw.pollEvents() gl.enable(gl.DEPTH_TEST) gl.depthFunc(gl.LEQUAL) gl.enable(gl.CULL_FACE) gl.cullFace(gl.BACK) t = time.perf_counter() framebuffer_width, framebuffer_height = window.getFramebufferSize() camera.view_matrix = Mat4.LookAt(Vec3(math.cos(time.clock() * 0.1), 1.0, math.sin(time.clock() * 0.1)) *15.0, Vec3(0.0, 0.0, 0.0), Vec3(0.0, 1.0, 0.0)) viewport = (0, 0, framebuffer_width, framebuffer_height) camera.render_to_viewport(viewport) err = gl.getError() if err: print("ERROR:", err) if TEST_ANIMATION: for i in range(n): for j in range(n): instance = instances[i,j] enabled = math.sin(i+j+t*10.0) > -0.8 instance.set_enabled(enabled) if enabled: transform_node = transforms[i,j] y = (math.sin(t+i) + math.cos(t+j)) * 0.25 transform = Mat4.Translation(Vec3((i-n//2) * 2, y, (j-n//2) * 2)) * Mat4.Rotation(math.pi/2.0 * instance.r, Vec3(0.0, 1.0, 0.0)) transform_node.local_matrix = transform # TODO: this should be done automatically in nodetree.graphics.Scene.update_instances instance.instance.model_matrix = transform_node.to_mat4() scene.update_instances() window.swapBuffers() frames += 1 if not frames % 100: print("FRAME RATE:", float(frames)/(time.perf_counter() - t0))
def main(): draw_mode = 1 global lastFrame, planeVAO, planeVBO # Init GLFW glfw.setErrorCallback(error_callback) glfw.init() glfw.windowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.windowHint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.windowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) # glfw.windowHint(glfw.RESIZABLE, gl.FALSE) glfw.windowHint(glfw.OPENGL_FORWARD_COMPAT, 1) window = glfw.createWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL") if window is None: print('could not open window.') glfw.terminate() sys.exit() inputMap = InputMap() window.makeContextCurrent() window.setKeyCallback(inputMap.key_callback) window.setCursorPosCallback(inputMap.mouse_callback) #window.setScrollCallback(inputMap.scroll_callback) window.setInputMode(glfw.CURSOR, glfw.CURSOR_DISABLED) # some versions of glfw cause an opengl error when creating a window, make sure that's ignored. gl.init() err = gl.getError() if err: print("WINDOW OPEN ERROR:", err) # Define the viewport dimensions VP_WIDTH, VP_HEIGHT = window.getFramebufferSize() gl.viewport(0, 0, VP_WIDTH, VP_HEIGHT) # Setup some OpenGL options gl.enable(gl.DEPTH_TEST); #Setup and compile our shaders shaderGeometryPass = Shader(G_BUFFER_VERT, G_BUFFER_FRAG); shaderLightingPass = Shader(DEFERRED_SHADING_VERT, DEFERRED_SHADING_FRAG); shaderLightBox = Shader(DEFERRED_LIGHT_BOX_VERT, DEFERRED_LIGHT_BOX_FRAG); gPosition, gNormal, gAlbedoSpec = gl.genTextures(3) shaderLightingPass.use() shaderLightingPass.uniforms.gPosition = gNormal shaderLightingPass.uniforms.gNormal = gPosition shaderLightingPass.uniforms.gAlbedoSpec = gAlbedoSpec # "learningopengl/resources/objects/cyborg/cyborg.obj" cyborg = Model("learningopengl/resources/objects/cyborg/cyborg.obj") objectPositions = [ Vec3(-3.0, -3.0, -3.0), Vec3( 0.0, -3.0, -3.0), Vec3( 3.0, -3.0, -3.0), Vec3(-3.0, -3.0, 0.0), Vec3( 0.0, -3.0, 0.0), Vec3( 3.0, -3.0, 0.0), Vec3(-3.0, -3.0, 3.0), Vec3( 0.0, -3.0, 3.0), Vec3( 3.0, -3.0, 3.0) ] NR_LIGHTS = 32 lightPositions = (Vec3 * NR_LIGHTS)() lightColors = (Vec3 * NR_LIGHTS)() for i in range(NR_LIGHTS): lightPositions[i].x = random.uniform(-3.0, 3.0) lightPositions[i].y = random.uniform(-4.0, 2.0) lightPositions[i].z = random.uniform(-3.0, 3.0) lightColors[i].x = random.uniform(0.5, 1.0) lightColors[i].y = random.uniform(0.5, 1.0) lightColors[i].z = random.uniform(0.5, 1.0) # set up the G-buffer # 3 textures: p # 1. Positions (RGB) # 2. Color (RGB) + Specular (A) # 3. Normal (RGB) gBuffer = gl.genFramebuffers(1)[0] gl.bindFramebuffer(gl.FRAMEBUFFER, gBuffer) # set up the position buffer gl.bindTexture(gl.TEXTURE_2D, gPosition) gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB16F, VP_WIDTH, VP_HEIGHT, 0, gl.RGB, gl.FLOAT, None) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, gPosition, 0) # set up the normal buffer gl.bindTexture(gl.TEXTURE_2D, gNormal); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, VP_WIDTH, VP_HEIGHT, 0, gl.RGB, gl.FLOAT,None) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, gNormal, 0) # set up the color + specular buffer gl.bindTexture(gl.TEXTURE_2D, gAlbedoSpec); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, VP_WIDTH, VP_HEIGHT, 0, gl.RGBA, gl.FLOAT, None) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.TEXTURE_2D, gAlbedoSpec, 0) # - Tell OpenGL which color attachments we'll use (of this framebuffer) for rendering attachments = [gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2] gl.drawBuffers(attachments) # - Create and attach depth buffer (renderbuffer) rboDepth = gl.genRenderbuffers(1)[0] gl.bindRenderbuffer(gl.RENDERBUFFER, rboDepth) gl.renderbufferStorage(gl.RENDERBUFFER,gl.DEPTH_COMPONENT, VP_WIDTH, VP_HEIGHT); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rboDepth) # - Finally check if framebuffer is complete if gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE: print("Framebuffer not complete!") gl.bindFramebuffer(gl.FRAMEBUFFER, 0) gl.clearColor(0.0, 0.0, 0.0, 0.0) # Game loop while not window.shouldClose(): # Set frame time currentFrame = time.perf_counter() deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; # Check and call events inputMap.begin_frame() glfw.pollEvents() input = inputMap.get_input() camera.processInput(input, 1.0/30.0) gl.bindFramebuffer(gl.FRAMEBUFFER, gBuffer) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) # TODO: use camera.zoom # 1. Geometry Pass: render scene's geometry/color data into gbuffer projection = Mat4.Perspective(45.0, float(SCR_WIDTH)/float(SCR_HEIGHT), 0.1, 100.0) view = camera.getViewMatrix() model = Mat4.Identity() shaderGeometryPass.use() shaderGeometryPass.uniforms.projection = projection shaderGeometryPass.uniforms.view = view for objectPosition in objectPositions: model = Mat4.Translation(objectPosition) * Mat4.Scale(0.25) shaderGeometryPass.uniforms.model = model cyborg.draw(shaderGeometryPass) gl.bindFramebuffer(gl.FRAMEBUFFER, 0) gl.polygonMode(gl.FRONT_AND_BACK, gl.FILL) # 2. Lighting Pass: calculate lighting by iterating over a screen filled quad pixel-by-pixel using the gbuffer's content. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); shaderLightingPass.use() shaderLightingPass.uniforms.gPosition = gPosition shaderLightingPass.uniforms.gNormal = gNormal shaderLightingPass.uniforms.gAlbedoSpec = gAlbedoSpec # Also send light relevant uniforms for i, lightPosition in enumerate(lightPositions): shaderLightingPass.uniforms.lights[i].Position = lightPosition shaderLightingPass.uniforms.lights[i].Color = lightColors[i] # Update attenuation parameters and calculate radius constant = 1.0 linear = shaderLightingPass.uniforms.lights[i].Linear = 0.7 quadratic = shaderLightingPass.uniforms.lights[i].Quadratic = 1.8 # Then calculate radius of light volume/sphere lightThreshold = 5.0 # 5 / 256 maxBrightness = max(max(lightColors[i].r, lightColors[i].g), lightColors[i].b) radius = (-linear + math.sqrt(linear * linear - 4 * quadratic * (constant - (256.0 / lightThreshold) * maxBrightness))) / (2 * quadratic) shaderLightingPass.uniforms.lights[i].Radius = radius shaderLightingPass.uniforms.viewPos = camera.position if window.getKey(glfw.KEY_1): draw_mode = 1 if window.getKey(glfw.KEY_2): draw_mode = 2 if window.getKey(glfw.KEY_3): draw_mode = 3 if window.getKey(glfw.KEY_4): draw_mode = 4 if window.getKey(glfw.KEY_5): draw_mode = 5 # print("SETTING DRAW MODE:", draw_mode) try: shaderLightingPass.uniforms.draw_mode = draw_mode except: pass RenderQuad() # 2.5. Copy content of geometry's depth buffer to default framebuffer's depth buffer gl.bindFramebuffer(gl.READ_FRAMEBUFFER, gBuffer); gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, 0); # Write to default framebuffer gl.blitFramebuffer(0, 0, VP_WIDTH, VP_HEIGHT, 0, 0, VP_WIDTH, VP_HEIGHT, gl.DEPTH_BUFFER_BIT, gl.NEAREST); gl.bindFramebuffer(gl.FRAMEBUFFER, 0); # 3. Render lights on top of scene, by blitting shaderLightBox.use() shaderLightBox.uniforms.projection = projection # glUniformMatrix4fv(glGetUniformLocation(shaderLightBox.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); shaderLightBox.uniforms.view = view # glUniformMatrix4fv(glGetUniformLocation(shaderLightBox.Program, "view"), 1, GL_FALSE, glm::value_ptr(view)); for i, lightPosition in enumerate(lightPositions): model = Mat4.Translation(lightPosition) * Mat4.Scale(0.25) shaderLightBox.uniforms.model = model shaderLightBox.uniforms.lightColor = lightColors[i] RenderCube() # Swap the buffers window.swapBuffers() return 0
def main(): glfw.setErrorCallback(error_callback) print("GL:", gl) glfw.init() glfw.windowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.windowHint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.windowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) glfw.windowHint(glfw.RESIZABLE, gl.FALSE) glfw.windowHint(glfw.OPENGL_FORWARD_COMPAT, 1) window = glfw.createWindow(WIDTH, HEIGHT, "LearnOpenGL") if window is None: print('could not open window.') glfw.terminate() sys.exit() window.makeContextCurrent() # window.setInputMode(glfw.CURSOR, glfw.CURSOR_DISABLED) window.setKeyCallback(key_callback) gl.init() print("IN MODULE:", gl.getError) err = gl.getError() if err: print("WINDOW OPEN ERROR:", err) gl.enable(gl.DEPTH_TEST) gl.enable(gl.BLEND) gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) # set up our application nodebuilder = NodeBuilder() # TODO: this stuff should happen automatically. debugdraw.register_with_nodebuilder(nodebuilder) transformnode.register_with_nodebuilder(nodebuilder) physicsnode.register_with_nodebuilder(nodebuilder) # set up scene = physicsnode.SceneNode(name='physics_scene') # scenenode.SceneNode(name='scene') debugdraw_renderer = debugdraw.RendererNode(name='debugdraw_renderer', parent=scene) sprite_renderer = spritenode.RendererNode(name="sprite_renderer", parent=scene) # space = create_wheelchair_guy(scene) # TODO: finish debugging the get_relative_path method... # print("wheel_suspension -> wheel_body", wheel_suspension.get_relative_path(wheel_body)) # print("wheel_suspension -> body", wheel_suspension.get_relative_path(body)) # print("wheel_suspension -> player", wheel_suspension.get_relative_path(player)) # print("wheel_suspension -> player_body", wheel_suspension.get_relative_path(body)) # # print(wheel_suspension.get_node('../../../..')) # assert(wheel_suspension.get_node('..') is wheel) # p = '../../../..' # print("P", wheel_suspension.get_node(p)) # assert(wheel_suspension.get_node(p) is player) # assert(wheel_suspension.get_node('../wheel_body') is wheel_body) # p = '../../../player_body' # print(wheel_suspension.get_node(p)) # assert(wheel_suspension.get_node(p) is body) while not window.shouldClose(): glfw.pollEvents() framebuffer_width, framebuffer_height = window.getFramebufferSize() gl.viewport(0, 0, framebuffer_width, framebuffer_height) gl.clearColor(0.2, 0.3, 0.3, 1.0) gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT) gl.enable(gl.BLEND) gl.enable(gl.DEPTH_TEST) sprite_renderer.draw() gl.disable(gl.BLEND) gl.disable(gl.DEPTH_TEST) debugdraw_renderer.draw() # draw the debug draw scene on top of the other stuff. scene.step(1.0/30.0, iterations=10) #print(scene.get_node('transform').position, scene.get_node('transform').angle) window.swapBuffers()
def main(): glfw.setErrorCallback(error_callback) glfw.init() glfw.windowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.windowHint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.windowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) # glfw.windowHint(glfw.RESIZABLE, gl.FALSE) glfw.windowHint(glfw.OPENGL_FORWARD_COMPAT, 1) if ENABLE_MULTISAMPLE: glfw.windowHint(glfw.SAMPLES, 4) window = glfw.createWindow(WIDTH, HEIGHT, "LearnOpenGL") if window is None: print('could not open window.') glfw.terminate() sys.exit() window.makeContextCurrent() # window.setInputMode(glfw.CURSOR, glfw.CURSOR_DISABLED) window.setKeyCallback(key_callback) gl.init() err = gl.getError() if err: print("WINDOW OPEN ERROR:", err) framebuffer_width, framebuffer_height = window.getFramebufferSize() # Framebuffers framebuffer = gl.genFramebuffers(1)[0] gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); # Create a color attachment texture textureColorbuffer = generateAttachmentTexture(gl.RGB, framebuffer_width, framebuffer_height); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureColorbuffer, 0) # set up the position buffer gPosition = gl.genTextures(1)[0] gl.bindTexture(gl.TEXTURE_2D, gPosition) gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB16F, framebuffer_width, framebuffer_height, 0, gl.RGB, gl.FLOAT, None) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, gPosition, 0) # set up the normal buffer gNormal = gl.genTextures(1)[0] gl.bindTexture(gl.TEXTURE_2D, gNormal) gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB16F, framebuffer_width, framebuffer_height, 0, gl.RGB, gl.FLOAT, None) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.TEXTURE_2D, gNormal, 0) gLight = gl.genTextures(1)[0] gl.bindTexture(gl.TEXTURE_2D, gLight) gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB16F, framebuffer_width, framebuffer_height, 0, gl.RGB, gl.FLOAT, None) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT3, gl.TEXTURE_2D, gLight, 0) # - Tell OpenGL which color attachments we'll use (of this framebuffer) for rendering attachments = [gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2] gl.drawBuffers(attachments) gDepth = gl.genTextures(1)[0] gl.bindTexture(gl.TEXTURE_2D, gDepth) gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH24_STENCIL8, framebuffer_width, framebuffer_height, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, None) # gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB16F, framebuffer_width, framebuffer_height, 0, gl.RGB, gl.FLOAT, None) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, gDepth, 0) # Create a renderbuffer object for depth and stencil attachment (we won't be sampling these) # rbo = gl.genRenderbuffers(1)[0] # gl.bindRenderbuffer(gl.RENDERBUFFER, rbo) # gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, framebuffer_width, framebuffer_height); # Use a single renderbuffer object for both a depth AND stencil buffer. # gl.bindRenderbuffer(gl.RENDERBUFFER, 0); # gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo) # Now actually attach it # Now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now if gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE: print("ERROR::FRAMEBUFFER:: Framebuffer is not complete!") gl.bindFramebuffer(gl.FRAMEBUFFER, 0) deferred_textures = { 'screenTexture': textureColorbuffer, 'normalTexture': gNormal, 'positionTexture': gPosition, 'lightTexture': gLight, 'depthTexture': gDepth } scene = Scene() camera = Camera(scene=scene) quad_scene = Scene() quad_camera = Camera(scene=quad_scene) light_scene = Scene() light_camera = Camera(scene=light_scene, clear=0) light_camera.clear = gl.COLOR_BUFFER_BIT light_camera.clear_color = (0.0, 0.0, 0.0, 0.0) light_camera.projection_matrix = camera.projection_matrix = Mat4.Perspective(45.0, framebuffer_width/framebuffer_height, 0.1, 100.0) light_camera.view_matrix = camera.view_matrix = Mat4.LookAt(Vec3(math.cos(time.clock()), 1.0, math.sin(time.clock())) *15.0, Vec3(0.0, 0.0, 0.0), Vec3(0.0, 1.0, 0.0)) # light volume model light_volume_data = objloader.load_obj(os.path.join("springtangent-model-files", "lightsphere", "lightsphere.obj"), calculate_normals=True) light_volume_model = Model.FromJSON(light_volume_data, PointLightInstanceData, PlateInstance) # other models armored_plate_data = objloader.load_obj(os.path.join("springtangent-model-files", "armored_plate.75.75.decimation_test7.obj"), calculate_normals=True) armored_plate_model = Model.FromJSON(armored_plate_data, InstanceData, PlateInstance) plane_plate_data = objloader.load_obj(os.path.join("springtangent-model-files", "plane_plate.75.75.decimation_test.00.obj"), calculate_normals=True) plane_plate_model = Model.FromJSON(plane_plate_data, InstanceData, PlateInstance) angled_plate_data = objloader.load_obj(os.path.join("springtangent-model-files", "angled_plate_plane.75.25..25.decimated.obj"), calculate_normals=True) angled_plate_model = Model.FromJSON(angled_plate_data, InstanceData, PlateInstance) angled_to_rounded_data = objloader.load_obj(os.path.join("springtangent-model-files", "angled_to_round_adapter.75.25.25", "angled_to_rounded_adapter.75.25.25.decimated.obj"), calculate_normals=True) angled_to_rounded_model = Model.FromJSON(angled_to_rounded_data, InstanceData, PlateInstance) models = [armored_plate_model, plane_plate_model, angled_plate_model, angled_to_rounded_model] deferred_shader = ShaderProgram(GBUFFER_VERT, GBUFFER_FRAG) deferred_light_shader = ShaderProgram(GBUFFER_LIGHT_VERT, GBUFFER_LIGHT_FRAG) for mesh in light_volume_model.meshes: mesh.shader = deferred_light_shader mesh.material = deferred_textures # replace the shader with the deferred shader in all meshes for model in models: for mesh in model.meshes: mesh.shader = deferred_shader # set up the data for the instances. # 30 x 30 array of tiles, which are randomly selected among the above models n = 30 instances = {} for i in range(n): for j in range(n): r = random.choice(range(4)) transform = Mat4.Translation(Vec3((i-n//2) * 2, 0.0, (j-n//2) * 2)) * Mat4.Rotation(math.pi/2.0 * r, Vec3(0.0, 1.0, 0.0)) instance = scene.add(random.choice(models), InstanceData(transform)) instance.r = r instances[i,j] = instance nlights = 400 for i in range(nlights): transform = Mat4.Translation(Vec3(random.uniform(-n/2, n/2), random.uniform(-1.0, 1.0), random.uniform(-n/2,n/2))) * Mat4.Scale(random.uniform(2.0, 10.0)) instance = light_scene.add(light_volume_model, PointLightInstanceData(transform, diffuse=Vec3(1.0, 1.0, 1.0), linear_attenuation=0.1, quadratic_attenutation=0.01)) # full screen rectangle class QuadVert(Structure): _fields_ = [ ('position', Vec2), ('texcoord', Vec2) ] quad_points = Vector(QuadVert) quad_points.append(QuadVert(Vec2(-1.0, 1.0), Vec2(0.0, 1.0))) quad_points.append(QuadVert(Vec2(-1.0, -1.0), Vec2(0.0, 0.0))) quad_points.append(QuadVert(Vec2( 1.0, -1.0), Vec2(1.0, 0.0))) quad_points.append(QuadVert(Vec2( 1.0, 1.0), Vec2(1.0, 1.0))) quad_indices = Vector(c_ubyte) quad_indices.append(0) quad_indices.append(1) quad_indices.append(2) quad_indices.append(0) quad_indices.append(2) quad_indices.append(3) quad_attribs = BufferAttribs(sizeof(QuadVert)) quad_attribs.add(BufferAttribs.POSITION_INDEX, 2, gl.FLOAT, gl.FALSE, QuadVert.position.offset) quad_attribs.add(BufferAttribs.TEXCOORD_INDEX, 2, gl.FLOAT, gl.FALSE, QuadVert.texcoord.offset) quad_shader = ShaderProgram(FRAMEBUFFER_VERT, FRAMEBUFFER_FRAG) quad_draw_call = DrawCall(gl.UNSIGNED_BYTE, gl.TRIANGLES, 0, len(quad_indices)) quad_material = deferred_textures quad_mesh = Mesh(quad_shader, quad_draw_call, quad_material) quad_model = Model(quad_indices.get_data(), quad_points.get_data(), quad_attribs, [quad_mesh], InstanceData, PlateInstance) # quad_instances = ModelInstances(quad_model) quad_instance = quad_scene.add(quad_model, InstanceData(Mat4.Identity())) gl.enable(gl.MULTISAMPLE) t0 = time.perf_counter() frames = 0 while not window.shouldClose(): glfw.pollEvents() t = time.perf_counter() # render scene to gbuffer gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer) gl.enable(gl.DEPTH_TEST) gl.depthFunc(gl.LEQUAL) gl.enable(gl.CULL_FACE) gl.cullFace(gl.BACK) # set up gbuffer for writing attachments = [gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2] gl.drawBuffers(attachments) framebuffer_width, framebuffer_height = window.getFramebufferSize() light_camera.view_matrix = camera.view_matrix = Mat4.LookAt(Vec3(math.cos(time.clock() * 0.1), 1.0, math.sin(time.clock() * 0.1)) *15.0, Vec3(0.0, 0.0, 0.0), Vec3(0.0, 1.0, 0.0)) viewport = (0, 0, framebuffer_width, framebuffer_height) camera.render_to_viewport(viewport) # render lights to gbuffer gl.drawBuffer(gl.COLOR_ATTACHMENT3) gl.depthFunc(gl.GREATER) gl.enable(gl.CULL_FACE) gl.cullFace(gl.FRONT) gl.enable(gl.BLEND) gl.blendEquation(gl.FUNC_ADD) gl.blendFunc(gl.ONE, gl.ONE) light_camera.render_to_viewport(viewport) err = gl.getError() if err: print("ERROR:", err) if TEST_ANIMATION: for i in range(n): for j in range(n): instance = instances[i,j] enabled = True # math.sin(i+j+t*10.0) > -0.8 # instance.set_enabled(enabled) if enabled: y = (math.sin(t+i) + math.cos(t+j)) * 0.25 transform = Mat4.Translation(Vec3((i-n//2) * 2, y, (j-n//2) * 2)) * Mat4.Rotation(math.pi/2.0 * instance.r, Vec3(0.0, 1.0, 0.0)) instance.model_matrix = transform # render quad with texture gl.bindFramebuffer(gl.FRAMEBUFFER, 0) gl.disable(gl.BLEND) gl.disable(gl.CULL_FACE) gl.disable(gl.DEPTH_TEST) # We don't care about depth information when rendering a single quad quad_camera.clear_color = (1.0, 1.0, 1.0, 1.0) quad_camera.clear = gl.COLOR_BUFFER_BIT quad_camera.render_to_viewport(viewport) scene.update_instances() quad_scene.update_instances() light_scene.update_instances() window.swapBuffers() frames += 1 if not frames % 100: print("FRAME RATE:", float(frames)/(time.perf_counter() - t0))