我正在尝试使用Python中的OpenGL来使用Compute Shaders,但我对我正在做的事情一无所知。我希望能够发送一些数据,让着色器改变它,并将数据读回来。这是我到目前为止编写的代码:
import OpenGL
from OpenGL.GL import *
from OpenGL.GL import shaders
from OpenGL.GLU import *
import pygame
from pygame.locals import *
import numpy as np
buffer_data = np.array([0, 0, 0, 0])
compute_shader_code = """
#version 430 core
layout(std430, binding=9) buffer data{
vec4 Data[];
};
void main()
{
Data[0].x = 1;
Data[0].y = 2;
Data[0].z = 3;
Data[0].w = 4;
}
"""
def setup():
pygame.init()
window_width = 1000
window_height = 800
display = (window_width, window_height)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
test()
pygame.quit()
quit()
def test():
print("Creating shader program")
compute_shader_program = -1
shader_program = -1
compute_shader_program = glCreateShader(GL_COMPUTE_SHADER)
glShaderSource(compute_shader_program, compute_shader_code)
glCompileShader(compute_shader_program)
if glGetShaderiv(compute_shader_program, GL_COMPILE_STATUS) != GL_TRUE:
raise RuntimeError(glGetShaderInfoLog(compute_shader_program))
shader_program = glCreateProgram()
glAttachShader(shader_program, compute_shader_program)
glLinkProgram(shader_program)
if shader_program != -1:
ssbo = -1
print("Binding buffers")
glUseProgram(shader_program)
glGenBuffers(1, ssbo)
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 9, ssbo)
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo)
print("Calling compute")
glDispatchCompute(1, 1, 1)
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)
block_index = glGetProgramResourceIndex(shader_program, GL_SHADER_STORAGE_BLOCK, "data", 9)
if block_index != GL_INVALID_INDEX:
print("I think I found the data")
# How do I access the data here
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER)
setup()
当我运行此程序时,我收到此错误:
File "some location/Compute Shader Test.py", line 56, in test
glUseProgram(shader_program)
File "some location\Anaconda3\envs\Regression\lib\site-packages\OpenGL\platform\baseplatform.py", line 402, in __call__
return self( *args, **named )
File "errorchecker.pyx", line 53, in OpenGL_accelerate.errorchecker._ErrorChecker.glCheckError (src\errorchecker.c:1218)
OpenGL.error.GLError: GLError(
err = 1282,
description = b'invalid operation',
baseOperation = glUseProgram,
cArguments = (2,)
)
所以我猜我有2个问题。首先,为什么我会收到此错误?着色器程序似乎编译得很好,在我的计算机上,它的整数值为2.我是否错误地创建它?这不是你使用计算着色器的方式吗?
其次,如何在着色器运行后读取数据?
非常感谢!
***************更新***************
根据评论中的一些建议,我让它运行而不会崩溃。现在问题是从卡上回来的价值很奇怪。
更新的代码:
import OpenGL
from OpenGL.GL import *
from OpenGL.GL import shaders
from OpenGL.GLU import *
import pygame
from pygame.locals import *
import numpy as np
buffer_data = np.array([0, 0, 0, 0])
compute_shader_code = """
#version 430 core
layout(local_size_x = 1, local_size_y = 1) in;
layout(std430, binding=9) buffer data{
vec4 Data[];
};
void main()
{
Data[0].x = 1;
Data[0].y = 2;
Data[0].z = 3;
Data[0].w = 4;
}
"""
def setup():
pygame.init()
window_width = 1000
window_height = 800
display = (window_width, window_height)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
print(glGetString(GL_VERSION))
test()
pygame.quit()
quit()
def test():
print("Creating shader program")
compute_shader_program = -1
shader_program = -1
compute_shader_program = glCreateShader(GL_COMPUTE_SHADER)
glShaderSource(compute_shader_program, compute_shader_code)
glCompileShader(compute_shader_program)
if glGetShaderiv(compute_shader_program, GL_COMPILE_STATUS) != GL_TRUE:
raise RuntimeError(glGetShaderInfoLog(compute_shader_program))
shader_program = glCreateProgram()
glAttachShader(shader_program, compute_shader_program)
glLinkProgram(shader_program)
print(glGetProgramInfoLog(shader_program))
if shader_program != -1:
ssbo = -1
print("Binding buffers")
glUseProgram(shader_program)
glGenBuffers(1, ssbo)
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 9, ssbo)
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo)
glBufferData(GL_SHADER_STORAGE_BUFFER, np.ascontiguousarray(buffer_data, dtype=np.float32), GL_DYNAMIC_READ)
print("Calling compute")
glDispatchCompute(1, 1, 1)
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)
block_index = glGetProgramResourceIndex(shader_program, GL_SHADER_STORAGE_BLOCK, "data", 9)
if block_index != GL_INVALID_INDEX:
print("I think I found the data")
# How do I access the data here
result = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY)
print(result)
print(buffer_data)
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER)
setup()
当我打印结果时,我得到2109824291840,这显然不是我所期待的。我将非常感谢有关如何从缓冲区正确读取数据的任何帮助。再次感谢!