[CG从零开始] 6. 加载一个柴犬模型学习UV贴图

在第 5 篇文章中,我们成功加载了 fbx 模型,并且做了 MVP 变换,将立方体按照透视投影渲染了出来。但是当时只是随机给顶点颜色,并且默认 fbx 文件里只有一个 mesh,这次我们来加载一个柴犬模型,并且给模型贴图,模型可以从 sketchfab 下载

本文没有涉及到理论解释,更多的是代码实践。

完整代码在 https://github.com/MangoWAY/CGLearner/tree/v0.3 tag v0.3

1. 创建纹理,加载图片

我们来封装一个 Texture 类用来加载图片,创建、bind 纹理,加载图片我用的是 pillow 库。

from OpenGL import GL as gl
from PIL import Image
import numpy as np
class Texture:
    COUNT = 0
    def __init__(self) -> None:
        self.texid = -1
        self.count = -1

    def create(self):
        self.texid = gl.glGenTextures(1)

    def load_from_path(self, path: str):
        gl.glActiveTexture(gl.GL_TEXTURE0 + Texture.COUNT)
        self.count = Texture.COUNT
        Texture.COUNT +=1
        gl.glBindTexture(gl.GL_TEXTURE_2D, self.texid)
        # Set the texture wrapping parameters
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT)
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT)
        # Set texture filtering parameters
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
        # load image
        image = Image.open(path)
        img_data = np.array(list(image.getdata()), np.uint8)
        gl.glTexImage2D(gl.GL_TEXTURE_2D,
                        0,
                        gl.GL_RGB,
                        image.width,
                        image.height,
                        0,
                        gl.GL_RGB,
                        gl.GL_UNSIGNED_BYTE,
                        img_data)
        gl.glGenerateMipmap(gl.GL_TEXTURE_2D)

    def bind(self):
        gl.glActiveTexture(gl.GL_TEXTURE0 + self.count)
        gl.glBindTexture(gl.GL_TEXTURE_2D, self.texid)

2. UV 采样

在之前的文章中,我们基本只用到了顶点的位置信息,这次我们需要用到顶点的 uv 坐标,我们根据 uv 坐标对纹理进行采样,获取当前的颜色。如下,在之前封装的模型加载类里,用 pyassimp 获取 uv 坐标。

model_importer.py
...

    def load_mesh(self, path: str):
        scene = pyassimp.load(path)
        mmeshes = []
        for mesh in scene.meshes:
            ...

            # 获取 uv 坐标
            mmesh.uvs = mesh.texturecoords.squeeze(0)
            ...

        return mmeshes
...

有了 uv 以后,我们需要将它放到我们的顶点数组里,然后正确设置长度、偏移等等,和位置、法线等数据类似。有一点需要注意一下,图片的坐标系原点一般在左上,而 uv 坐标的原点在左下,因此需要 y 方向需要翻转一下。vert 如下,我们新加一个 uv 的顶点属性,然后将它传递到 frag shader 中。在 frag 中翻转一下 y,然后采样纹理。

// vert
#version 330 core
...

layout(location = 3) in vec2 aUV;
out vec3 c;
out vec2 uv;
uniform mat4 u_mvp;
void main(){
    gl_Position = u_mvp * vec4(aPos,1.0);
    c = aColor;
    uv = aUV;
}
// frag
#version 330 core
out vec4 color;
in vec3 c;
in vec2 uv;
uniform sampler2D ourTexture;
void main(){
    ...

    vec2 uv1 = vec2(uv.x,1.0-uv.y);
    color = texture(ourTexture, uv1);
}

3. 绘制多个网格

这个柴犬模型里有 3 个网格,我们需要绘制 3 个网格,因此我们需要修改一下之前主函数的逻辑,之前是默认加载的第一个网格,现在需要加载每一个网格,然后创建 VAO、VBO、EBO 等渲染数据,然后加载纹理资源,最后在渲染循环中依次渲染。

main.py
...

verts = []
indes = []
renderData = []
for mesh in meshes:
    vert = []
    for i in range(len(mesh.vertices)):
        if i % 3 == 0:
            vert.extend([mesh.vertices[i],mesh.vertices[i + 1],mesh.vertices[i + 2]])
            vert.extend([mesh.normals[i],mesh.normals[i + 1],mesh.normals[i + 2]])
            vert.extend([random.random(),random.random(),random.random()])
            vert.extend([mesh.uvs[int(i/3),0],mesh.uvs[int(i/3),1]])
    verts.append(vert)
    inde = mesh.subMeshes[0].indices
    indes.append(inde)
    data = RendererData()
    data.build_data([desp,desp1,desp2,desp3],vert, inde)
    renderData.append(data)
...

tex = Texture()
tex.create()
tex.load_from_path("default_Base_Color.png")
tex.bind()

while (...):
       ...

        for data in renderData:
            data.use()
            data.draw()
            data.unuse()
       ...

我们可以调一调之前定义的 Transform 的位置、角度,或者相机的角度等,渲染的结果如下:

[CG从零开始] 6. 加载一个柴犬模型学习UV贴图

4. 总结

  • 加载 uv 坐标传递到 shader 中;
  • 利用 pyopengl 加载纹理贴图;
  • 渲染多个网格数据;

