ModernGL设置uniform。

3

我考虑从PyOpenGL转到ModernGL,但现在我正在努力实现任何东西。

首先,我想尝试经典的“使用时间uniform和正弦函数改变形状的三角形”,但我不知道如何向uniform写入内容。

以下是文档关于此的说明:

A uniform is a global GLSL variable declared with the “uniform” storage qualifier. These act as parameters that the user of a shader program can pass to that program.

In ModernGL, Uniforms can be accessed using Program.__getitem__() or Program.__iter__().

# Set a vec4 uniform
uniform['color'] = 1.0, 1.0, 1.0, 1.0

# Optionally we can store references to a member and set the value directly
uniform = program['color']
uniform.value = 1.0, 0.0, 0.0, 0.0

uniform = program['cameraMatrix']
uniform.write(camera_matrix)
这是我的代码:
import moderngl as mgl
import glfw
import numpy as np
import time
from math import sin

glfw.init()
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
window = glfw.create_window(800, 600, "__DELETEME__", None, None)
glfw.make_context_current(window)

context = mgl.create_context()
vertex_source = """
#version 330 core

in vec2 aPos;
uniform float time;

void main() {
    gl_Position = vec4(aPos.x, aPos.y + sin(time), 0.0, 1.0);
}
"""
fragment_source = """
#version 330 core

out vec4 color;

void main(){
    color = vec4(0.0, 0.0, 1.0, 1.0);
}
"""

program = context.program(vertex_shader=vertex_source, fragment_shader=fragment_source)

data = np.array([
    0.5, 0, 
   -0.5, 0, 
    0, 0.5], dtype = "float32")

vbo = context.buffer(data.tobytes())
vao = context.vertex_array(program, vbo, "aPos")
uniform = program["time"]
uniform.value = 1.0

while not glfw.window_should_close(window):
    now = time.time()
    vao.render()
    elapsed = time.time() - now
    glfw.poll_events()
    glfw.swap_buffers(window)
glfw.terminate()

现在它没有绘制任何东西。我做错了什么?谢谢!
1个回答

3
经过的时间是开始时间和当前时间之间的差值。在应用程序循环之前获取开始时间,并在每个帧中计算经过的时间:
start_time = time.time()
while not glfw.window_should_close(window):
    elapsed = time.time() - start_time

    # [...]

统一变量 "time" 的值必须在循环中不断更新:
while not glfw.window_should_close(window):
    # [...]

    uniform.value = elapsed

在应用程序循环中,您需要在每个帧中清除显示 (请参见 ModernGL 上下文):

while not glfw.window_should_close(window):
    # [...]

    context.clear(0.0, 0.0, 0.0)
    vao.render()

完整示例:

import moderngl as mgl
import glfw
import numpy as np
import time
from math import sin

glfw.init()
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
window = glfw.create_window(800, 600, "__DELETEME__", None, None)
glfw.make_context_current(window)

context = mgl.create_context()
vertex_source = """
#version 330 core

in vec2 aPos;
uniform float time;

void main() {
    gl_Position = vec4(aPos.x, aPos.y + sin(time), 0.0, 1.0);
}
"""
fragment_source = """
#version 330 core

out vec4 color;

void main(){
    color = vec4(0.0, 0.0, 1.0, 1.0);
}
"""

program = context.program(vertex_shader=vertex_source, fragment_shader=fragment_source)

data = np.array([
    0.5, 0, 
   -0.5, 0, 
    0, 0.5], dtype = "float32")

vbo = context.buffer(data.tobytes())
vao = context.vertex_array(program, vbo, "aPos")
uniform = program["time"]
uniform.value = 1.0

start_time = time.time()
while not glfw.window_should_close(window):
    elapsed = time.time() - start_time
    uniform.value = elapsed

    context.clear(0.0, 0.0, 0.0)
    vao.render()
    
    glfw.poll_events()
    glfw.swap_buffers(window)
glfw.terminate()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接