gpt4 book ai didi

python - 绘制时翻转纹理pyopengl

转载 作者:行者123 更新时间:2023-12-04 01:14:49 26 4
gpt4 key购买 nike

我最近下载了一个使用pyOpenGl和pygame的批量渲染程序。我想编辑绘图功能,以便在绘制时能够翻转纹理。这是批量渲染程序的代码。

import numpy
from OpenGL import GL
from OpenGL.GL import shaders
import ctypes

def setup_shaders(vpMatrix):
global shaderProgram, vshader, fshader
global texCoordAttribute, positionAttribute

vshader = shaders.compileShader('''#version 440

layout (location = 0) uniform mat4 vpMatrix;

layout (location = 0) in vec2 vPosition;
layout (location = 1) in vec2 vTexCoord0;
//layout (location = 2) in vec4 vVertColor;

out vec2 texCoord0;
//out vec4 vertColor;

void main(void) {
gl_Position = vpMatrix * vec4(vPosition, 0.0, 1.0);
texCoord0 = vTexCoord0;
}''', GL.GL_VERTEX_SHADER)

fshader = shaders.compileShader('''#version 440

in vec2 texCoord0;
//in vec4 vertColor;
layout (location = 1) uniform sampler2D u_texture0;

void main(void) {
gl_FragColor = texture2D(u_texture0, texCoord0);
}''', GL.GL_FRAGMENT_SHADER)

shaderProgram = shaders.compileProgram(vshader, fshader)

texCoordAttribute = GL.glGetAttribLocation(shaderProgram, 'vTexCoord0')
positionAttribute = GL.glGetAttribLocation(shaderProgram, 'vPosition')
texUniform = GL.glGetUniformLocation(shaderProgram, 'u_texture0')

GL.glEnableVertexAttribArray(positionAttribute)
GL.glEnableVertexAttribArray(texCoordAttribute)

GL.glUseProgram(shaderProgram)

GL.glUniformMatrix4fv(
GL.glGetUniformLocation(shaderProgram, 'vpMatrix'),
1,
False,
vpMatrix,
)
GL.glUniform1i(texUniform, 0)

# TODO: cleanup (delete shaders)

class GLTexture:
def __init__(self, textureId, width, height):
self.texture = textureId
self.width, self.height = width, height

def delete(self):
GL.glDeleteTextures([self.texture])

class GLTextureRegion:
def __init__(self, glTexture, subX, subY, subWidth, subHeight):
self.texture = glTexture
#self.tx, self.ty = subX, subY
self.tw, self.th = subWidth, subHeight

self.normalizedCoords = (
subX / glTexture.width, subY / glTexture.height,
(subX + subWidth) / glTexture.width, subY / glTexture.height,
subX / glTexture.width, (subY + subHeight) / glTexture.height,
(subX + subWidth) / glTexture.width, (subY + subHeight) / glTexture.height,
)

def write_tex_coords(self, aj):
nc = self.normalizedCoords
aj[4 * 0 + 2] = nc[0]
aj[4 * 0 + 3] = nc[1]
aj[4 * 1 + 2] = nc[2]
aj[4 * 1 + 3] = nc[3]
aj[4 * 2 + 2] = nc[4]
aj[4 * 2 + 3] = nc[5]
aj[4 * 3 + 2] = nc[6]
aj[4 * 3 + 3] = nc[7]

def write_vertices(self, aj, x, y):
aj[4 * 0 + 0] = x
aj[4 * 0 + 1] = y
aj[4 * 1 + 0] = x + self.tw
aj[4 * 1 + 1] = y
aj[4 * 2 + 0] = x
aj[4 * 2 + 1] = y + self.th
aj[4 * 3 + 0] = x + self.tw
aj[4 * 3 + 1] = y + self.th

def update_array(self, vboData, arrayIndex, x, y):
aj = vboData[arrayIndex]
self.write_vertices(aj, x, y)
self.write_tex_coords(aj)

def delete(self):
'''deletes the underlying texture'''
self.texture.delete()

class Batch:
def __init__(self, maxQuads = 10000):
self.maxQuads = maxQuads

