首页 > 解决方案 > 需要 pyopengl 调试帮助,glUniform1f 用于 sampler2d 类型错误

问题描述

import pygame
from PIL import Image
import math
import ctypes
import numpy as np
from pygame.locals import *
from OpenGL.GL import shaders
from OpenGL.GL import *
 

models = [-0.5,0.5,2.0, 0.0,1.0, 
          
            -0.5,-0.5,2.0, 0.0,0.0,
          
            0.5,-0.5,2.0, 1.0,0.0,

            0.5,-0.5,2.0, 1.0,0.0,

            0.5,0.5,2.0, 1.0,1.0,

            -0.5,0.5,2.0, 0.0,0.0,]

         
vertex_shader="""
#version 430
in vec3 position;
in vec2 texturecoordinate;
out vec2 texcoordinate;
void main()
{
    gl_Position = vec4(position,1.0);
    texcoordinate = texturecoordinate;
    
}
"""
fragment_shader="""
#version 430
precision mediump float;
in vec2 texcoordinate;
uniform sampler2D texturergbadata;
out vec4 colour;

void main()
{
    colour = texture2D(texturergbadata,texcoordinate);
}
"""

shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
                                        OpenGL.GL.shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER))

VBO=glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER,VBO)
glBufferData(GL_ARRAY_BUFFER,len(models)*4,None,GL_STATIC_DRAW)

position = glGetAttribLocation(shader,"position")
glVertexAttribPointer(position, 3, GL_FLOAT, False, 20, ctypes.c_void_p(0))
glEnableVertexAttribArray(position)

image = Image.open('box.png')
rgbadata = list(image.getdata())
width = 200
height = 151

texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
             GL_UNSIGNED_BYTE, rgbadata)

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

texturecoordinate = glGetAttribLocation(shader,"texturecoordinate")
glEnableVertexAttribArray(texturecoordinate)
glVertexAttribPointer(texturecoordinate, 2, GL_FLOAT, False, 20,
                      ctypes.c_void_p(12))
glEnableVertexAttribArray(texturecoordinate)

texture = glGetUniformLocation(shader, "texturergbadata")
glActiveTexture(GL_TEXTURE0)
glUniform1f(texture, ctypes.c_float(0))


glEnable(GL_DEPTH_TEST)

glUseProgram(shader)

这是我的代码,我被这个错误困住了,我已经调试了好几天了,我完全被难住了。我喜欢对此有一双新的眼睛。这段代码的主要问题是这里的这一行:

glUniform1f(texture, ctypes.c_float(0))

这个值进入我的着色器,但是没有办法在 python 中使用这个函数的整数变体,因为 python ctypes 库默认所有 c 类型整数为 c_long,这是我关于这个的论坛帖子:How to convert python integers into c integers ? 所以我使用了浮动版本,但我仍然遇到这个错误:

    Traceback (most recent call last):
  File "C:C:\path to file(this isnt what the actual error shows)", line 233, in <module>
    main()
  File "C:\path to file(this isnt what the actual error shows)", line 184, in main
    glUniform1f(texture, ctypes.c_float(0))
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\OpenGL\platform\baseplatform.py", line 415, in __call__
    return self( *args, **named )
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\OpenGL\error.py", line 230, in glCheckError
    raise self._errorClass(
OpenGL.error.GLError: GLError(
    err = 1282,
    description = b'invalid operation',
    baseOperation = glUniform1f,
    cArguments = (0, c_float(0.0))
)

标签: pythonglslctypespyopengl

解决方案


不能混合整数和浮点数,句号。即使有符号和无符号整数也不能在 OpenGL 中混合使用。因此,要么找到一种调用方式glUniform1i,要么使用layout(binding = 0)限定符。有关详细信息,请参阅OpenGL 维基


推荐阅读