Выборка текстуры фрагмента шейдера PyOpenGL - PullRequest
0 голосов
/ 03 декабря 2018

Хорошо, ребята, к счастью, у меня есть немного более глубокое понимание того, как OpenGL в (почти) современной работе.Но есть кое-что, что я не могу понять.

Как фрагментный шейдер может сэмплировать мою текстуру, даже если я ее пропустил, правильно настроил?Я думаю, что как-то сэмплер автоматически получит текстуру.Но как?

После того, как я закомментировал glBindTexture (GL_TEXTURE_2D, 1) текстура все еще обнаружилась.

* (я использую GLSL 1.2 из-за моего Raspberry Pi.)

Вершинный шейдер:

#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 голосов
/ 03 декабря 2018

В glsl стандартные переменные по умолчанию инициализируются 0 соответственно 0.0.Таким образом, значение равномерного сэмплера текстуры textureObj также инициализируется (единица текстуры) 0.

Далее есть объект текстуры по умолчанию (0).Если вы не создаете и не связываете именованный объект текстуры, то по-прежнему существует объект текстуры по умолчанию (0), а glTexImage2D задает изображение текстуры объекта текстуры по умолчанию (0).

См. Спецификация профиля совместимости API OpenGL 4.6;8.1. Объекты текстуры;страница 179

Текстуры в GL представлены именованными объектами.Пространство имен для объектов текстуры представляет собой целые числа без знака, с нулем, зарезервированным GL для представления объекта текстуры по умолчанию . Объект текстуры по умолчанию привязан к каждой из TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, [...] во время инициализации контекста.

GLSL - Язык затенения OpenGL 4.6;4.3.5.Равномерные переменные;стр. 50

Универсальный квалификатор используется для объявления глобальных переменных, значения которых одинаковы во всем обрабатываемом примитиве. Все универсальные переменные доступны только для чтения и инициализируются извне либо во время соединения, либо через API . Начальное значение времени соединения - это либо значение инициализатора переменной, если оно есть, либо 0, если инициализатор отсутствует .


Кстати, glGenTextures возвращает именованный объект текстуры, который может быть связан glBindTexture.Не указывается, что 1-й именованный объект текстуры, который генерируется glGenTextures, должен быть 1. Это может быть любой идентификатор (число).

Так должно быть:

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

вместо

glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, 1)

...