尝试使用Compute Shader时,glUseProgram会出现Invalid Operation错误

时间:2017-12-05 14:36:19

标签: python-3.x opengl compute-shader

我正在尝试使用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,这显然不是我所期待的。我将非常感谢有关如何从缓冲区正确读取数据的任何帮助。再次感谢!

0 个答案:

没有答案