python下学习opengl之纹理贴图1


原教程地址:https://learnopengl.com/Getting-started/Textures

中文翻译地址:https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/

文件列表:

glfw3.dll: 在http://www.glfw.org/download.html 点击下载32-bit Windows binaries,解压后选择lib-vc2015/glfw3.dll

glfw.py: 在https://github.com/rougier/pyglfw文件列表中下载glfw.py

ShaderProgram.py:

 1 import os
 2 import sys
 3 import numpy as np
 4 from OpenGL.GL import (glCreateProgram, glLinkProgram, glDeleteProgram,
 5                        glCreateShader, glShaderSource, glCompileShader, glAttachShader, glDeleteShader,
 6                        glGetAttribLocation, glGetProgramiv, glGetShaderiv,
 7                        glGetUniformLocation, glGetShaderInfoLog, glGetProgramInfoLog,
 8                        GL_FLOAT, GL_TRUE, GL_FALSE, GL_COMPILE_STATUS, GL_LINK_STATUS, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER)
 9 
10 # this class is needed to create shader program and attach shaders to it.
11 
12 class ShaderProgram(object):
13     def __init__(self, vertpath="", fragpath=""):
14         # paths to files should be set correctly
15         # yep it will contain paths to shaders.
16         self.vertpath = vertpath
17         self.fragpath = fragpath
18         vflag = os.path.exists(self.vertpath)
19         fflag = os.path.exists(self.fragpath)
20         if not vflag:
21             print ("Vertex shader file (--> %s <--) doesn't exist!"%self.vertpath)
22         if not fflag:
23             print ("Fragment shader file (--> %s <--) doesn't exist!"%self.fragpath)
24         if not (fflag and vflag):
25             sys.exit(1)
26         self.initProgram()
27 
28     def getShader(self, shader_source, shader_type):
29         try:
30             shader_id = glCreateShader(shader_type)
31             glShaderSource(shader_id, shader_source)
32             glCompileShader(shader_id)
33             if glGetShaderiv(shader_id, GL_COMPILE_STATUS) != GL_TRUE:
34                 info = glGetShaderInfoLog(shader_id)
35                 raise RuntimeError('Shader compilation failed:\n %s'%info)
36             return shader_id
37         except:
38             glDeleteShader(shader_id)
39             raise
40 
41     def loadShader(self, path):
42         source_file = open(path)
43         shader_source = source_file.read()
44         source_file.close()
45         return shader_source
46 
47     def initProgram(self):
48         # create unique shader program id
49         self.program_id = glCreateProgram()
50         # load and compile individual shaders
51         vertsource = self.loadShader(self.vertpath)
52         fragsource = self.loadShader(self.fragpath)
53         vert_id = self.getShader(vertsource, GL_VERTEX_SHADER)
54         frag_id = self.getShader(fragsource, GL_FRAGMENT_SHADER)
55         # if it's ok, attach them to shader program
56         glAttachShader(self.program_id, vert_id)
57         glAttachShader(self.program_id, frag_id)
58         # link program means make program obj with created executables for different programmable processors for shaders,
59         # that were attached.
60         glLinkProgram(self.program_id)
61         # if something went wrong
62         if glGetProgramiv(self.program_id, GL_LINK_STATUS) != GL_TRUE:
63             info = glGetProgramInfoLog(self.program_id)
64             glDeleteProgram(self.program_id)
65             # they should be deleted anyway
66             glDeleteShader(vert_id)
67             glDeleteShader(frag_id)
68             raise RuntimeError("Error in program linking: %s"%info)
69         # shaders are attached, program is linked -> full shader program with compiled executables is ready,
70         # no need in individual shaders ids, i suppose
71         glDeleteShader(vert_id)
72         glDeleteShader(frag_id)
73 
74     def attribLocation(self, name):
75         return glGetAttribLocation(self.program_id, name)
76 
77     def uniformLocation(self, name):
78         return glGetUniformLocation(self.program_id, name)

 

