PyOpenGL передает переменную в вершинный шейдер - PullRequest
0 голосов
/ 26 ноября 2018

После нескольких предложений я решил немного изучить OpenGL с трудом.Я попытался передать переменную (float - myAttrib) вершинному шейдеру, и она, похоже, сработала (строка 33), но, очевидно, не работает.Позже я хотел бы разделить код на следующие части.

Код:

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

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

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

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

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

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

    myAttrib = 0.3

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

    shaderProgram = glCreateProgram()
    glAttachShader(shaderProgram, vertexShader)
    glAttachShader(shaderProgram, fragmentShader)
    glBindAttribLocation(shaderProgram, 1, "myAttrib")
    glLinkProgram(shaderProgram)

    print(glGetAttribLocation(shaderProgram, "myAttrib"))

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

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

    glUseProgram(shaderProgram)
    glDrawArrays(GL_TRIANGLES, 0, 3)

    pygame.display.flip()
    time.sleep(2)

initDraw()

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

#version 130

attribute vec2 vPosition;
attribute float myAttrib;

void main()
{
    gl_Position = vec4(vPosition.x, vPosition.y + myAttrib, 0.0, 1.0);
}

Фрагмент шейдера:

#version 130

void main()
{
    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);            
}

1 Ответ

0 голосов
/ 26 ноября 2018

Если вы используете атрибут, вы должны определить массив общих атрибутов вершины, с одним значением атрибута на координату вершины (3 в вашем случае).См. Спецификация вершины .
Если вы используете униформу, вы можете установить одно значение для программы, хранящейся в универсальной переменной в унифицированном блоке по умолчанию (вы можете представить это как глобальную переменную),См. Uniform (GLSL) :

Case 1 - Атрибут myAttrib:

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

#version 130

attribute vec2 vPosition;
attribute float myAttrib;

void main()
{
    gl_Position = vec4(vPosition.x, vPosition.y + myAttrib, 0.0, 1.0);
}

Вы должны определить массив общих атрибутов вершин, как вы это делаете для координат вершин:

attrib = [-0.2, 0.2, 0.0]
myAttrib  = numpy.array(attrib, dtype = numpy.float32)

# .....

glLinkProgram(shaderProgram)
myAttrib_location = glGetAttribLocation(shaderProgram, "myAttrib")

# .....

glVertexAttribPointer(myAttrib_location, 1, GL_FLOAT, GL_FALSE, 0, myAttrib)
glEnableVertexAttribArray(myAttrib_location)

или

glBindAttribLocation(shaderProgram, 1, "myAttrib")
glLinkProgram(shaderProgram)

# .....

glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, myAttrib)
glEnableVertexAttribArray(1)

Случай 2 - УнифицированныйmyUniform

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

#version 130

attribute vec2 vPosition;
uniform float myUniform;

void main()
{
    gl_Position = vec4(vPosition.x, vPosition.y + myUniform, 0.0, 1.0);
}

Получить местоположение униформы ("myUniform") с помощью glGetUniformLocationи установите значение в форму: glUniform:

myUniform = 0.3

# .....

glLinkProgram(shaderProgram)
myUniform_location = glGetUniformLocation(shaderProgram, "myUniform")

# .....

glUseProgram(shaderProgram)
glUniform1f(myUniform_location, myUniform)

glDrawArrays(GL_TRIANGLES, 0, 3)
...