pyopengl - 纹理未按应有的方式渲染

问题描述

original

这是原始的 2d 256x256 图像,我正在尝试在屏幕上制作纹理。但由于某种原因,它不会在没有 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR) 行的情况下进行渲染。当它的渲染因为 pic 是 2d 我发送 attrib 指针 uv is size of 2 with glVertexAttribPointer(attribute_texture,2,GL_FLOAT,GL_FALSE,None) 但事实证明是这样。

second

当我把它变成 3 只是为了尝试它是这样的

third

我尝试了什么并没有改变任何更好的 我在这里做错了什么?我真的可以用另一双眼睛。谢谢。 这是我的代码

import glfw
from OpenGL.GL import *
# from OpenGL.GL.shaders import compileShader,compileProgram
import numpy as np
from math import radians
from pyrr import matrix44,Vector3
from PIL import Image
# ----------------------------------------------------------------------
if not glfw.init():
    raise Exception("GLFW not initialized")
window = glfw.create_window(800,600,"personal",None,None)
if not window:
    glfw.terminate()
    raise Exception("window did not created")
glfw.set_window_pos(window,xpos=200,ypos=50)
glfw.make_context_current(window)
# ----------------------------------------------------------------------
vertices = np.array([-0.7,0.7,0.0,-0.7,0.0],dtype=np.float32)
indices = np.array([0,1,3,2],dtype=np.uint32)
# color = np.array([0.0,#                   0.0,dtype=np.float32)
texture_coord = np.array([0,0],dtype=np.uint32)
# --------------------------------------------------------------------- TRANSFORMATION CALculaTION
matrix = matrix44.create_identity(dtype=np.float32)
matrix = np.dot(matrix44.create_from_translation(Vector3([0.0,0.0])),matrix)
matrix = np.dot(matrix44.create_from_x_rotation(radians(0)),matrix)
matrix = np.dot(matrix44.create_from_y_rotation(radians(0)),matrix)
matrix = np.dot(matrix44.create_from_z_rotation(radians(0)),matrix)
matrix = np.dot(matrix44.create_from_scale(Vector3([1,1])),matrix)
# ---------------------------------------------------------------------
vertex_shader_src = """
#version 330 core
layout(location = 0)in vec3 position;
layout(location = 1)in vec2 texture;
//in vec3 color;//for using color equal it to toFColor
uniform mat4 trans;
out vec3 toFColor;
out vec2 passtexCoord;
void main(){
gl_Position = trans * vec4(position.x,position.y,position.z,1.0f);
//toFColor=color;
passtexCoord=texture;
}
"""
# ---------------------------------------------------------------------
fragment_shader_src = """
#version 330 core
//in vec3 toFColor;
in vec2 passtexCoord;
//uniform vec3 triColor;
uniform sampler2D texture_sampler;
out vec4 outColor;
void main(){
//outColor = vec4(toFColor,1.0);
outColor = texture(texture_sampler,passtexCoord);
}
"""
# ---------------------------------------------------------------------PyOpenGL working shader program
# shader_program = compileProgram(compileShader(vertex_shader_src,GL_VERTEX_SHADER),#                         compileShader(fragment_shader_src,GL_FRAGMENT_SHADER))
# ---------------------------------------------------------------------tutorial way shader program
vertex_shader_id = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vertex_shader_id,vertex_shader_src)
glCompileShader(vertex_shader_id)
if glGetShaderiv(vertex_shader_id,GL_COMPILE_STATUS) == GL_FALSE:
    print(glGetShaderInfoLog(vertex_shader_id))
    print("cant compile shader")
fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fragment_shader_id,fragment_shader_src)
glCompileShader(fragment_shader_id)
if glGetShaderiv(fragment_shader_id,GL_COMPILE_STATUS) == GL_FALSE:
    print(glGetShaderInfoLog(fragment_shader_id))
    print("cant compile shader")
