PyOpenGL片段着色器纹理采样

时间:2018-12-02 22:04:34

标签: python opengl pygame textures pyopengl

好的,谢谢,我对(几乎)现代工作中的 OpenGL 有了更深入的了解。但是有些事情我无法弄清。

即使我正确设置了片段着色器,如何也可以对我的纹理进行采样?我认为采样器会以某种方式自动获取纹理。但是如何?

我注释掉 glBindTexture(GL_TEXTURE_2D,1)后,纹理仍然显示。

*(由于我的Raspberry Pi,我正在使用GLSL 1.2。)

顶点着色器:

#version 120

attribute vec2 vPosition;
attribute vec2 vTexcoords;

varying vec2 fTexcoords;

void main()
{
    gl_Position = vec4(vPosition.x/1.33, vPosition.y, 0.0, 1.0);
    fTexcoords = vTexcoords;
}

片段着色器:

#version 120

varying vec2 fTexcoords;
uniform sampler2D textureObj;

void main()
{
    gl_FragColor = texture2D(textureObj, fTexcoords);
}

代码:

from OpenGL.GL import *
from OpenGL.GL.shaders import *

import pygame
from pygame.locals import *
import numpy, time, sys

def getFileContent(file):
    content = open(file, 'r').read()
    return content

def init():
    pygame.init()
    pygame.display.set_mode((640, 480), HWSURFACE | OPENGL | DOUBLEBUF)
    glViewport(0, 0, 640, 480)

    img = pygame.image.load("brick.jpg")
    textureData = pygame.image.tostring(img, "RGB", 1)
    width = img.get_width()
    height = img.get_height()
    #glGenTextures(1)
    #glBindTexture(GL_TEXTURE_2D, 1)
    glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    vertices = [-0.5, -0.5,
                -0.5, 0.5,
                0.5, 0.5,
                0.5, -0.5]

    texcoords = [0.0, 0.0,
                 0.0, 1.0,
                 1.0, 1.0,
                 1.0, 0.0]

    vertices = numpy.array(vertices, dtype=numpy.float32)
    texcoords = numpy.array(texcoords, dtype=numpy.float32)

    vertexShader = compileShader(getFileContent("helloTriangle.vert"), GL_VERTEX_SHADER)
    fragmentShader = compileShader(getFileContent("helloTriangle.frag"), GL_FRAGMENT_SHADER)

    global shaderProgram
    shaderProgram = glCreateProgram()
    glAttachShader(shaderProgram, vertexShader)
    glAttachShader(shaderProgram, fragmentShader)
    glLinkProgram(shaderProgram)

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices)
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texcoords)
    glEnableVertexAttribArray(0)
    glEnableVertexAttribArray(1)

    global texLocation
    texLocation = glGetUniformLocation(shaderProgram, "textureObj")

def main():
    init()

    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT: sys.exit()

        glClearColor(0.25, 0.25, 0.25, 1)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

        glUseProgram(shaderProgram)
        #glUniform1i(texLocation, 0)
        glDrawArrays(GL_QUADS, 0, 4)

        pygame.display.flip()

main()

1 个答案:

答案 0 :(得分:3)

在glsl中,统一变量默认分别初始化为0和0.0。因此,纹理采样器统一textureObj的值也将由(纹理单位)0初始化。

此外,还有默认的纹理对象(0)。如果不创建和绑定命名的纹理对象,则仍然存在默认纹理对象(0),而glTexImage2D指定默认纹理对象的纹理图像(0)。

请参见OpenGL 4.6 API Compatibility Profile Specification; 8.1 Texture Objects; page 179

  

GL中的纹理由命名对象表示。纹理对象的名称空间是无符号整数, GL保留零以表示默认纹理对象默认纹理对象在上下文中绑定到每个 TEXTURE_1D TEXTURE_2D TEXTURE_3D,[...]目标初始化。

GLSL - The OpenGL Shading Language 4.6; 4.3.5. Uniform Variables; page 50

  

统一限定符用于声明全局变量,其值在整个正在处理的原语中相同。 所有统一变量均为只读,并且可以在链接时或通过API在外部进行初始化链接时初始值是变量的初始化程序的值(如果存在),或者是0(如果没有初始化程序的话)


顺便说一句,glGenTextures返回一个命名纹理对象,该对象可以与glBindTexture绑定。未指定glGenTextures生成的第一个命名纹理对象必须为1。它可以是任何id(数字)。

因此必须是:

texID = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texID)

代替

glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, 1)