>source

OpenGL 프로그램의 배경으로 wood.jpg를 사용하고 싶습니다. 이 프로그램이 그림과 같이 basketball.obj 모델도 보여주고 싶습니다.

몇 가지 튜토리얼 (Youtube channels sentdex, atibyte, The Cherno)을 읽었습니다. 또한 웹 사이트 learnopengl.com, opengl-tutorial.org 및 codeloop.com을 사용해 보았습니다. Udemy도 사용했습니다. 이들 중 어느 것도 .obj 모델의 배경으로 .jpg를 사용하는 방법을 구체적으로 보여주지 않습니다.

메인 코드 내에 정의 된 여러 모델에 대한 코드를 실행할 수 있습니다. 여러 .obj 파일에 대한 코드를 실행할 수도 있습니다. 하지만 동시에 둘 다 실행할 수있는 코드 실행에 실패했습니다.

누군가 나를 도울 수 있습니까? Python 용 OpenGL C ++ 및 pyOpenGL로 코딩 할 수 있습니다.

지금까지 wood.jpg 이미지를 배경으로 표시 한 유일한 성공은 다음과 같습니다.

#Code modified from https://codeloop.org/python-modern-opengl-texturing-rectangle/
import glfw
from OpenGL.GL import *
import OpenGL.GL.shaders
import numpy as np
from PIL import Image
def main():
    if not glfw.init():
        return
    window = glfw.create_window(720, 600, "Pyopengl Texturing Rectangle", None, None)
    if not window:
        glfw.terminate()
        return
    glfw.make_context_current(window)
    # positions        colors               texture coords
    rectangle = [-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
                 1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
                 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
                 -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0]
    # convert to 32bit float
    rectangle = np.array(rectangle, dtype=np.float32)
    indicesRectange = [0, 1, 2,
               2, 3, 0]
    indicesRectange = np.array(indicesRectange, dtype=np.uint32)
    VERTEX_SHADER = """
           #version 330
           in vec3 position;
           in vec3 color;
           in vec2 InTexCoords;
           out vec3 newColor;
           out vec2 OutTexCoords;
           void main() {
            gl_Position = vec4(position, 1.0);
            newColor = color;
            OutTexCoords = InTexCoords;
             }
       """
    FRAGMENT_SHADER = """
        #version 330
         in vec3 newColor;
         in vec2 OutTexCoords;
         out vec4 outColor;
         uniform sampler2D samplerTex;
        void main() {
           outColor = texture(samplerTex, OutTexCoords);
        }
    """
    # Compile The Program and shaders
    shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(VERTEX_SHADER, GL_VERTEX_SHADER),
                                              OpenGL.GL.shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER))
    # Create Buffer object in gpu
    VBO = glGenBuffers(1)
    # Bind the buffer
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, 128, rectangle, GL_STATIC_DRAW)
    # Create EBO
    EBO = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesRectange, GL_STATIC_DRAW)
    # get the position from  shader
    #position = glGetAttribLocation(shader, 'position')
    position = 0
    glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
    glEnableVertexAttribArray(position)
    # get the color from  shader
    #color = glGetAttribLocation(shader, 'color')
    color = 1
    glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
    glEnableVertexAttribArray(color)
    #texCoords = glGetAttribLocation(shader, "InTexCoords")
    texCoords = 2
    glVertexAttribPointer(texCoords, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
    glEnableVertexAttribArray(texCoords)
    glBindAttribLocation(shader, position, 'position' )
    glBindAttribLocation(shader, color, 'color' )
    glBindAttribLocation(shader, texCoords, 'InTexCoords' )
    # Creating Texture
    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)
    # texture wrapping params
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    # texture filtering params
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    image = Image.open("wood.jpg")
    img_data = np.array(list(image.getdata()), np.uint8)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
    glUseProgram(shader)
    glClearColor(1.0, 0.0, 0.0, 1.0)
    while not glfw.window_should_close(window):
        glfw.poll_events()
        glClear(GL_COLOR_BUFFER_BIT)
        # Draw Rectangle
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
        glfw.swap_buffers(window)
    glfw.terminate()