self.vboIndices = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.vboIndices)
vidA = []
for i in range(maxQuads):
vidA.extend([
4 * i + 0,
4 * i + 2,
4 * i + 1,
4 * i + 2,
4 * i + 1,
4 * i + 3
])
self.vboIndexData = numpy.array(vidA, numpy.ushort)
del vidA
GL.glBufferData(
GL.GL_ELEMENT_ARRAY_BUFFER,
self.vboIndexData,
GL.GL_STATIC_DRAW,
)

self.vbo = GL.glGenBuffers(1) # texture coords & vertices
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
self.vboData = numpy.zeros((maxQuads, 4 * 4), numpy.float32)
GL.glBufferData(
GL.GL_ARRAY_BUFFER,
self.vboData,
GL.GL_DYNAMIC_DRAW
)

self.currentTexture = None
self.objectIndex = 0

def begin(self):
GL.glBindBuffer(
GL.GL_ARRAY_BUFFER,
self.vbo,
)
if self.currentTexture:
GL.glBindTexture(
GL.GL_TEXTURE_2D,
self.currentTexture.texture,
)
GL.glEnable(GL.GL_TEXTURE_2D)
GL.glActiveTexture(GL.GL_TEXTURE0)

def draw(self, textureRegion, x, y, flip = False):


if self.currentTexture != textureRegion.texture:
self.flush()
self.currentTexture = textureRegion.texture
GL.glBindTexture(
GL.GL_TEXTURE_2D,
textureRegion.texture.texture,
)
elif self.objectIndex >= self.maxQuads:
self.flush()

textureRegion.update_array(
self.vboData,
self.objectIndex,
x, y
)

self.objectIndex += 1

def end(self):
self.flush()

def flush(self):
if not self.objectIndex:
return
GL.glVertexAttribPointer(
texCoordAttribute,
2,
GL.GL_FLOAT,
GL.GL_TRUE,
4 * self.vboData.itemsize,
ctypes.c_void_p(2 * self.vboData.itemsize)
)
GL.glVertexAttribPointer(
positionAttribute,
2,
GL.GL_FLOAT,
GL.GL_FALSE,
4 * self.vboData.itemsize,
ctypes.c_void_p(0)
)
GL.glBufferSubData(
GL.GL_ARRAY_BUFFER,
0,
16 * self.objectIndex * self.vboData.itemsize,
self.vboData,
)
GL.glDrawElements(
GL.GL_TRIANGLES,
6 * self.objectIndex,
GL.GL_UNSIGNED_SHORT,
ctypes.c_void_p(0),
)
self.objectIndex = 0

def delete(self):
GL.glDeleteBuffers(1, [self.vbo])
GL.glDeleteBuffers(1, [self.vboIndices])

到目前为止,我已经尝试了一些涉及 glscalef 的操作(正如我在互联网上找到的答案所建议的那样),但是我无法让它对纹理产生任何影响。有没有办法在绘图函数中实现此功能,还是我必须完全尝试另一种方法?

最佳答案

您可以在顶点着色器中“翻转”纹理坐标的 y 分量:

void main(void) {
// [...]

texCoord0 = vec2(vTexCoord0.x, 1.0 - vTexCoord0.y);
}

如果你想“翻转”单独的纹理,那么你翻转纹理坐标属性。将 TrueFalse 传递给参数 flipY:

class GLTextureRegion:
# [...]

def write_tex_coords(self, aj, flipY):
nc = self.normalizedCoords
for i in range(4):
aj[i*4 + 2] = nc[i*2]
aj[i*4 + 3] = 1-nc[i*2 + 1] if flipY else nc[i*2 + 1]

# [...]

def update_array(self, vboData, arrayIndex, x, y, flipY):
aj = vboData[arrayIndex]
self.write_vertices(aj, x, y)
self.write_tex_coords(aj, flipY)

或者,您可以在顶点着色器中通过统一缩放纹理坐标。初始化制服

layout (location = 0) uniform mat4 vpMatrix;
layout (location = 1) uniform vec2 uTexCoordScale;

layout (location = 0) in vec2 vPosition;
layout (location = 1) in vec2 vTexCoord0;

out vec2 texCoord0;

void main(void)
{
gl_Position = vpMatrix * vec4(vPosition, 0.0, 1.0);
texCoord0 = uTexCoordScale * vTexCoord0;
}

用 (1.0, 1.0) 初始化统一的 uTexCoordScale,如果你想“翻转”纹理,将它更改为 (1.0, -1.0)。

关于python - 绘制时翻转纹理pyopengl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63691526/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com