【OpenGL/Assimp】渲染模型、半透明材质与封装光源
文章目录
- 渲染成果
- Assimp库准备:
- Mesh类修改:
- 透明贴图使用:
- 光源封装:
- 使用方式在如下测试环境中:
渲染成果

Assimp库准备:
从GitHub拉取源码,根据网络教程,借助CMake生成VS工程项目,并用VS将其编译为静态链接库(lib)或动态链接库(dll + lib)。最后将其库文件和工程内的include文件复制到图形工程下。
Mesh类修改:
在抽象Model,Mesh这些类时,我改动LearnOpenGL的最大的类是Mesh类,将其直接使用的GLAPI替换成了封装好的API,类如下。修改的数据结构在Model中修改相应的数据存放方法即可
//Mesh.h#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>#include <glm/glm.hpp>#include <vector>#include "Shader.h"
#include "VertexArray.h"
#include "VertexBuffer.h"
#include "VertexBufferLayout.h"
#include "IndexBuffer.h"
#include "Texture.h"using namespace std;struct Vertex
{glm::vec3 Position;glm::vec3 Normal;glm::vec2 TexCoords;
};struct TextureData
{string name;Texture* texture;
};class Mesh
{
public:vector<Vertex> vertices;vector<GLuint> indices;vector<TextureData> textures;Mesh(vector<Vertex> vertices, vector<GLuint> indices, vector<TextureData> textures);void Draw(Renderer& renderer, Shader& shader);private:VertexArray VAO;VertexBuffer VBO;IndexBuffer EBO;void setupMesh();
};//Mesh.cpp
#include "Mesh.h"Mesh::Mesh(vector<Vertex> vertices, vector<GLuint> indices, vector<TextureData> textures)
{this->vertices = vertices;this->indices = indices;this->textures = textures;this->setupMesh();
}void Mesh::setupMesh()
{VAO.Bind();VBO.Init(&vertices[0], vertices.size() * sizeof(Vertex));EBO.Init(&indices[0], indices.size());VAO.AddVertexBuffer(VBO);VAO.Unbind();
}void Mesh::Draw(Renderer& renderer, Shader& shader)
{for (int i = 0; i < textures.size(); i++){textures[i].texture->Bind(i);shader.SetUniform1i(textures[i].name, i);}renderer.Draw(VAO, EBO, shader);
}
透明贴图使用:
我所需要绘制的模型有半透明的面部贴图,因此需要使用透明度,这里需要注意的是,如果所有使用数据获取数据的地方都没有出错但仍没有透明效果,可以检查原始数据的问题,如图片本身的透明效果,在工程中加载图片时是否包含透明通道。
//shader
void main()
{vec3 norm = normalize(Normal);vec3 viewDir = normalize(viewPos - FragPos);//透明测试vec4 texColor = texture(texture_diffuse, TexCoords);if(texColor.a < 0.2 && mixFactor == 0)discard;//光照着色color = vec4(CalcPointLight(light, norm, FragPos, viewDir), 1);
}
光源封装:
每次使用光源需要大段的赋值语句,因此对其进行简单封装,目前只封装了点光源
//Light.h#pragma once
#include <iostream>
#include <glm/glm.hpp>#include "Shader.h"using namespace std;class Light
{
public:Light(glm::vec3 position = { 1.2f, 1.0f, 2.0f }, glm::vec3 ambient = { 0.4, 0.4, 0.4 },glm::vec3 diffuse = { 1.2, 1.2, 1.2 },glm::vec3 specular = { 0.1, 0.1, 0.1 },float constant = 1, float linear = 0.09, float quadratic = 0.032);void SetupShader(Shader& shader, string lightName);private:glm::vec3 m_Position;glm::vec3 m_Ambient;glm::vec3 m_Diffuse;glm::vec3 m_Specular;float m_Constant;float m_Linear;float m_Quadratic;
};//Light.cpp
#include "Light.h"Light::Light(glm::vec3 position, glm::vec3 ambient, glm::vec3 diffuse, glm::vec3 specular, float constant, float linear, float quadratic)
{m_Position = position;m_Ambient = ambient;m_Diffuse = diffuse;m_Specular = specular;m_Constant = constant;m_Linear = linear;m_Quadratic = quadratic;
}void Light::SetupShader(Shader& shader, std::string lightName)
{shader.SetUniform3f(lightName + ".position", m_Position.x, m_Position.y, m_Position.z);shader.SetUniform3f(lightName + ".ambient", m_Ambient.x, m_Ambient.y, m_Ambient.z);shader.SetUniform3f(lightName + ".diffuse", m_Diffuse.x, m_Diffuse.y, m_Diffuse.z);shader.SetUniform3f(lightName + ".specular", m_Specular.x, m_Specular.y, m_Specular.z);shader.SetUniform1f(lightName + ".constant", m_Constant);shader.SetUniform1f(lightName + ".linear", m_Linear);shader.SetUniform1f(lightName + ".quadratic", m_Quadratic);
}
使用方式在如下测试环境中:
#pragma once#include "RunBase.h"#include "Model.h"
#include "Light.h"#include <glm/gtc/type_ptr.hpp>class AssimpTest : public RunBase
{
public:Model* body, *blue, *ear, *eye, *mao, *mouth;Shader diffuseShader;Renderer renderer;Light light;AssimpTest() : RunBase(){diffuseShader.Init("res/shaders/AssimpTest.shader");}virtual void Init(GLFWwindow* window, float targetFrameTime) override{/*GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC1_ALPHA));GLCall(glEnable(GL_BLEND));*/body = new Model("res/models/jixuanyou/body.obj");blue = new Model("res/models/jixuanyou/blue.obj");ear = new Model("res/models/jixuanyou/ear.obj");eye = new Model("res/models/jixuanyou/eye.obj");mao = new Model("res/models/jixuanyou/mao.obj");mouth = new Model("res/models/jixuanyou/mouth.obj");}virtual void RenderLoop(GLFWwindow* window, float targetFrameTime) override{renderer.Clear();//绘制受光物体diffuseShader.Bind();//视图矩阵(透视参数)glm::mat4 view(1), proj(1), model(1);view = camera.GetViewMatrix();proj = glm::perspective<GLfloat>(45, 640 / 480, .1f, 100.f);//赋值透视diffuseShader.SetUniformMat4f("view", glm::value_ptr(view));diffuseShader.SetUniformMat4f("projection", glm::value_ptr(proj));diffuseShader.SetUniformMat4f("model", glm::value_ptr(model));//赋值光照light.SetupShader(diffuseShader, "light");//赋值视图位置diffuseShader.SetUniform3f("viewPos", camera.Position.x, camera.Position.y, camera.Position.z);diffuseShader.SetUniform1f("shininess", 4);// 取消纯色diffuseShader.SetUniform1f("mixFactor", 0);//不透明物件body->Draw(renderer, diffuseShader);ear->Draw(renderer, diffuseShader);eye->Draw(renderer, diffuseShader);mouth->Draw(renderer, diffuseShader);// 使用纯色diffuseShader.SetUniform1f("mixFactor", 1);// 浅蓝色diffuseShader.SetUniform3f("diffuseColor", 0.50, 0.66, 0.81);mao->Draw(renderer, diffuseShader);// 深蓝色diffuseShader.SetUniform3f("light.diffuse", 4, 4, 4);diffuseShader.SetUniform3f("light.specular", 0.5, 0.5, 0.5);diffuseShader.SetUniform3f("diffuseColor", 0.022, 0.06, 0.21);blue->Draw(renderer, diffuseShader);}virtual bool UseCameraControl() override{return true;}
};
相关文章:
【OpenGL/Assimp】渲染模型、半透明材质与封装光源
文章目录 渲染成果Assimp库准备:Mesh类修改:透明贴图使用:光源封装:使用方式在如下测试环境中: 渲染成果 Assimp库准备: 从GitHub拉取源码,根据网络教程,借助CMake生成VS工程项目&a…...
pandas与sql对应关系【帮助sql使用者快速上手pandas】
本页旨在提供一些如何使用pandas执行各种SQL操作的示例,来帮助SQL使用者快速上手使用pandas。 目录 SQL语法一、选择SELECT1、选择2、添加计算列 二、连接JOIN ON1、内连接2、左外连接3、右外连接4、全外连接 三、过滤WHERE1、AND2、OR3、IS NULL4、IS NOT NULL5、B…...
Linux WEB漏洞
定义:Linux Web 漏洞是指在基于 Linux 操作系统的 Web 应用程序、Web 服务器软件或者相关的网络服务配置中存在的安全弱点。这些漏洞可能导致攻击者未经授权访问敏感信息、篡改网页内容、执行恶意代码,甚至完全控制服务器。 常见类型及原理 SQL 注入漏…...
音视频入门基础:RTP专题(2)——使用FFmpeg命令生成RTP流
通过FFmpeg命令可以将一个媒体文件转推RTP: ffmpeg -re -stream_loop -1 -i input.mp4 -c:v copy -an -f rtp rtp://192.168.0.102:5400 但是通过ffplay尝试播放上述产生的RTP流时会报错:“Unable to receive RTP payload type 96 without an SDP file …...
大语言模型预训练、微调、RLHF
转发,如有侵权,请联系删除: 1.【LLM】3:从零开始训练大语言模型(预训练、微调、RLHF) 2.老婆饼里没有老婆,RLHF里也没有真正的RL 3.【大模型微调】一文掌握7种大模型微调的方法 4.基于 Qwen2.…...
vue3后台系统动态路由实现
动态路由的流程:用户登录之后拿到用户信息和token,再去请求后端给的动态路由表,前端处理路由格式为vue路由格式。 1)拿到用户信息里面的角色之后再去请求路由表,返回的路由为tree格式 后端返回路由如下: …...
解决idea中无法拖动tab标签页的问题
1、按 Ctrl Alt S 打开设置,找到路径 File | Settings | Appearance & Behavior | Appearance 2、去掉勾选 Drag-and-drop with Alt pressed only 即可...
WMS仓库管理系统,Vue前端开发,Java后端技术源码(源码学习)
一、项目背景和建设目标 随着企业业务的不断扩展,仓库管理成为影响生产效率、成本控制及客户满意度的重要环节。为了提升仓库作业的透明度、准确性和效率,本方案旨在构建一套全面、高效、易用的仓库管理系统(WMS)。该系统将涵盖库…...
25/1/12 嵌入式笔记 学习esp32
了解了一下位选线和段选线的知识: 位选线: 作用:用于选择数码管的某一位,例如4位数码管的第1位,第2位) 通过控制位选线的电平(高低电平),决定当前哪一位数码管处于激活状…...
【NLP】ELMO、GPT、BERT、BART模型解读及对比分析
文章目录 一、基础知识1.1 Word Embedding(词嵌入)1.2 词嵌入模型1.3 神经网络语言模型NNLM 二、ELMO2.1 ELMO的提出2.2 ELMO核心思想2.3 ELMO的优缺点 三、GPT3.1 Transformer3.2 GPT简介3.3 GPT模型架构3.4 预训练及微调3.5 GPT和ELMO对比 四、BERT4.1…...
go语言学习(数组,切片,字符串)
字符串 如果里面存储的是汉字,那么其实就是存储的是UTF--8编码,所以一个字会对应多个字节.如果想要获取汉字的个数,可以使用rune,来处理unicode字符 length: utf8.RuneCountInString( s) 如果只使用len()获取的是字节的个数, 字符串的功能 1,获取字节长度 len(xx) 2,获取字…...
PM 实战 - 智能药盒PRD + 市场规模分析
写在前面 智能硬件 PRD 实例资源很少,Po下个人作品,假定前提为to Boss需求,目标在于覆盖产品设计核心部分(用户画像Persona、产品逻辑图、产品架构图、软件原型图、硬件低保真设计、用例Use Case、硬件标准)。不是申请…...
SQL刷题快速入门(二)
其他章节:SQL刷题快速入门(一) 承接上一章节,本章主要讲SQL的运算符、聚合函数、SQL保留小数的几种方式三个部分 运算符 SQL 支持多种运算符,用于执行各种操作,如算术运算、比较、赋值、逻辑运算等。以下…...
hive迁移后修复分区慢,怎么办?
我有1个30TB的分区表,客户给的带宽只有600MB,按照150%的耗时来算,大概要迁移17小时。 使用hive自带的修复分区命令(一般修复分区比迁移时间长一点),可能要花24小时。于是打算用前面黄大佬的牛B方案。 Hive增…...
代码随想录算法训练营day27
代码随想录算法训练营 —day27 文章目录 代码随想录算法训练营前言一、贪心算法理论基础二、455.分发饼干三、376. 摆动序列53. 最大子数组和总结 前言 今天是算法营的第27天,希望自己能够坚持下来! 今日任务: ● 贪心算法理论基础 ● 455.…...
python 代码使用 DeepXDE 库实现了一个求解二维非线性偏微分方程(PDE)的功能
import deepxde as dde import numpy as np import matplotlib.pyplot as plt import tensorflow as tf# 设置时空计算域 Lx 1 # x 范围从 0 到 1 Ly 1 # y 范围从 0 到 1 Lt 0.05 # t 范围从 0 到 0.05 geom dde.geometry.Rectangle([0, 0], [Lx, Ly]) # 空间域 timed…...
【Go】:深入解析 Go 1.24:新特性、改进与最佳实践
前言 Go 1.24 尚未发布。这些是正在进行中的发布说明。Go 1.24 预计将于 2025 年 2 月发布。本文将深入探讨 Go 1.24 中引入的各项更新,并通过具体示例展示这些变化如何影响日常开发工作,确保为读者提供详尽而有价值的参考。 新特性及改进综述 HTTP/2 …...
VUE3 一些常用的 npm 和 cnpm 命令,涵盖了修改源、清理缓存、修改 SSL 协议设置等内容。
以下是一些常用的 npm 和 cnpm 命令,涵盖了修改源、清理缓存、修改 SSL 协议设置等内容。 npm 常用命令 1. 修改 npm 源 更改为淘宝的 npm 镜像源(可以提高安装速度): bash复制代码 npm config set registry https://registry…...
【SpringBoot】@Value 没有注入预期的值
问题复现 在装配对象成员属性时,我们常常会使用 Autowired 来装配。但是,有时候我们也使用 Value 进行装配。不过这两种注解使用风格不同,使用 Autowired 一般都不会设置属性值,而 Value 必须指定一个字符串值,因为其…...
【STM32-学习笔记-6-】DMA
文章目录 DMAⅠ、DMA框图Ⅱ、DMA基本结构Ⅲ、不同外设的DMA请求Ⅳ、DMA函数Ⅴ、DMA_InitTypeDef结构体参数①、DMA_PeripheralBaseAddr②、DMA_PeripheralDataSize③、DMA_PeripheralInc④、DMA_MemoryBaseAddr⑤、DMA_MemoryDataSize⑥、DMA_MemoryInc⑦、DMA_DIR⑧、DMA_Buff…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
