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 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))