def __init__(self, name=None, parent=None, mode=gl.LINES, vertices=None): super(ShapeNode, self).__init__(name, parent) self.start = 0 self.vao = gl.genVertexArrays(1)[0] self.vbo = gl.genBuffers(1)[0] self.mode = mode self.vertices = vertices gl.bindVertexArray(self.vao) gl.bindBuffer(gl.ARRAY_BUFFER, self.vbo) # Position attribute gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, sizeof(Vertex), Vertex.position.offset) gl.enableVertexAttribArray(0) # Color attribute gl.vertexAttribPointer(1, 3, gl.FLOAT, gl.FALSE, sizeof(Vertex), Vertex.color.offset) gl.enableVertexAttribArray(1) # unbind the vbo gl.bindBuffer(gl.ARRAY_BUFFER, 0) # Unbind the VAO gl.bindVertexArray(0)
def initQuad(): global quadVAO, quadVBO class QuadVertex(Structure): _fields_ = [ ('position', Vec3), ('texcoord', Vec2) ] quadVertices = (QuadVertex * 4)( # Positions # Texture Coords (( -1.0, 1.0, 0.0), (0.0, 1.0)), (( -1.0, -1.0, 0.0), (0.0, 0.0)), (( 1.0, 1.0, 0.0), (1.0, 1.0)), (( 1.0, -1.0, 0.0), (1.0, 0.0)), ) # Setup plane VAO quadVAO = gl.genVertexArrays(1)[0] quadVBO = gl.genBuffers(1)[0] gl.bindVertexArray(quadVAO) gl.bindBuffer(gl.ARRAY_BUFFER, quadVBO) gl.bufferData(gl.ARRAY_BUFFER, bytes(quadVertices), gl.STATIC_DRAW) gl.enableVertexAttribArray(0) gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, sizeof(QuadVertex), QuadVertex.position.offset) gl.enableVertexAttribArray(1) gl.vertexAttribPointer(1, 2, gl.FLOAT, gl.FALSE, sizeof(QuadVertex), QuadVertex.texcoord.offset)
def draw(self, *args): gl.bindVertexArray(self.vao) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.ebo) for mesh in self.obj_model['meshes']: dc = mesh['draw_call'] gl.drawElements(gl.TRIANGLES, dc['count'], gl.UNSIGNED_INT, dc['start'] * self.obj_model['vertex_buffer']['stride']) gl.bindVertexArray(0);
def update(self): # print("UPDATING BUFFER INSTANCES") gl.bindBuffer(gl.ARRAY_BUFFER, self.vbo) # respecify the buffer data. instance_buffer_bytes = self.instances.get_data() gl.bufferData(gl.ARRAY_BUFFER, len(instance_buffer_bytes), gl.STREAM_DRAW) gl.bufferData(gl.ARRAY_BUFFER, instance_buffer_bytes, gl.STREAM_DRAW)
def vertices(self, vertices): self._vertex_data = (Vertex * len(vertices))(*[tuple([tuple(e) for e in v]) for v in vertices]) self.count = len(vertices) gl.bindVertexArray(self.vao) gl.bindBuffer(gl.ARRAY_BUFFER, self.vbo) gl.bufferData(gl.ARRAY_BUFFER, bytes(self._vertex_data), gl.STATIC_DRAW) gl.bindBuffer(gl.ARRAY_BUFFER, 0) # Unbind the VAO gl.bindVertexArray(0)
def load_model_data(obj_data): vertex_buffer = obj_data['vertex_buffer'] vertex_buffer_format = vertex_buffer['format'] vertex_buffer_bytes = base64.b64decode(vertex_buffer['bytes']) # set up the vao and vbo vao = gl.genVertexArrays(1)[0] vbo, ebo = gl.genBuffers(2) # 1. Bind Vertex Array Object gl.bindVertexArray(vao) # 2. Copy our vertices array in a buffer for OpenGL to use gl.bindBuffer(gl.ARRAY_BUFFER, vbo) gl.bufferData(gl.ARRAY_BUFFER, vertex_buffer_bytes, gl.STATIC_DRAW) # Position attribute gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, vertex_buffer['stride'], vertex_buffer_format['position']['offset']) gl.enableVertexAttribArray(0) # Normal attribute if 'normal' in vertex_buffer_format: gl.vertexAttribPointer(1, 3, gl.FLOAT, gl.FALSE, vertex_buffer['stride'], vertex_buffer_format['normal']['offset']) gl.enableVertexAttribArray(1) if 'texcoord' in vertex_buffer_format: gl.vertexAttribPointer(2, 2, gl.FLOAT, gl.FALSE, vertex_buffer['stride'], vertex_buffer_format['texcoord']['offset']) gl.enableVertexAttribArray(2) # load the index buffer index_buffer = obj_data['index_buffer'] index_buffer['bytes'] = base64.b64decode(index_buffer['bytes']) gl.bindBuffer(gl.ARRAY_BUFFER, ebo) gl.bufferData(gl.ARRAY_BUFFER, index_buffer['bytes'], gl.STATIC_DRAW) gl.bindBuffer(gl.ARRAY_BUFFER, 0) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0) gl.bindVertexArray(0) return vao, vbo, ebo
def __init__(self, index_buffer_bytes, vertex_buffer_bytes, vertex_buffer_attribs, meshes, instance_type, instance_wrapper_type=None): super(Model, self).__init__() self.instance_type = instance_type self.instance_wrapper_type = instance_wrapper_type self.vbo = gl.genBuffers(1)[0] # Copy our vertices array in a buffer for OpenGL to use gl.bindBuffer(gl.ARRAY_BUFFER, self.vbo) gl.bufferData(gl.ARRAY_BUFFER, vertex_buffer_bytes, gl.STATIC_DRAW) self.ebo = gl.genBuffers(1)[0] # populate the elemeent buffer gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,self.ebo) gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, index_buffer_bytes, gl.STATIC_DRAW) self.vertex_buffer_attribs = vertex_buffer_attribs self.meshes = meshes gl.bindBuffer(gl.ARRAY_BUFFER, 0) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
def __init__(self, model): super(ModelInstances, self).__init__() self.model = model self.instance_type = self.model.instance_type self.instance_wrapper = self.model.instance_wrapper_type self.instances = Set(self.instance_type) # the vao will contain all the binding for the mesh and instance data self.vao = gl.genVertexArrays(1)[0] gl.bindVertexArray(self.vao) # this vbo contains the instance data instance_buffer_bytes = self.instances.get_data() self.vbo = gl.genBuffers(1)[0] gl.bindBuffer(gl.ARRAY_BUFFER, self.vbo) gl.bufferData(gl.ARRAY_BUFFER, instance_buffer_bytes, gl.STREAM_DRAW) instance_buffer_attribs = BufferAttribs(sizeof(self.instance_type), 1) if hasattr(self.instance_type, 'model_matrix'): instance_buffer_attribs.add_mat(self.MODEL_MATRIX_LOCATION, 4, gl.FLOAT, gl.FALSE, self.instance_type.model_matrix.offset) if hasattr(self.instance_type, 'linear_attenuation'): instance_buffer_attribs.add_mat(self.LINEAR_ATTENUATION_LOCATION, 1, gl.FLOAT, gl.FALSE, self.instance_type.linear_attenuation.offset) if hasattr(self.instance_type, 'quadratic_attenuation'): instance_buffer_attribs.add_mat(self.QUADRATIC_ATTENUATION_LOCATION, 1, gl.FLOAT, gl.FALSE, self.instance_type.quadratic_attenuation.offset) if hasattr(self.instance_type, 'diffuse'): instance_buffer_attribs.add_mat(self.DIFFUSE_LOCATION, 3, gl.FLOAT, gl.FALSE, self.instance_type.diffuse.offset) instance_buffer_attribs.bind() # bind the models buffers and attribute data gl.bindBuffer(gl.ARRAY_BUFFER, self.model.vbo) self.model.vertex_buffer_attribs.bind() gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.model.ebo) gl.bindVertexArray(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(800, 600, "LearnOpenGL") if window is None: print('could not open window.') glfw.terminate() sys.exit() window.makeContextCurrent() window.setKeyCallback(key_callback) gl.init() err = gl.getError() print(gl) if err: print("WINDOW OPEN ERROR:", err) vertexShader = gl.createShader(gl.VERTEX_SHADER) gl.shaderSource(vertexShader, [VERTEX_SHADER_SOURCE]); gl.compileShader(vertexShader) success = gl.getShaderiv(vertexShader, gl.COMPILE_STATUS) print("VERTEX SHADER COMPILE STATUS:",success) if not success: infoLog = gl.getShaderInfoLog(vertexShader) print("ERROR COMPILING SHADER:", infoLog) sys.exit() fragmentShader = gl.createShader(gl.FRAGMENT_SHADER) gl.shaderSource(fragmentShader, [FRAGMENT_SHADER_SOURCE]); gl.compileShader(fragmentShader) success = gl.getShaderiv(fragmentShader, gl.COMPILE_STATUS) print("FRAGMENT SHADER COMPILE STATUS:",success) if not success: infoLog = gl.getShaderInfoLog(fragmentShader) print("ERROR COMPILING SHADER:", infoLog) sys.exit() shaderProgram = gl.createProgram() gl.attachShader(shaderProgram, vertexShader) gl.attachShader(shaderProgram, fragmentShader) gl.linkProgram(shaderProgram) gl.getProgramiv(shaderProgram, gl.LINK_STATUS) print("SHADER PROGRAM LINK STATUS:",success) if not success: infoLog = gl.getProgramInfoLog(shaderProgram) print("ERROR LINKING SHADER PROGRAM:", infoLog) sys.exit() assert(gl.isProgram(shaderProgram)) gl.useProgram(shaderProgram) #gl.deleteShader(vertexShader) #gl.deleteShader(fragmentShader) vao = gl.genVertexArrays(1)[0] vbo, ebo = gl.genBuffers(2) print(vao, vbo, ebo) # 1. Bind Vertex Array Object gl.bindVertexArray(vao) # 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) # 2. Copy our index array in a buffer for OpenGL to use gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo) gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW) # 3. Then set our vertex attributes pointers gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 3 * sizeof(gl.GLfloat), None) gl.enableVertexAttribArray(0) # 4. unbind the vbo gl.bindBuffer(gl.ARRAY_BUFFER, 0) # 4. Unbind the VAO gl.bindVertexArray(0) 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.useProgram(shaderProgram) gl.bindVertexArray(vao) gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, 0) # gl.drawArrays(gl.TRIANGLES, 0, 3); gl.bindVertexArray(0) window.swapBuffers() gl.deleteVertexArrays([vao]) gl.deleteBuffers([vbo, ebo])
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 initCube(): global cubeVAO, cubeVBO vertices = (Vertex * 36)( # Back face ((-0.5, -0.5, -0.5), ( 0.0, 0.0, -1.0), (0.0, 0.0)), # Bottom-left (( 0.5, 0.5, -0.5), ( 0.0, 0.0, -1.0), (1.0, 1.0)), # top-right (( 0.5, -0.5, -0.5), ( 0.0, 0.0, -1.0), (1.0, 0.0)), # bottom-right (( 0.5, 0.5, -0.5), ( 0.0, 0.0, -1.0), (1.0, 1.0)), # top-right ((-0.5, -0.5, -0.5), ( 0.0, 0.0, -1.0), (0.0, 0.0)), # bottom-left ((-0.5, 0.5, -0.5), ( 0.0, 0.0, -1.0), (0.0, 1.0)), # top-left # Front face ((-0.5, -0.5, 0.5), ( 0.0, 0.0, 1.0), (0.0, 0.0)), # bottom-left (( 0.5, -0.5, 0.5), ( 0.0, 0.0, 1.0), (1.0, 0.0)), # bottom-right (( 0.5, 0.5, 0.5), ( 0.0, 0.0, 1.0), (1.0, 1.0)), # top-right (( 0.5, 0.5, 0.5), ( 0.0, 0.0, 1.0), (1.0, 1.0)), # top-right ((-0.5, 0.5, 0.5), ( 0.0, 0.0, 1.0), (0.0, 1.0)), # top-left ((-0.5, -0.5, 0.5), ( 0.0, 0.0, 1.0), (0.0, 0.0)), # bottom-left # Left face ((-0.5, 0.5, 0.5), (-1.0, 0.0, 0.0), (1.0, 0.0)), # top-right ((-0.5, 0.5, -0.5), (-1.0, 0.0, 0.0), (1.0, 1.0)), # top-left ((-0.5, -0.5, -0.5), (-1.0, 0.0, 0.0), (0.0, 1.0)), # bottom-left ((-0.5, -0.5, -0.5), (-1.0, 0.0, 0.0), (0.0, 1.0)), # bottom-left ((-0.5, -0.5, 0.5), (-1.0, 0.0, 0.0), (0.0, 0.0)), # bottom-right ((-0.5, 0.5, 0.5), (-1.0, 0.0, 0.0), (1.0, 0.0)), # top-right # Right face (( 0.5, 0.5, 0.5), ( 1.0, 0.0, 0.0), (1.0, 0.0)), # top-left (( 0.5, -0.5, -0.5), ( 1.0, 0.0, 0.0), (0.0, 1.0)), # bottom-right (( 0.5, 0.5, -0.5), ( 1.0, 0.0, 0.0), (1.0, 1.0)), # top-right (( 0.5, -0.5, -0.5), ( 1.0, 0.0, 0.0), (0.0, 1.0)), # bottom-right (( 0.5, 0.5, 0.5), ( 1.0, 0.0, 0.0), (1.0, 0.0)), # top-left (( 0.5, -0.5, 0.5), ( 1.0, 0.0, 0.0), (0.0, 0.0)), # bottom-left # Bottom face ((-0.5, -0.5, -0.5), ( 0.0, -1.0, 0.0), (0.0, 1.0)), # top-right (( 0.5, -0.5, -0.5), ( 0.0, -1.0, 0.0), (1.0, 1.0)), # top-left (( 0.5, -0.5, 0.5), ( 0.0, -1.0, 0.0), (1.0, 0.0)), # bottom-left (( 0.5, -0.5, 0.5), ( 0.0, -1.0, 0.0), (1.0, 0.0)), # bottom-left ((-0.5, -0.5, 0.5), ( 0.0, -1.0, 0.0), (0.0, 0.0)), # bottom-right ((-0.5, -0.5, -0.5), ( 0.0, -1.0, 0.0), (0.0, 1.0)), # top-right # Top face ((-0.5, 0.5, -0.5), ( 0.0, 1.0, 0.0), (0.0, 1.0)), # top-left (( 0.5, 0.5, 0.5), ( 0.0, 1.0, 0.0), (1.0, 0.0)), # bottom-right (( 0.5, 0.5, -0.5), ( 0.0, 1.0, 0.0), (1.0, 1.0)), # top-right (( 0.5, 0.5, 0.5), ( 0.0, 1.0, 0.0), (1.0, 0.0)), # bottom-right ((-0.5, 0.5, -0.5), ( 0.0, 1.0, 0.0), (0.0, 1.0)), # top-left ((-0.5, 0.5, 0.5), ( 0.0, 1.0, 0.0), (0.0, 0.0)) # bottom-left ) cubeVAO = gl.genVertexArrays(1)[0] cubeVBO = gl.genBuffers(1)[0] # Fill buffer gl.bindBuffer(gl.ARRAY_BUFFER, cubeVBO); gl.bufferData(gl.ARRAY_BUFFER, bytes(vertices), gl.STATIC_DRAW) # Link vertex attributes gl.bindVertexArray(cubeVAO) 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.bindBuffer(gl.ARRAY_BUFFER, 0) gl.bindVertexArray(0)
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