if __name__ == "__main__":
    main()

[업데이트] 이것은 내가 시도한 마지막 코드입니다. 텍스처 튜토리얼의 코드와 오브젝트 로더 튜토리얼의 코드를 결합합니다.

# Object loading code by AtiBYte - OpenGL in python e15 - loading 3D .obj files. Youtube
# Background Texture loading code modified from CodeLoop.org https://codeloop.org/python-modern-opengl-texturing-rectangle/
import glfw
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram, compileShader
import pyrr
from TextureLoader import load_texture
from ObjLoader import ObjLoader
# imports for background texture
import numpy as np
from PIL import Image
############## Background Texture ######################
# positions        colors               texture coords
rectangle = [-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
             1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
             1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
             -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0]
# convert to 32bit float
rectangle = np.array(rectangle, dtype=np.float32)
indicesBackground = [0, 1, 2,
                     2, 3, 0]
indicesBackground = np.array(indicesBackground, dtype=np.uint32)
VERTEX_SHADER = """
       #version 330
       in vec3 position;
       in vec3 color;
       in vec2 InTexCoords;
       out vec3 newColor;
       out vec2 OutTexCoords;
       void main() {
        gl_Position = vec4(position, 1.0);
        newColor = color;
        OutTexCoords = InTexCoords;
         }
   """
FRAGMENT_SHADER = """
    #version 330
     in vec3 newColor;
     in vec2 OutTexCoords;
     out vec4 outColor;
     uniform sampler2D samplerTex;
    void main() {
       outColor = texture(samplerTex, OutTexCoords);
    }
"""
########################################################
vertex_src = """
# version 330
layout(location = 0) in vec3 a_position;
layout(location = 1) in vec2 a_texture;
layout(location = 2) in vec3 a_normal;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
out vec2 v_texture;
void main()
{
    gl_Position = projection * view * model * vec4(a_position, 1.0);
    v_texture = a_texture;
}
"""
fragment_src = """
# version 330
in vec2 v_texture;
out vec4 out_color;
uniform sampler2D s_texture;
void main()
{
    out_color = texture(s_texture, v_texture);
}
"""
# glfw callback functions
def window_resize(window, width, height):
    glViewport(0, 0, width, height)
    projection = pyrr.matrix44.create_perspective_projection_matrix(45, width / height, 0.1, 100)
    glUniformMatrix4fv(proj_loc, 1, GL_FALSE, projection)
# initializing glfw library
if not glfw.init():
    raise Exception("glfw can not be initialized!")
# creating the window
window = glfw.create_window(1280, 720, "My OpenGL window", None, None)
# check if window was created
if not window:
    glfw.terminate()
    raise Exception("glfw window can not be created!")