Original: https://www.cnblogs.com/WAoyu/p/16758981.html
Author: 芒果和小猫
Title: [CG从零开始] 6. 加载一个柴犬模型学习UV贴图

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/801323/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • PyGame “超级玛丽”游戏专题开篇——“变态超级玛丽”的诞生

    欢迎来到PyGame频道🐱‍👓 开篇介绍 源码获取 开篇介绍 哈喽,又是我,一个很久又不更新博客的苦逼大二学生,哈哈哈哈哈前段时间学习了PyGame,自己也做了很多游戏啦,嘿嘿 变…

    Python 2023年9月20日
    062
  • 详解 pyinstaller 打包多个py文件

    前言 最近有个需求要把python项目打包成可执行程序运行,看了很多帖子,大多数博主都采用pyinstall 打包,看着也不难,本以为很简单的事情,对于我这个新手来说也折腾了2个多…

    Python 2023年8月3日
    056
  • python pygame创建窗口和背景图片_如何用pygame创建窗口?怎么实现?

    这应该是最入门的基础内容了,想必大家在刚接触时候,都遇到这个问题吧?不管小伙伴们有没有遇到这个问题,我都希望大家可以跟着小编一起来学习下,充斥自己的知识库,这样对将来我们完成项目任…

    Python 2023年9月21日
    058
  • pytest之parametrize参数化

    文章末尾给大家留了大量福利哟 前言 我们都知道pytest和unittest是兼容的,但是它也有不兼容的地方,比如ddt数据驱动,测试夹具fixtures(即setup、teard…

    Python 2023年9月12日
    061
  • Pandas loc与iloc

    先来看一下示例: #!/usr/bin/python import pandas as pd 三个字&#x…

    Python 2023年8月7日
    039
  • Python 游戏框架搭建

    目标 – 使用 面向对象 设计 飞机大战游戏类。目标明确主程序职责实现主程序类准备游戏精灵组 1、明确主程序职责回顾 快速入门案例,一个游戏主程序的 职责 可以分为来应该部分:游戏…

    Python 2023年9月19日
    063
  • pandas数据分析之分组聚合

    在数据分析过程中,经常会需要根据某一列或多列把数据划分为不同的组别,然后再对其进行数据分析。本文将介绍pandas的数据分组及分组后的应用如对数据进行聚合、转换和过滤。在关系型数据…

    Python 2023年8月6日
    047
  • Flask中SQLAlchemy自动更新表结构

    Flask中SQLAlchemy自动更新表结构 Python: 2.7Flask: 1.0.3Flask-SQLAlchemy: 2.3.2SQLAlchemy: 1.3.12Fl…

    Python 2023年8月11日
    066
  • Python Scrapy环境配置教程+使用Scrapy爬取李毅吧内容

    Python爬虫框架Scrapy Scrapy框架 1、Scrapy框架安装 直接通过这里安装scrapy会提示报错: error: Microsoft Visual C++ 14…

    Python 2023年10月5日
    042
  • python 归一化_Python 数据归一化、标准化、正则化 (机器学习)

    数据归一化、标准化、正则化 1、归一化 是将数据放缩到0~1区间,利用公式(x-min)/(max-min) 2、标准化 将数据转化为标准的正态分布,均值为0,方差为1 3、正则化…

    Python 2023年8月19日
    097
  • 给ShardingSphere提了个PR

    说来惭愧,干了 10 来年程序员,还没有给开源做过任何贡献,以前只知道嘎嘎写,出了问题嘎嘎改,从来没想过提个 PR 去修复他,最近碰到个问题,发现挺简单的,就随手提了个 PR 过去…

    Python 2023年10月23日
    055
  • flask介绍与简单操作

    一、介绍 Flask的核心在于werkzeug(路由模块),Jinja2模板引擎 类比Django:路由、模板、orm Flask要完成功能,依赖于丰富的插件 补充:Django与…

    Python 2023年8月11日
    041
  • Ubuntu18.04.1 LTS 下Nginx+uWSGI+Django项目部署

    因为我图方便,直接使用云服务器(没成功重装了好多次),所以有些图片中出现的IP地址我就打马赛克了!请知悉! 建议 安装系统-检查python环境-安装django和项目依赖包-安装…

    Python 2023年8月4日
    049
  • task1-3:第一章:第三节探索性数据分析

    task1-3:第一章:第三节探索性数据分析 * – 1 第一章:探索性数据分析 – + * 开始之前,导入numpy、pandas包和数据 + 1.6 了…

    Python 2023年8月7日
    035
  • ChatGPT接入微信。

    啊哦~你想找的内容离你而去了哦 内容不存在,可能为如下原因导致: ① 内容还在审核中 ② 内容以前存在,但是由于不符合新 的规定而被删除 ③ 内容地址错误 ④ 作者删除了内容。 可…

    Python 2023年11月3日
    057
  • Uniapp实现实时音视频的基础美颜滤镜功能

    视频基础美颜功能简介 ZEGO 音视频SDK提供基础美颜功能,为用户呈现出良好的肌肤状态,打造独特自然的美颜效果。美颜滤镜功能常用于视频通话、直播等场景。 开发者可以开启美颜开关,…

    Python 2023年10月25日
    052
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球