关于我的项目:我在Linux上使用OpenGL3.2,我使用GTK3和GLArea小部件构建了一个基本的应用程序。该程序是用PyCharm IDE用Python编写的。项目解释器被设置为Python 3.8,我已经加载了以下包:Pillow 7.1.2、PyGObject 3.36.1、PyOpenGL 3.1.5、numpy 1.18、pyrr 0.10.3和glfw 1.11.2(见下图)
我有一个使用GLFW可以正确运行的程序,但使用gtk3的glarea不能正确运行。我试图使用自定义framebuffer对象呈现到纹理,基于GTK3的程序不能成功地呈现到自定义framebuffer。然而,基于GLFW的程序呈现得很好。在OpenGL代码中没有区别。我只是更改窗口代码。为了使用自定义framebuffers,GTK3是否需要启用一些东西?GTK3的文档(这里)只指出需要设置特殊标志来启用深度缓冲区和模具缓冲区(我已经启用了这两个),但与自定义纹理缓冲区没有任何关系。
任何和所有的见解都非常赞赏。
import sys
import gi, pyrr
import numpy
gi.require_version('Gtk', '3.0')
from pyrr import matrix44, Vector3
from gi.repository import Gtk
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram
from PIL import Image
class GLCanvas(Gtk.GLArea):
def __init__(self):
Gtk.GLArea.__init__(self)
self.set_required_version(3, 2) # Sets the version of OpenGL required by this OpenGL program
self.connect("realize", self.on_initialize) # This signal is used to initialize the OpenGL state
self.connect("render", self.on_render) # This signal is emitted for each frame that is rendered
self.add_tick_callback(self.tick) # This is a frame time clock that is called each time a frame is rendered
self.set_start_time = False # Boolean to track whether the clock has been initialized
self.set_has_depth_buffer(True)
self.set_has_stencil_buffer(True)
def tick(self, widget, frame_clock):
self.current_frame_time = frame_clock.get_frame_time() # Gets the current timestamp in microseconds
if self.set_start_time == False: # Initializes the timer at the start of the program
self.starting_time = self.current_frame_time # Stores the timestamp set when the program was initalized
self.set_start_time = True # Prevents the initialization routine from running again in this instance
self.application_clock = (self.current_frame_time - self.starting_time)/1000000 # Calculate the total number of seconds that the program has been running
return True # Returns true to indicate that tick callback should contine to be called
def on_initialize(self, gl_area):
# Prints information about our OpenGL Context
opengl_context = self.get_context() # Retrieves the Gdk.GLContext used by gl_area
opengl_context.make_current() # Makes the Gdk.GLContext current to the drawing surfaced used by Gtk.GLArea
major, minor = opengl_context.get_version() # Gets the version of OpenGL currently used by the opengl_context
print("\033[93m OpenGL context created successfully.\n -- Using OpenGL Version \033[94m" + str(major) + "." + str(minor) + "\033[0m")
# Checks to see if there were errors creating the context
if gl_area.get_error() != None:
print(gl_area.get_error())
# Get information about current GTK GLArea canvas
window = gl_area.get_allocation()
w_width, w_height = window.width, window.height
self.aspect_ratio = w_width / w_height
self.cube_positions = [(1.0, 1.0, 0.0), (0.0, 0.0, 0.0), (2.0, 0.0, 0.0)]
self.plane_position = matrix44.create_from_translation(Vector3([-3.0, 1.0, 0.0]))
cube = [-0.5, -0.5, 0.5, 0.0, 0.0,
0.5, -0.5, 0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0, 0.0,
0.5, 0.5, -0.5, 1.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 1.0,
0.5, -0.5, -0.5, 0.0, 0.0,
0.5, 0.5, -0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 1.0,
0.5, -0.5, 0.5, 0.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 0.0,
-0.5, -0.5, -0.5, 1.0, 0.0,
-0.5, -0.5, 0.5, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0, 0.0,
0.5, -0.5, 0.5, 1.0, 1.0,
-0.5, -0.5, 0.5, 0.0, 1.0,
0.5, 0.5, -0.5, 0.0, 0.0,
-0.5, 0.5, -0.5, 1.0, 0.0,
-0.5, 0.5, 0.5, 1.0, 1.0,
0.5, 0.5, 0.5, 0.0, 1.0]
cube = numpy.array(cube, dtype=numpy.float32)
self.cube_indices = [0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4,
8, 9, 10, 10, 11, 8,
12, 13, 14, 14, 15, 12,
16, 17, 18, 18, 19, 16,
20, 21, 22, 22, 23, 20]
self.cube_indices = numpy.array(self.cube_indices, dtype=numpy.uint32)
plane = [-0.5, -0.5, 0.0, 0.0, 0.0,
2.0, -0.5, 0.0, 1.0, 0.0,
2.0, 1.0, 0.0, 1.0, 1.0,
-0.5, 1.0, 0.0, 0.0, 1.0]
plane = numpy.array(plane, dtype=numpy.float32)
self.plane_indices = [0, 1, 2, 2, 3, 0]
self.plane_indices = numpy.array(self.plane_indices, dtype=numpy.uint32)
vertex_shader = """
#version 330
in layout(location = 0) vec3 position;
in layout(location = 1) vec2 textCoords;
uniform mat4 vp;
uniform mat4 model;
out vec2 outText;
void main()
{
gl_Position = vp * model * vec4(position, 1.0f);
outText = textCoords;
}
"""
fragment_shader = """
#version 330
in vec2 outText;
out vec4 outColor;
uniform sampler2D renderedTexture;
void main()
{
outColor = texture(renderedTexture, outText);
}
"""
shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
OpenGL.GL.shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER))
# cube VAO
self.cube_vao = glGenVertexArrays(1)
glBindVertexArray(self.cube_vao)
cube_VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, cube_VBO)
glBufferData(GL_ARRAY_BUFFER, cube.itemsize * len(cube), cube, GL_STATIC_DRAW)
cube_EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube_EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.cube_indices.itemsize * len(self.cube_indices), self.cube_indices, GL_STATIC_DRAW)
# position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, cube.itemsize * 5, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)
# textures
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, cube.itemsize * 5, ctypes.c_void_p(12))
glEnableVertexAttribArray(1)
glBindVertexArray(0)
# plane VAO
self.plane_vao = glGenVertexArrays(1)
glBindVertexArray(self.plane_vao)
plane_VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, plane_VBO)
glBufferData(GL_ARRAY_BUFFER, plane.itemsize * len(plane), plane, GL_STATIC_DRAW)
plane_EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, plane_EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.plane_indices.itemsize * len(self.plane_indices), self.plane_indices,
GL_STATIC_DRAW)
# position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, plane.itemsize * 5, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)
# textures
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, plane.itemsize * 5, ctypes.c_void_p(12))
glEnableVertexAttribArray(1)
glBindVertexArray(0)
###########################################################################################
self.plane_texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, self.plane_texture)
# texture wrapping params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# texture filtering params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w_width, w_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
glBindTexture(GL_TEXTURE_2D, 0)
depth_buff = glGenRenderbuffers(1)
glBindRenderbuffer(GL_RENDERBUFFER, depth_buff)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w_width, w_height)
self.FBO = glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, self.FBO)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self.plane_texture, 0)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buff)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
###########################################################################################
self.crate_texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, self.crate_texture)
# Set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
# load image
image = Image.open("models/crate.jpg")
img_data = numpy.array(list(image.getdata()), numpy.uint8)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
glBindTexture(GL_TEXTURE_2D, 0)
###########################################################################################
glEnable(GL_DEPTH_TEST)
view = matrix44.create_from_translation(Vector3([0.0, 0.0, -5.0]))
projection = matrix44.create_perspective_projection_matrix(45.0, self.aspect_ratio, 0.1, 100.0)
vp = matrix44.multiply(view, projection)
glUseProgram(shader)
vp_loc = glGetUniformLocation(shader, "vp")
self.model_loc = glGetUniformLocation(shader, "model")
glUniformMatrix4fv(vp_loc, 1, GL_FALSE, vp)
return True
def on_render(self, gl_area, gl_context):
glClearColor(0.2, 0.25, 0.27, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
rot_y = pyrr.Matrix44.from_y_rotation(self.application_clock * 2)
# draw to the default frame buffer
glBindVertexArray(self.cube_vao)
glBindTexture(GL_TEXTURE_2D, self.crate_texture)
for i in range(len(self.cube_positions)):
model = matrix44.create_from_translation(self.cube_positions[i])
if i == 0:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, rot_y * model)
elif i == 1:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, model)
else:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, model)
glDrawElements(GL_TRIANGLES, len(self.cube_indices), GL_UNSIGNED_INT, None)
# draw to the custom frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, self.FBO)
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
for i in range(len(self.cube_positions)):
model = matrix44.create_from_translation(self.cube_positions[i])
if i == 0:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, rot_y * model)
elif i == 1:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, model)
else:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, model)
glDrawElements(GL_TRIANGLES, len(self.cube_indices), GL_UNSIGNED_INT, None)
glBindVertexArray(0)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
# draw the plane
glBindVertexArray(self.plane_vao)
glBindTexture(GL_TEXTURE_2D, self.plane_texture)
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, self.plane_position)
glDrawElements(GL_TRIANGLES, len(self.plane_indices), GL_UNSIGNED_INT, None)
glBindVertexArray(0)
self.queue_draw() # Schedules a redraw for Gtk.GLArea
class RootWindow(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self)
def do_activate(self):
window = Gtk.Window(application=self)
window.set_title("Render To Texture")
window.set_default_size(1280, 720)
window.set_position(Gtk.WindowPosition.CENTER)
window.add(GLCanvas())
window.show_all()
win = RootWindow()
exit_status = win.run(sys.argv)
sys.exit(exit_status)
import glfw
from OpenGL.GL import *
import OpenGL.GL.shaders
import numpy
import pyrr
from pyrr import matrix44, Vector3
from PIL import Image
def window_resize(window, width, height):
glViewport(0, 0, width, height)
cube_positions = [(1.0, 1.0, 0.0), (0.0, 0.0, 0.0), (2.0, 0.0, 0.0)]
plane_position = matrix44.create_from_translation(Vector3([-3.0, 1.0, 0.0]))
def main():
if not glfw.init():
return
w_width, w_height = 1280, 720
aspect_ratio = w_width / w_height
window = glfw.create_window(w_width, w_height, "My OpenGL window", None, None)
if not window:
glfw.terminate()
return
glfw.make_context_current(window)
glfw.set_window_size_callback(window, window_resize)
cube = [-0.5, -0.5, 0.5, 0.0, 0.0,
0.5, -0.5, 0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0, 0.0,
0.5, 0.5, -0.5, 1.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 1.0,
0.5, -0.5, -0.5, 0.0, 0.0,
0.5, 0.5, -0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 1.0,
0.5, -0.5, 0.5, 0.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 0.0,
-0.5, -0.5, -0.5, 1.0, 0.0,
-0.5, -0.5, 0.5, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0, 0.0,
0.5, -0.5, 0.5, 1.0, 1.0,
-0.5, -0.5, 0.5, 0.0, 1.0,
0.5, 0.5, -0.5, 0.0, 0.0,
-0.5, 0.5, -0.5, 1.0, 0.0,
-0.5, 0.5, 0.5, 1.0, 1.0,
0.5, 0.5, 0.5, 0.0, 1.0]
cube = numpy.array(cube, dtype=numpy.float32)
cube_indices = [ 0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4,
8, 9, 10, 10, 11, 8,
12, 13, 14, 14, 15, 12,
16, 17, 18, 18, 19, 16,
20, 21, 22, 22, 23, 20]
cube_indices = numpy.array(cube_indices, dtype=numpy.uint32)
plane = [-0.5, -0.5, 0.0, 0.0, 0.0,
2.0, -0.5, 0.0, 1.0, 0.0,
2.0, 1.0, 0.0, 1.0, 1.0,
-0.5, 1.0, 0.0, 0.0, 1.0]
plane = numpy.array(plane, dtype=numpy.float32)
plane_indices = [0, 1, 2, 2, 3, 0]
plane_indices = numpy.array(plane_indices, dtype=numpy.uint32)
vertex_shader = """
#version 330
in layout(location = 0) vec3 position;
in layout(location = 1) vec2 textCoords;
uniform mat4 vp;
uniform mat4 model;
out vec2 outText;
void main()
{
gl_Position = vp * model * vec4(position, 1.0f);
outText = textCoords;
}
"""
fragment_shader = """
#version 330
in vec2 outText;
out vec4 outColor;
uniform sampler2D renderedTexture;
void main()
{
outColor = texture(renderedTexture, outText);
}
"""
shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
OpenGL.GL.shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER))
# cube VAO
cube_vao = glGenVertexArrays(1)
glBindVertexArray(cube_vao)
cube_VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, cube_VBO)
glBufferData(GL_ARRAY_BUFFER, cube.itemsize * len(cube), cube, GL_STATIC_DRAW)
cube_EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube_EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, cube_indices.itemsize * len(cube_indices), cube_indices, GL_STATIC_DRAW)
# position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, cube.itemsize * 5, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)
# textures
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, cube.itemsize * 5, ctypes.c_void_p(12))
glEnableVertexAttribArray(1)
glBindVertexArray(0)
# plane VAO
plane_vao = glGenVertexArrays(1)
glBindVertexArray(plane_vao)
plane_VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, plane_VBO)
glBufferData(GL_ARRAY_BUFFER, plane.itemsize * len(plane), plane, GL_STATIC_DRAW)
plane_EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, plane_EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, plane_indices.itemsize * len(plane_indices), plane_indices, GL_STATIC_DRAW)
# position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, plane.itemsize * 5, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)
# textures
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, plane.itemsize * 5, ctypes.c_void_p(12))
glEnableVertexAttribArray(1)
glBindVertexArray(0)
###########################################################################################
plane_texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, plane_texture)
# texture wrapping params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# texture filtering params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w_width, w_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
glBindTexture(GL_TEXTURE_2D, 0)
depth_buff = glGenRenderbuffers(1)
glBindRenderbuffer(GL_RENDERBUFFER, depth_buff)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w_width, w_height)
FBO = glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, FBO)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, plane_texture, 0)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buff)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
###########################################################################################
crate_texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, crate_texture)
# Set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
# load image
image = Image.open("res/crate.jpg")
img_data = numpy.array(list(image.getdata()), numpy.uint8)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
glBindTexture(GL_TEXTURE_2D, 0)
###########################################################################################
glEnable(GL_DEPTH_TEST)
view = matrix44.create_from_translation(Vector3([0.0, 0.0, -5.0]))
projection = matrix44.create_perspective_projection_matrix(45.0, aspect_ratio, 0.1, 100.0)
vp = matrix44.multiply(view, projection)
glUseProgram(shader)
vp_loc = glGetUniformLocation(shader, "vp")
model_loc = glGetUniformLocation(shader, "model")
glUniformMatrix4fv(vp_loc, 1, GL_FALSE, vp)
while not glfw.window_should_close(window):
glfw.poll_events()
glClearColor(0.2, 0.25, 0.27, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
rot_y = pyrr.Matrix44.from_y_rotation(glfw.get_time() * 2)
# draw to the default frame buffer
glBindVertexArray(cube_vao)
glBindTexture(GL_TEXTURE_2D, crate_texture)
for i in range(len(cube_positions)):
model = matrix44.create_from_translation(cube_positions[i])
if i == 0:
glUniformMatrix4fv(model_loc, 1, GL_FALSE, rot_y * model)
elif i == 1:
glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)
else:
glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)
glDrawElements(GL_TRIANGLES, len(cube_indices), GL_UNSIGNED_INT, None)
# draw to the custom frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, FBO)
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
for i in range(len(cube_positions)):
model = matrix44.create_from_translation(cube_positions[i])
if i == 0:
glUniformMatrix4fv(model_loc, 1, GL_FALSE, rot_y * model)
elif i == 1:
glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)
else:
glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)
glDrawElements(GL_TRIANGLES, len(cube_indices), GL_UNSIGNED_INT, None)
glBindVertexArray(0)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
# draw the plane
glBindVertexArray(plane_vao)
glBindTexture(GL_TEXTURE_2D, plane_texture)
glUniformMatrix4fv(model_loc, 1, GL_FALSE, plane_position)
glDrawElements(GL_TRIANGLES, len(plane_indices), GL_UNSIGNED_INT, None)
glBindVertexArray(0)
glfw.swap_buffers(window)
glfw.terminate()
if __name__ == "__main__":
main()
事实证明,GLArea没有使用framebuffer0作为默认值。这里的问题是在使用glBindFramebuffer(GL_FRAMEBUFFER,0)的呈现循环结束时将framebuffer重置回0。相反,在呈现循环开始时使用default_ID=glGetIntegerv(GL_FRAMEBUFFER_BINDING)获取当前默认ID。在循环结束时,使用glBindFramebuffer(GL_FRAMEBUFFER,default_ID)重置为默认的framebuffer。
import sys
import gi, pyrr
import numpy
gi.require_version('Gtk', '3.0')
from pyrr import matrix44, Vector3
from gi.repository import Gtk
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram
from PIL import Image
class GLCanvas(Gtk.GLArea):
def __init__(self):
Gtk.GLArea.__init__(self)
self.set_required_version(3, 2) # Sets the version of OpenGL required by this OpenGL program
self.connect("realize", self.on_initialize) # This signal is used to initialize the OpenGL state
self.connect("render", self.on_render) # This signal is emitted for each frame that is rendered
self.add_tick_callback(self.tick) # This is a frame time clock that is called each time a frame is rendered
self.set_start_time = False # Boolean to track whether the clock has been initialized
self.set_has_depth_buffer(True)
self.set_has_stencil_buffer(True)
def tick(self, widget, frame_clock):
self.current_frame_time = frame_clock.get_frame_time() # Gets the current timestamp in microseconds
if self.set_start_time == False: # Initializes the timer at the start of the program
self.starting_time = self.current_frame_time # Stores the timestamp set when the program was initalized
self.set_start_time = True # Prevents the initialization routine from running again in this instance
self.application_clock = (self.current_frame_time - self.starting_time)/1000000 # Calculate the total number of seconds that the program has been running
return True # Returns true to indicate that tick callback should contine to be called
def on_initialize(self, gl_area):
# Prints information about our OpenGL Context
opengl_context = self.get_context() # Retrieves the Gdk.GLContext used by gl_area
opengl_context.make_current() # Makes the Gdk.GLContext current to the drawing surfaced used by Gtk.GLArea
major, minor = opengl_context.get_version() # Gets the version of OpenGL currently used by the opengl_context
# https://stackoverflow.com/questions/287871/how-to-print-colored-text-in-terminal-in-python
print("\033[93m OpenGL context created successfully.\n -- Using OpenGL Version \033[94m" + str(major) + "." + str(minor) + "\033[0m")
# Checks to see if there were errors creating the context
if gl_area.get_error() != None:
print(gl_area.get_error())
# Get information about current GTK GLArea canvas
window = gl_area.get_allocation()
w_width, w_height = window.width, window.height
self.aspect_ratio = w_width / w_height
self.cube_positions = [(1.0, 1.0, 0.0), (0.0, 0.0, 0.0), (2.0, 0.0, 0.0)]
self.plane_position = matrix44.create_from_translation(Vector3([-3.0, 1.0, 0.0]))
cube = [-0.5, -0.5, 0.5, 0.0, 0.0,
0.5, -0.5, 0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0, 0.0,
0.5, 0.5, -0.5, 1.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 1.0,
0.5, -0.5, -0.5, 0.0, 0.0,
0.5, 0.5, -0.5, 1.0, 0.0,
0.5, 0.5, 0.5, 1.0, 1.0,
0.5, -0.5, 0.5, 0.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 0.0,
-0.5, -0.5, -0.5, 1.0, 0.0,
-0.5, -0.5, 0.5, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 0.0,
0.5, -0.5, -0.5, 1.0, 0.0,
0.5, -0.5, 0.5, 1.0, 1.0,
-0.5, -0.5, 0.5, 0.0, 1.0,
0.5, 0.5, -0.5, 0.0, 0.0,
-0.5, 0.5, -0.5, 1.0, 0.0,
-0.5, 0.5, 0.5, 1.0, 1.0,
0.5, 0.5, 0.5, 0.0, 1.0]
cube = numpy.array(cube, dtype=numpy.float32)
self.cube_indices = [0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4,
8, 9, 10, 10, 11, 8,
12, 13, 14, 14, 15, 12,
16, 17, 18, 18, 19, 16,
20, 21, 22, 22, 23, 20]
self.cube_indices = numpy.array(self.cube_indices, dtype=numpy.uint32)
plane = [-0.5, -0.5, 0.0, 0.0, 0.0,
2.0, -0.5, 0.0, 1.0, 0.0,
2.0, 1.0, 0.0, 1.0, 1.0,
-0.5, 1.0, 0.0, 0.0, 1.0]
plane = numpy.array(plane, dtype=numpy.float32)
self.plane_indices = [0, 1, 2, 2, 3, 0]
self.plane_indices = numpy.array(self.plane_indices, dtype=numpy.uint32)
vertex_shader = """
#version 330
in vec3 position;
in vec2 textCoords;
uniform mat4 vp;
uniform mat4 model;
out vec2 outText;
void main()
{
gl_Position = vp * model * vec4(position, 1.0f);
outText = textCoords;
}
"""
fragment_shader = """
#version 330
in vec2 outText;
out vec4 outColor;
uniform sampler2D renderedTexture;
void main()
{
outColor = texture(renderedTexture, outText);
}
"""
shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
OpenGL.GL.shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER))
# cube VAO
self.cube_vao = glGenVertexArrays(1)
glBindVertexArray(self.cube_vao)
cube_VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, cube_VBO)
glBufferData(GL_ARRAY_BUFFER, cube.itemsize * len(cube), cube, GL_STATIC_DRAW)
cube_EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube_EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.cube_indices.itemsize * len(self.cube_indices), self.cube_indices, GL_STATIC_DRAW)
# position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, cube.itemsize * 5, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)
# textures
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, cube.itemsize * 5, ctypes.c_void_p(12))
glEnableVertexAttribArray(1)
glBindVertexArray(0)
# plane VAO
self.plane_vao = glGenVertexArrays(1)
glBindVertexArray(self.plane_vao)
plane_VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, plane_VBO)
glBufferData(GL_ARRAY_BUFFER, plane.itemsize * len(plane), plane, GL_STATIC_DRAW)
plane_EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, plane_EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.plane_indices.itemsize * len(self.plane_indices), self.plane_indices,
GL_STATIC_DRAW)
# position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, plane.itemsize * 5, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)
# textures
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, plane.itemsize * 5, ctypes.c_void_p(12))
glEnableVertexAttribArray(1)
glBindVertexArray(0)
###########################################################################################
self.plane_texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, self.plane_texture)
# texture wrapping params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# texture filtering params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w_width, w_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
glBindTexture(GL_TEXTURE_2D, 0)
depth_buff = glGenRenderbuffers(1)
glBindRenderbuffer(GL_RENDERBUFFER, depth_buff)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w_width, w_height)
self.FBO = glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, self.FBO)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self.plane_texture, 0)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buff)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
###########################################################################################
self.crate_texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, self.crate_texture)
# Set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
# load image
image = Image.open("models/crate.jpg")
img_data = numpy.array(list(image.getdata()), numpy.uint8)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
glBindTexture(GL_TEXTURE_2D, 0)
###########################################################################################
glEnable(GL_DEPTH_TEST)
view = matrix44.create_from_translation(Vector3([0.0, 0.0, -5.0]))
projection = matrix44.create_perspective_projection_matrix(45.0, self.aspect_ratio, 0.1, 100.0)
vp = matrix44.multiply(view, projection)
glUseProgram(shader)
vp_loc = glGetUniformLocation(shader, "vp")
self.model_loc = glGetUniformLocation(shader, "model")
glUniformMatrix4fv(vp_loc, 1, GL_FALSE, vp)
return True
def on_render(self, gl_area, gl_context):
default_ID = glGetIntegerv(GL_FRAMEBUFFER_BINDING)
glClearColor(0.2, 0.25, 0.27, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
rot_y = pyrr.Matrix44.from_y_rotation(self.application_clock * 2)
# draw to the default frame buffer
glBindVertexArray(self.cube_vao)
glBindTexture(GL_TEXTURE_2D, self.crate_texture)
for i in range(len(self.cube_positions)):
model = matrix44.create_from_translation(self.cube_positions[i])
if i == 0:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, rot_y * model)
elif i == 1:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, model)
else:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, model)
glDrawElements(GL_TRIANGLES, len(self.cube_indices), GL_UNSIGNED_INT, None)
# draw to the custom frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, self.FBO)
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
for i in range(len(self.cube_positions)):
model = matrix44.create_from_translation(self.cube_positions[i])
if i == 0:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, rot_y * model)
elif i == 1:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, model)
else:
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, model)
glDrawElements(GL_TRIANGLES, len(self.cube_indices), GL_UNSIGNED_INT, None)
glBindFramebuffer(GL_FRAMEBUFFER, default_ID)
glBindVertexArray(0)
# draw the plane
glBindVertexArray(self.plane_vao)
glBindTexture(GL_TEXTURE_2D, self.plane_texture)
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, self.plane_position)
glDrawElements(GL_TRIANGLES, len(self.plane_indices), GL_UNSIGNED_INT, None)
glBindVertexArray(0)
self.queue_draw() # Schedules a redraw for Gtk.GLArea
class RootWindow(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self)
def do_activate(self):
window = Gtk.Window(application=self)
window.set_title("Render To Texture")
window.set_default_size(1280, 720)
window.set_position(Gtk.WindowPosition.CENTER)
window.add(GLCanvas())
window.show_all()
win = RootWindow()
exit_status = win.run(sys.argv)
sys.exit(exit_status)
我正在对对象进行两次模糊处理。为了确保在中,整个场景都被我试图模糊的图像所覆盖。这是过程。 > < li >我设置了一个< code>FBO,其中包含我需要模糊的图像尺寸。 < li> 我正在使用以下函数设置< code >正交投影(称为< code >设置正交(FBO尺寸)): glViewport(0,0,w,h)glMatrixMode(GL _ PROJECTION)glload iden
我使用OpenGL 3.2来渲染阴影贴图。为此,我构造了一个渲染深度纹理的帧缓冲区。 要将纹理附加到帧缓冲区,我使用: 这很有效。渲染灯光视图后,我的GLSL着色器可以对深度纹理进行采样,以解决灯光的可见性问题。 我现在试图解决的问题是有更多的阴影贴图,比如说50个。在我的主要渲染过程中,我不想从50个不同的纹理中采样。我可以使用图集,但我想知道:我可以将所有这些阴影贴图作为2D纹理数组的切片传递
纹理根本不渲染,几何体都是黑色的。 截图:http://i.imgur.com/ypMdQY4.png 代码:http://pastebin.com/SvB8rxxt 我也会链接到我试图渲染的纹理和transformations.py模块,但是我没有被允许放置两个以上链接的声誉。谷歌搜索“现代opengl 02”会给你前者的教程,“转换py”会给你后者。 搜索“纹理材料开始”以查找纹理材料的设置位
我对OpenGL、GLFW或GLEW没有太多的经验,所以我对这些库的故障排除能力微乎其微。我已经设法呈现了一个三角形([-1,-1,0],[1,-1,0],[0,1,0]),但是当使用顶点属性坐标和颜色属性作为立方体时,它似乎无法呈现。我的代码、着色器和矩阵运算可能有很多问题。我希望我对我所做的事情有更清楚的了解,这样我就可以对我的错误有更详细的描述。目前,上面的代码只呈现窗口。我最初遵循http
我正在尝试使用OpenGL GLSL着色器渲染到纹理。首先,我尝试用白色填充30x30纹理的每个像素。我将顶点着色器索引从0传递到899,表示纹理的每个像素。对吗?顶点着色器: 片段着色器:
我正在努力熟悉Java的LWJGL库,我一直在线学习一些教程,我似乎无法渲染模型。 我使用的是OpenGL 2.1(这似乎非常过时,但我不知道如何更新它,我知道它与你的硬件捆绑在一起,如果有人对我的规格感兴趣,我使用的是MacBook Pro 2017型号) 如果有人能看看我的代码,告诉我哪里做错了,我会非常感激!(现在呈现的只是一个红色窗口) 从我研究过的来源来看,这段代码应该会产生一个由两个三