# set window's position
glfw.set_window_pos(window, 400, 200)
# set the callback function for window resize
glfw.set_window_size_callback(window, window_resize)
# make the context current
glfw.make_context_current(window)
# load here the 3d meshes
chibi_indices, chibi_buffer = ObjLoader.load_model("meshes/chibi.obj")
monkey_indices, monkey_buffer = ObjLoader.load_model("meshes/monkey.obj")
shaderObj = compileProgram(compileShader(vertex_src, GL_VERTEX_SHADER), compileShader(fragment_src, GL_FRAGMENT_SHADER))
# VAO and VBO
VAO = glGenVertexArrays(2)
VBO = glGenBuffers(3) #edited from 2 to 3 for background texture
# EBO = glGenBuffers(1)
# Chibi VAO
glBindVertexArray(VAO[0])
# Chibi Vertex Buffer Object
glBindBuffer(GL_ARRAY_BUFFER, VBO[0])
glBufferData(GL_ARRAY_BUFFER, chibi_buffer.nbytes, chibi_buffer, GL_STATIC_DRAW)
# glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
# glBufferData(GL_ELEMENT_ARRAY_BUFFER, chibi_indices.nbytes, chibi_indices, GL_STATIC_DRAW)
# chibi vertices
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, chibi_buffer.itemsize * 8, ctypes.c_void_p(0))
# chibi textures
glEnableVertexAttribArray(1)
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, chibi_buffer.itemsize * 8, ctypes.c_void_p(12))
# chibi normals
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, chibi_buffer.itemsize * 8, ctypes.c_void_p(20))
glEnableVertexAttribArray(2)
# Monkey VAO
glBindVertexArray(VAO[1])
# Monkey Vertex Buffer Object
glBindBuffer(GL_ARRAY_BUFFER, VBO[1])
glBufferData(GL_ARRAY_BUFFER, monkey_buffer.nbytes, monkey_buffer, GL_STATIC_DRAW)
# monkey vertices
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, monkey_buffer.itemsize * 8, ctypes.c_void_p(0))
# monkey textures
glEnableVertexAttribArray(1)
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, monkey_buffer.itemsize * 8, ctypes.c_void_p(12))
# monkey normals
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, monkey_buffer.itemsize * 8, ctypes.c_void_p(20))
glEnableVertexAttribArray(2)
############### Background Texture #################################
# Bind the buffer
glBindBuffer(GL_ARRAY_BUFFER, VBO[2])
glBufferData(GL_ARRAY_BUFFER, 128, rectangle, GL_STATIC_DRAW)
# Create EBO
EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBackground, GL_STATIC_DRAW)
# get the position from  shader
position = glGetAttribLocation(shaderObj, 'position')
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
glEnableVertexAttribArray(position)
# get the color from  shader
# color = glGetAttribLocation(shader, 'color')
color = 1
glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
glEnableVertexAttribArray(color)
# texCoords = glGetAttribLocation(shader, "InTexCoords")
texCoords = 2
glVertexAttribPointer(texCoords, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
glEnableVertexAttribArray(texCoords)
glBindAttribLocation(shaderObj, position, 'position')
glBindAttribLocation(shaderObj, color, 'color')
glBindAttribLocation(shaderObj, texCoords, 'InTexCoords')
# Creating Texture
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)
# texture wrapping params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# texture filtering params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
image = Image.open("wood.jpg")
img_data = np.array(list(image.getdata()), np.uint8)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
#####################################################################
textures = glGenTextures(2)
load_texture("meshes/chibi.png", textures[0])
load_texture("meshes/monkey.jpg", textures[1])
glUseProgram(shaderObj)
glClearColor(0, 0.1, 0.1, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
projection = pyrr.matrix44.create_perspective_projection_matrix(45, 1280 / 720, 0.1, 100)
chibi_pos = pyrr.matrix44.create_from_translation(pyrr.Vector3([0, -5, -10]))
monkey_pos = pyrr.matrix44.create_from_translation(pyrr.Vector3([-4, 0, 0]))
# eye, target, up
view = pyrr.matrix44.create_look_at(pyrr.Vector3([0, 0, 8]), pyrr.Vector3([0, 0, 0]), pyrr.Vector3([0, 1, 0]))
model_loc = glGetUniformLocation(shaderObj, "model")
proj_loc = glGetUniformLocation(shaderObj, "projection")
view_loc = glGetUniformLocation(shaderObj, "view")
glUniformMatrix4fv(proj_loc, 1, GL_FALSE, projection)
glUniformMatrix4fv(view_loc, 1, GL_FALSE, view)
# the main application loop
while not glfw.window_should_close(window):
    glfw.poll_events()
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    rot_y = pyrr.Matrix44.from_y_rotation(0.8 * glfw.get_time())
    model = pyrr.matrix44.multiply(rot_y, chibi_pos)
    # draw the chibi character
    glBindVertexArray(VAO[0])
    glBindTexture(GL_TEXTURE_2D, textures[0])
    glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)
    glDrawArrays(GL_TRIANGLES, 0, len(chibi_indices))
    rot_y = pyrr.Matrix44.from_y_rotation(-0.8 * glfw.get_time())
    model = pyrr.matrix44.multiply(rot_y, monkey_pos)
    # draw the monkey head
    glBindVertexArray(VAO[1])
    glBindTexture(GL_TEXTURE_2D, textures[1])
    glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)
    glDrawArrays(GL_TRIANGLES, 0, len(monkey_indices))
    # Draw Background Texture
    glDrawElements(GL_TRIANGLES, len(chibi_indices), GL_UNSIGNED_INT, None)
    glfw.swap_buffers(window)