shader_program = glCreateProgram()
glAttachShader(shader_program,vertex_shader_id)
glAttachShader(shader_program,fragment_shader_id)
glBindAttribLocation(shader_program,"position")
glBindAttribLocation(shader_program,"texture")
glLinkProgram(shader_program)
glValidateProgram(shader_program)
gluseProgram(shader_program)
# --------------------------------------------------------------------- my trying for VAO vertex positions
VAO = glGenVertexArrays(1)  # generate vao
glBindVertexArray(VAO)  # ready VAO to use
VBO1 = glGenBuffers(1)  # generate vbo
glBindBuffer(GL_ARRAY_BUFFER,VBO1)  # binding vbo for use
glBufferData(GL_ARRAY_BUFFER,vertices.nbytes,vertices,GL_STATIC_DRAW)  # setting VBO what to carry
attribute_position = glGetAttribLocation(shader_program,"position")  # taking attribute name position from shader
glEnabLevertexAttribArray(attribute_position)  # ready to use attribute
glVertexAttribPointer(attribute_position,None)  # telling OpenGL how to read data on given uniform
# ---------------------------------------------------------------------- indexing positions
EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER,indices.nbytes,indices,GL_STATIC_DRAW)
# ---------------------------------------------------------------------- coloring instead of texture
# i am closing this because i will use texture
# VBO2 = glGenBuffers(1)
# glBindBuffer(GL_ARRAY_BUFFER,VBO2)
# glBufferData(GL_ARRAY_BUFFER,color.nbytes,color,GL_STATIC_DRAW)
# attribute_color = glGetAttribLocation(shader_program,"color")  # taking uniform name color from shader
# glEnabLevertexAttribArray(attribute_color)  # ready to use uniform
# glVertexAttribPointer(attribute_color,#                       None)  # telling OpenGL how to read data on given attribute
# ---------------------------------------------------------------------- Texture pressing
TEX_BO = glGenTextures(1)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D,TEX_BO)
attribute_texture = glGetAttribLocation(shader_program,"texture")
glEnabLevertexAttribArray(attribute_texture)
glVertexAttribPointer(attribute_texture,None)
texture = Image.open("../res/pic1.png","r")
texture = texture.transpose(Image.FLIP_TOP_BottOM)
image_data = texture.convert("RGBA").tobytes()
glTexImage2D(GL_TEXTURE_2D,GL_RGBA,texture.width,texture.height,GL_UNSIGNED_BYTE,image_data)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT)
# Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D,GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
# ---------------------------------------------------------------------- TRANSFORMATION MATRIX -------------------------
loc_uniform_transformation = glGetUniformlocation(shader_program,"trans")
# ----------------------------------------------------------------------
while not glfw.window_should_close(window):
    glfw.poll_events()
    glClearColor(0.15,0.15,1.0)
    glClear(GL_COLOR_BUFFER_BIT)
    gluniformMatrix4fv(loc_uniform_transformation,matrix44.create_identity())
    glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,None)
    glfw.swap_buffers(window)
# ------------------------------------------------------------------------------ Cleaning
glDeleteTextures(1,int(TEX_BO))
glDetachShader(shader_program,vertex_shader_id)
glDetachShader(shader_program,fragment_shader_id)
glDeleteShader(vertex_shader_id)
glDeleteShader(fragment_shader_id)
glDeleteProgram(shader_program)
glDeleteBuffers(1,int(VBO1))
# glDeleteBuffers(1,int(VBO2)) # if use colors
glDeleteBuffers(1,int(EBO))
glDeleteVertexArrays(1,int(VAO))
# ------------------------------------------------------------------------------
glfw.destroy_window(window)
glfw.terminate()

解决方法

您必须设置 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR),因为默认的缩小功能是 GL_NEAREST_MIPMAP_LINEAR。由于您不生成 mipmap,如果您不将最小化函数更改为 GL_NEARESTGL_LINEAR,纹理将是“Mipmap Incomplete”。

纹理坐标数组的类型必须是np.float32而不是np.uint32

texture_coord = np.array([0,1,0],dtype=np.float32)

您错过了为纹理坐标创建缓冲区对象:

VBO2 = glGenBuffers(1)  # generate vbo
glBindBuffer(GL_ARRAY_BUFFER,VBO2)  # binding vbo for use
glBufferData(GL_ARRAY_BUFFER,texture_coord.nbytes,texture_coord,GL_STATIC_DRAW)

attribute_texture = glGetAttribLocation(shader_program,"texture")
glEnableVertexAttribArray(attribute_texture)
glVertexAttribPointer(attribute_texture,2,GL_FLOAT,GL_FALSE,None)

调用 glVertexAttribPointer 时,当前绑定到目标 GL_ARRAY_BUFFER 的缓冲区对象与指定的顶点属性相关联。