PyOpenGL 片段着色器纹理采样
PyOpenGL fragment shader texture sampling
好吧,谢天谢地,我对 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()
在 glsl 中,uniform 变量默认分别初始化为 0 和 0.0。所以纹理采样器uniform textureObj
的值也由(纹理单元)0初始化。
此外还有默认纹理对象 (0)。如果不创建并绑定命名纹理对象,那么默认纹理对象(0)仍然存在,glTexImage2D
指定默认纹理对象(0)的纹理图像。
参见 OpenGL 4.6 API Compatibility Profile Specification; 8.1 Texture Objects; page 179
Textures in GL are represented by named objects. The name space for texture objects is the unsigned integers, with zero reserved by the GL to represent the default texture object. The default texture object is bound to each of the TEXTURE_1D
, TEXTURE_2D
, TEXTURE_3D
, [...] targets during context initialization.
GLSL - The OpenGL Shading Language 4.6; 4.3.5. Uniform Variables; page 50
The uniform qualifier is used to declare global variables whose values are the same across the entire primitive being processed. All uniform variables are read-only and are initialized externally either at link time or through the API. The link-time initial value is either the value of the variable’s initializer, if present, or 0 if no initializer is present.
对了,glGenTextures
returns一个命名纹理对象,可以被glBindTexture
绑定。没有指定glGenTextures
生成的第一个命名纹理对象必须是1。它可以是任何id(数字)。
所以它必须是:
texID = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texID)
而不是
glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, 1)
好吧,谢天谢地,我对 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()
在 glsl 中,uniform 变量默认分别初始化为 0 和 0.0。所以纹理采样器uniform textureObj
的值也由(纹理单元)0初始化。
此外还有默认纹理对象 (0)。如果不创建并绑定命名纹理对象,那么默认纹理对象(0)仍然存在,glTexImage2D
指定默认纹理对象(0)的纹理图像。
参见 OpenGL 4.6 API Compatibility Profile Specification; 8.1 Texture Objects; page 179
Textures in GL are represented by named objects. The name space for texture objects is the unsigned integers, with zero reserved by the GL to represent the default texture object. The default texture object is bound to each of the
TEXTURE_1D
,TEXTURE_2D
,TEXTURE_3D
, [...] targets during context initialization.
GLSL - The OpenGL Shading Language 4.6; 4.3.5. Uniform Variables; page 50
The uniform qualifier is used to declare global variables whose values are the same across the entire primitive being processed. All uniform variables are read-only and are initialized externally either at link time or through the API. The link-time initial value is either the value of the variable’s initializer, if present, or 0 if no initializer is present.
对了,glGenTextures
returns一个命名纹理对象,可以被glBindTexture
绑定。没有指定glGenTextures
生成的第一个命名纹理对象必须是1。它可以是任何id(数字)。
所以它必须是:
texID = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texID)
而不是
glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, 1)