# terminate glfw, free up allocated resources
glfw.terminate()

  • 답변 # 1

    2 개의 셰이더 프로그램이 있으므로 두 셰이더 프로그램을 모두 컴파일해야하며 다음 방법으로 지오메트리를 그리기 전에 셰이더 프로그램을 설치해야합니다. glUseProgram :

    shaderObj = compileProgram(compileShader(vertex_src, GL_VERTEX_SHADER), compileShader(fragment_src, GL_FRAGMENT_SHADER))
    shaderObjBackground = compileProgram(compileShader(VERTEX_SHADER, GL_VERTEX_SHADER), compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER))
    
    

    ############### Background Texture #################################
    backgroundVAO = glGenVertexArrays(1)
    glBindVertexArray(backgroundVAO)
    # Bind the buffer
    glBindBuffer(GL_ARRAY_BUFFER, VBO[2])
    glBufferData(GL_ARRAY_BUFFER, 128, rectangle, GL_STATIC_DRAW)
    # Create EBO
    EBO = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBackground, GL_STATIC_DRAW)
    # get the position from  shader
    position = glGetAttribLocation(shaderObjBackground, 'position')
    glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
    glEnableVertexAttribArray(position)
    # get the color from  shader
    color = glGetAttribLocation(shaderObjBackground, 'color')
    glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
    glEnableVertexAttribArray(color)
    texCoords = glGetAttribLocation(shaderObjBackground, "InTexCoords")
    glVertexAttribPointer(texCoords, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
    glEnableVertexAttribArray(texCoords)
    
    

    # the main application loop
    while not glfw.window_should_close(window):
        glfw.poll_events()
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glUseProgram(shaderObj)
        rot_y = pyrr.Matrix44.from_y_rotation(0.8 * glfw.get_time())
        model = pyrr.matrix44.multiply(rot_y, chibi_pos)
        # draw the chibi character
        glBindVertexArray(VAO[0])
        glBindTexture(GL_TEXTURE_2D, textures[0])
        glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)
        glDrawArrays(GL_TRIANGLES, 0, len(chibi_indices))
        rot_y = pyrr.Matrix44.from_y_rotation(-0.8 * glfw.get_time())
        model = pyrr.matrix44.multiply(rot_y, monkey_pos)
        # draw the monkey head
        glBindVertexArray(VAO[1])
        glBindTexture(GL_TEXTURE_2D, textures[1])
        glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)
        glDrawArrays(GL_TRIANGLES, 0, len(monkey_indices))
    
        glUseProgram(shaderObjBackground)
        # Draw Background Texture
        glBindVertexArray(backgroundVAO)
        glBindTexture(GL_TEXTURE_2D, texture)
        glDrawElements(GL_TRIANGLES, len(chibi_indices), GL_UNSIGNED_INT, None)
        glfw.swap_buffers(window)
    
    

    <시간 />

    배경 텍스처가 항상 다른 모든 지오메트리의 뒤에 있는지 확인합니다.

    z 좌표를 1.0 인치에 가까운 값으로 설정하여이를 수행 할 수 있습니다. VERTEX_SHADER 정점 셰이더 :

    gl_Position = vec4(position, 1.0);

    gl_Position = vec4(position.xy, 0.999, 1.0);
    
    

    또는 깊이 테스트 기능을 다음으로 변경할 수 있습니다. GL_LEQUAL 배경 질감을 그릴 때

    glDepthFunc(GL_LEQUAL)
    
    

    클립 공간 z 좌표를 w 구성 요소와 동일하게 설정합니다. 예를 들면 :

    gl_Position = vec4(position, 1.0);
    gl_Position.z = gl_Position.w;
    
    

  • 이전 javascript : 뷰어 드래그를 비활성화하는 방법은 무엇입니까?
  • 다음 reactjs - React Native에서 InputField 구성 요소를 만들 때 오류가 발생했습니다