Stencil 测试不剪裁 Texture
Stencil test does not clip Texture
我正在尝试使用模板测试裁剪纹理。
这个想法是创建一个表面(在这个例子中是一个简单的矩形)到 select 要显示的纹理区域(如下图)
我为此创建了一个简单的代码,首先执行始终模板测试以将模板缓冲区上的所有位设置为 2,然后将测试更改为 KEEP,我认为这会输出所需的结果, 但什么也没发生
import pygame
import sys
from OpenGL.GL import *
from pygame.locals import *
# set pygame screen
pygame.display.set_mode((1000, 500), OPENGL | DOUBLEBUF)
info = pygame.display.Info()
# basic opengl configuration
glViewport(0, 0, info.current_w, info.current_h)
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
# set up texturing
glEnable(GL_TEXTURE_2D)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
# load texture
surf = pygame.image.load('Player1.png')
s = pygame.image.tostring(surf, 'RGBA')
texID = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texID)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf.get_width(), surf.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, s)
glGenerateMipmap(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, 0)
# create pygame clock
MAINCLOCK = pygame.time.Clock()
# init screen
pygame.display.init()
while True:
# get quit event
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# prepare to render screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
# Enable stencil test
glEnable(GL_STENCIL_TEST)
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)
glStencilFunc(GL_ALWAYS, 2, ~0)
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE)
# draw rectangle
glDisable(GL_TEXTURE_2D)
glColor3fv((0, 0, 0))
glRectf(-1, 1, 0, 0.5)
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
glStencilFunc(GL_EQUAL, 2, ~0)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
# draw texture
glEnable(GL_TEXTURE_2D)
glColor3fv((1, 1, 1))
glBindTexture(GL_TEXTURE_2D, texID)
glBegin(GL_QUADS)
glTexCoord2f(0, 0); glVertex2f(-1, -1)
glTexCoord2f(0, 1); glVertex2f(-1, 1)
glTexCoord2f(1, 1); glVertex2f(1, 1)
glTexCoord2f(1, 0); glVertex2f(1, -1)
glEnd()
# disable stencil test
glDisable(GL_STENCIL_TEST)
pygame.display.flip()
MAINCLOCK.tick(60)
我错过了什么?
提前致谢
模板测试已正确实施,但您在初始化 PyGame OpenGL window 时忘记设置模板缓冲区的大小。在您的情况下,模板测试不起作用,因为没有模板缓冲区。
可以通过使用方法 pygame.display.gl_set_attribute
设置 GL_STENCIL_SIZE
属性来设置 stecil 缓冲区
将以下内容添加到您的代码中:
pygame.display.init()
pygame.display.gl_set_attribute(GL_STENCIL_SIZE, 8)
pygame.display.set_mode((1000, 500), OPENGL | DOUBLEBUF)
我正在尝试使用模板测试裁剪纹理。 这个想法是创建一个表面(在这个例子中是一个简单的矩形)到 select 要显示的纹理区域(如下图)
我为此创建了一个简单的代码,首先执行始终模板测试以将模板缓冲区上的所有位设置为 2,然后将测试更改为 KEEP,我认为这会输出所需的结果, 但什么也没发生
import pygame
import sys
from OpenGL.GL import *
from pygame.locals import *
# set pygame screen
pygame.display.set_mode((1000, 500), OPENGL | DOUBLEBUF)
info = pygame.display.Info()
# basic opengl configuration
glViewport(0, 0, info.current_w, info.current_h)
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
# set up texturing
glEnable(GL_TEXTURE_2D)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
# load texture
surf = pygame.image.load('Player1.png')
s = pygame.image.tostring(surf, 'RGBA')
texID = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texID)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf.get_width(), surf.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, s)
glGenerateMipmap(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, 0)
# create pygame clock
MAINCLOCK = pygame.time.Clock()
# init screen
pygame.display.init()
while True:
# get quit event
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# prepare to render screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
# Enable stencil test
glEnable(GL_STENCIL_TEST)
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)
glStencilFunc(GL_ALWAYS, 2, ~0)
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE)
# draw rectangle
glDisable(GL_TEXTURE_2D)
glColor3fv((0, 0, 0))
glRectf(-1, 1, 0, 0.5)
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
glStencilFunc(GL_EQUAL, 2, ~0)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
# draw texture
glEnable(GL_TEXTURE_2D)
glColor3fv((1, 1, 1))
glBindTexture(GL_TEXTURE_2D, texID)
glBegin(GL_QUADS)
glTexCoord2f(0, 0); glVertex2f(-1, -1)
glTexCoord2f(0, 1); glVertex2f(-1, 1)
glTexCoord2f(1, 1); glVertex2f(1, 1)
glTexCoord2f(1, 0); glVertex2f(1, -1)
glEnd()
# disable stencil test
glDisable(GL_STENCIL_TEST)
pygame.display.flip()
MAINCLOCK.tick(60)
我错过了什么?
提前致谢
模板测试已正确实施,但您在初始化 PyGame OpenGL window 时忘记设置模板缓冲区的大小。在您的情况下,模板测试不起作用,因为没有模板缓冲区。
可以通过使用方法 pygame.display.gl_set_attribute
GL_STENCIL_SIZE
属性来设置 stecil 缓冲区
将以下内容添加到您的代码中:
pygame.display.init()
pygame.display.gl_set_attribute(GL_STENCIL_SIZE, 8)
pygame.display.set_mode((1000, 500), OPENGL | DOUBLEBUF)