texture.py:

  1 #! /usr/bin/env python
  2 # -*- coding: utf-8 -*-
  3 
  4 import os, sys
  5 
  6 import OpenGL.GL as gl
  7 import glfw
  8 from ShaderProgram import ShaderProgram
  9 import numpy as np
 10 from ctypes import c_void_p
 11 from PIL import Image
 12 
 13 class MyShaderProgram(ShaderProgram):
 14     def __init__(self, vertPath="vertexShader.glsl", fragPath="fragmentShader.glsl"):
 15         super().__init__(vertPath, fragPath)
 16 
 17     def use(self):
 18         gl.glUseProgram(self.program_id)
 19 
 20 WIN_WIDTH = 800
 21 WIN_HEIGHT = 600
 22 
 23 vertices = np.array([0.5, 0.5, 0,    1.0, 0.0, 0.0,   1.0, 1.0,
 24                      0.5,-0.5, 0,    0.0, 1.0, 0.0,   1.0, 0.0,
 25                     -0.5,-0.5, 0,    0.0, 0.0, 1.0,   0.0, 0.0,
 26                     -0.5, 0.5, 0,    1.0, 1.0, 0.0,   0.0, 1.0], dtype = np.float32)
 27 
 28 indices = np.array([0, 1, 3,
 29                     1, 2, 3], dtype = np.uint32)
 30 
 31 def framebuffer_size_callback(window, width, height):
 32     gl.glViewport(0, 0, width, height)
 33 
 34 def processInput(window):
 35     if glfw.glfwGetKey(window, glfw.GLFW_KEY_ESCAPE) == glfw.GLFW_PRESS:
 36         glfw.glfwSetWindowShouldClose()
 37 
 38     if glfw.glfwGetKey(window, glfw.GLFW_KEY_LEFT) == glfw.GLFW_PRESS:
 39         gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
 40 
 41     if glfw.glfwGetKey(window, glfw.GLFW_KEY_RIGHT) == glfw.GLFW_PRESS:
 42         gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)
 43 
 44 def main():
 45     glfw.glfwInit()
 46     glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 3)
 47     glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, 3)
 48     glfw.glfwWindowHint(glfw.GLFW_OPENGL_PROFILE, glfw.GLFW_OPENGL_CORE_PROFILE)
 49 
 50     window = glfw.glfwCreateWindow(WIN_WIDTH, WIN_HEIGHT, "学习OpenGL".encode(), 0, 0)
 51     if window == 0:
 52         print("failed to create window")
 53         glfw.glfwTerminate()
 54 
 55     glfw.glfwMakeContextCurrent(window)
 56     glfw.glfwSetFramebufferSizeCallback(window, framebuffer_size_callback)
 57 
 58     myShaderProg = MyShaderProgram()
 59 
 60     VAO = gl.glGenVertexArrays(1)
 61     VBO, EBO = gl.glGenBuffers(2)
 62 
 63     gl.glBindVertexArray(VAO)
 64     gl.glBindBuffer(gl.GL_ARRAY_BUFFER, VBO)
 65     gl.glBufferData(gl.GL_ARRAY_BUFFER, sys.getsizeof(vertices), vertices, gl.GL_STATIC_DRAW)
 66     gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, EBO)
 67     gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sys.getsizeof(indices), indices, gl.GL_STATIC_DRAW)
 68 
 69     gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 32, c_void_p(0))
 70     gl.glEnableVertexAttribArray(0)
 71     gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 32, c_void_p(12))
 72     gl.glEnableVertexAttribArray(1)
 73     gl.glVertexAttribPointer(2, 2, gl.GL_FLOAT, gl.GL_FALSE, 32, c_void_p(24))
 74     gl.glEnableVertexAttribArray(2)
 75 
 76     texture = gl.glGenTextures(1)
 77     gl.glBindTexture(gl.GL_TEXTURE_2D, texture)
 78     gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT)
 79     gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT)
 80     gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
 81     gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
 82 
 83     img = Image.open("container.jpg")
 84     width, height = img.size
 85     data = np.array(list(img.getdata()), dtype=np.uint8)
 86 
 87     gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, width, height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, data)
 88     gl.glGenerateMipmap(gl.GL_TEXTURE_2D)
 89 
 90     gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
 91     gl.glBindVertexArray(0)
 92 
 93     while not glfw.glfwWindowShouldClose(window):
 94         processInput(window)
 95         gl.glClearColor(0.2, 0.3, 0.3, 1.0)
 96         gl.glClear(gl.GL_COLOR_BUFFER_BIT)
 97 
 98         myShaderProg.use()
 99 
100         gl.glBindVertexArray(VAO)
101         gl.glDrawElements(gl.GL_TRIANGLES, len(indices), gl.GL_UNSIGNED_INT, None)
102 
103         glfw.glfwSwapBuffers(window)
104         glfw.glfwPollEvents()
105 
106     glfw.glfwTerminate()
107 
108 if __name__ == "__main__":
109     main()

 

vertexShader.glsl:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

void main()
{
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor;
    TexCoord = aTexCoord;
}

 

fragmentShader.glsl:

#version 330 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D ourTexture;

void main()
{
    FragColor = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0);
}

 

container.jpg:

 

最终程序执行效果:


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM