【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;
	}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/952788.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构高阶】B-树

目录 一、常见的搜索结构 二、B树 2.1 B树的概念 2.2 B树插入数据的分析 2.3 B树的性能分析 2.4 模拟实现B树 2.4.1 B树节点的定义 2.4.2 B树数据的查找 2.4.3 B树节点的数据插入 2.4.4 B树的遍历 2.4.5 模拟实现B树实现的完整代码 三、B树 3.1 B树的概念 3.2 B树…

人才选拔中,如何优化面试流程

在与某大型央企的深入交流中&#xff0c;随着该企业的不断壮大与业务扩张&#xff0c;对技术人才的需求急剧上升&#xff0c;尽管企业加大了招聘力度并投入了大量资源&#xff0c;但招聘成效却不尽如人意。经过项目组细致调研与访谈&#xff0c;问题的根源逐渐浮出水面&#xf…

【Bluedroid】HFP连接流程源码分析(一)

connect /packages/modules/Bluetooth/system/btif/src/btif_hf_client.cc static bt_status_t connect(const RawAddress* bd_addr) {log::verbose("HFP Client version is {}", btif_hf_client_version);CHECK_BTHF_CLIENT_INIT(); // 检查HFP客户端是否已初始化…

Shader->LinearGradient线性渐变着色器详解

XML文件 <com.example.myapplication.MyViewxmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_gravity"center"android:layout_height"400dp"/>自定义View代码 c…

【芯片封测学习专栏 -- 单 Die 与 多Die(Chiplet)介绍】

请阅读【嵌入式开发学习必备专栏 Cache | MMU | AMBA BUS | CoreSight | Trace32 | CoreLink | ARM GCC | CSH】 文章目录 Overview单个Die&#xff08;Monolithic Die&#xff09;多个Die&#xff08;Chiplet Architecture or Heterogeneous SoC&#xff09;如何判断一个SoC是…

acwing_5722_十滴水

acwing_5722_十滴水 下面这篇大佬的题解属实是把指针用明白了&#xff0c;可以好好理解一下&#xff1a; 原题解连接&#xff1a;AcWing 5722. 一个简单模拟实现 - AcWing map/unordered_map的用法:见收藏夹 #include<iostream> #include<unordered_map> #incl…

零基础学AI大模型要多久?真的能学会吗?

很多人都对学习AI大模型抱有疑问&#xff0c;特别是那些完全没有编程基础的朋友。其实&#xff0c;从零开始学习AI大模型是可以做到的&#xff0c;关键在于你的学习方法和投入的时间。下面我们来详细聊一聊这个问题。 学习时间 自学&#xff1a; 如果你选择自学&#xff0c;…

攻防靶场(34):隐蔽的计划任务提权 Funbox1

目录 1. 侦查 1.1 收集目标网络信息&#xff1a;IP地址 1.2 主动扫描&#xff1a;扫描IP地址段 1.3 搜索目标网站 2. 初始访问 2.1 有效账户&#xff1a;默认账户 2.2 利用面向公众的应用 2.3 有效账户&#xff1a;默认账户 3. 权限提升 3.1 计划任务/作业&#xff1a;Cron 靶场…

Java高频面试之SE-11

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本牛马baby今天又来了&#xff01;哈哈哈哈哈嗝&#x1f436; Java中是引用传递还是值传递&#xff1f; 在 Java 中&#xff0c;方法参数传递是通过 值传递 的方式实现的&#xff0c;但这可能会引起一…

2.两数相加--力扣

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …

与Linux的设备树文件(dts)的基础知识【编写和操作】

编写相关 01-双引号中的内容表示字符串,<>中的内容表示数值 示例如下&#xff1a; / {swh_led0 {compatible "swh_leddrv";pin <0x00030001>;};.......};compatible的具体内容为字符串swh_leddrv&#xff0c;而pin的值为数值0x00030001。 操作相关…

STM32第6章、WWDG

一、简介 WWDG&#xff1a;全称Window watchdog&#xff0c;即窗口看门狗&#xff0c;本质上是一个能产生系统复位信号和提前唤醒中断的计数器。 特性&#xff1a; 是一个递减计数器。 看门狗被激活后&#xff0c; 当递减计数器值从 0x40减到0x3F时会产生复位&#xff08;即T6位…

国产fpga nvme ip高速存储方案设计

国产高速存储方案主要是使用nvme ip实现高速存储方案&#xff0c;nvme ip采用纯verilog语言实现&#xff0c;用户拿到nvme ip使用起来也很简单。 先看看效果如 zu7eg板子&#xff0c;这个芯片支持pcie3.0 x4. zynq 7045板子只支持pcie 2.0 x4 速度测试&#xff0c;测试nvme …

《框架程序设计》复习题解析-1

目录 单选题 1.以下关于Maven说法错误的是&#xff1f;&#xff08; &#xff09;。 2.在项目的开发过程中&#xff0c;MyBatis承担的责任是( ) 3.当项目引用依赖的范围设置为以下&#xff08; &#xff09;选项时&#xff0c;表示依赖在编译时是必需的&#xff0c;但在运…

STM32F103的ADC通道映射

ADC通道映射 STM32F103带3个ADC控制器&#xff0c;一共支持23个通道&#xff0c;包括21个外部和2个内部信号源。ADC1控制器最多有18个通道&#xff0c;包括16个外部和2个内部信号源。 ADC1和ADC2的16个外部通道相同&#xff0c;且ADC1和ADC2共用一个系统中断向量&#xff0c;A…

Vue2+OpenLayers使用Overlay实现点击获取当前经纬度信息(提供Gitee源码)

目录 一、案例截图 二、安装OpenLayers库 三、代码实现 关键参数&#xff1a; 实现思路&#xff1a; 核心代码&#xff1a; 完整代码&#xff1a; 四、Gitee源码 一、案例截图 二、安装OpenLayers库 npm install ol 三、代码实现 覆盖物&#xff08;Overlay&#xf…

[Transformer] The Structure of GPT, Generative Pretrained Transformer

The Structure of Generative Pretrained Transformer Reference: The Transformer architecture of GPT models How GPT Models Work

【芯片封测学习专栏 -- Substrate | RDL Interposer | Si Interposer | 嵌入式硅桥(EMIB)详细介绍】

请阅读【嵌入式开发学习必备专栏 Cache | MMU | AMBA BUS | CoreSight | Trace32 | CoreLink | ARM GCC | CSH】 文章目录 OverviewSubstrate&#xff08;衬底或基板&#xff09;Substrate 定义Substrate 特点与作用Substrate 实例 RDL Interposer&#xff08;重布线层中介层&a…

基于单片机的无线气象仪系统设计(论文+源码)

1系统方案设计 如图2.1所示为无线气象仪系统设计框架。系统设计采用STM32单片机作为主控制器&#xff0c;结合DHT11温湿度传感器、光敏传感器、BMP180气压传感器、PR-3000-FS-N01风速传感器实现气象环境的温度、湿度、光照、气压、风速等环境数据的检测&#xff0c;并通过OLED1…

【JavaWeb】JavaWeb入门之Tomcat详解

目录 1.Java Web前奏 1.1.C/S结构 1.2.B/S结构 1.3.静态网页和动态网页 1.4.常见的网页 1.5.Web服务器 2.HTTP协议 2.1.HTTP协议概念 2.2.无状态协议 2.3.HTTP1.0和HTTP1.1 2.4.请求协议和响应协议 2.5.请求协议 2.5.1.GET请求 2.5.2.POST请求 2.6.响应协议 1.J…