国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Overload游戲引擎細(xì)節(jié)分析】UBO與SSBO的封裝

這篇具有很好參考價(jià)值的文章主要介紹了【Overload游戲引擎細(xì)節(jié)分析】UBO與SSBO的封裝。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、OpenGL的UBO

? 在OpenGL Shader中,如果邏輯比較復(fù)雜,使用的uniform變量較多。通常多個(gè)著色器使用同一個(gè)uniform變量。由于uniform變量的位置是著色器鏈接時(shí)候產(chǎn)生的,因此它在應(yīng)用程序中獲得的索引會(huì)有變化。Uniform Buffer Object(UBO)是一種優(yōu)化uniform變量訪問(wèn),不同著色器直接共享unfiorm數(shù)據(jù)的方法。??

在Overload引擎中,很多Shader包含如下片段,這里就是定義了一個(gè)UBO變量。 它將MVP矩陣一起放入到UBO變量中。

layout (std140) uniform EngineUBO
{
    mat4    ubo_Model;
    mat4    ubo_View;
    mat4    ubo_Projection;
    vec3    ubo_ViewPos;
    float   ubo_Time;
};

std140是內(nèi)存布局限定符,除此之外還有std430、binding、packed等限定符。

二·、Overload對(duì)UBO的封裝

? ?Overload引擎中對(duì)UBO的封裝在UniformBuffer.h、UniformBuffer.inl、UniformBuffer.cpp文件中,將其操作包裝成了一個(gè)類(lèi)UniformBuffer。使用的時(shí)候先調(diào)用Bind,結(jié)束后UnBind,設(shè)置值使用SetSubData。

namespace OvRendering::Buffers
{
	/**
	* OpenGL UBO的封裝
	*/
	class UniformBuffer
	{
	public:
		/**
		* Create a UniformBuffer
		* @param p_size (Specify the size in bytes of the UBO data)
		* @param p_bindingPoint (Specify the binding point on which the uniform buffer should be binded)
		* @parma p_offset (The offset of the UBO, sizeof previouses UBO if the binding point is != 0)
		* @param p_accessSpecifier
		*/
		UniformBuffer(size_t p_size, uint32_t p_bindingPoint = 0, uint32_t p_offset = 0, EAccessSpecifier p_accessSpecifier = EAccessSpecifier::DYNAMIC_DRAW);

		/**
		* Destructor of the UniformBuffer
		*/
		~UniformBuffer();

		/**
		* Bind the UBO
		*/
		void Bind();

		/**
		* Unbind the UBO
		*/
		void Unbind();

		/**
		* Set the data in the UBO located at p_offset to p_data
		* @param p_data
		* @param p_offset
		*/
		template<typename T>
		void SetSubData(const T& p_data, size_t p_offset);

		/**
		* Set the data in the UBO located at p_offset to p_data
		* @param p_data
		* @param p_offsetInOut (Will keep track of the current stride of the data layout)
		*/
		template<typename T>
		void SetSubData(const T& p_data, std::reference_wrapper<size_t> p_offsetInOut);

		/**
		* Return the ID of the UBO
		*/
		uint32_t GetID() const;

		/**
		* Bind a block identified by the given ID to given shader
		* @param p_shader
		* @param p_uniformBlockLocation
		* @param p_bindingPoint
		*/
		static void BindBlockToShader(OvRendering::Resources::Shader& p_shader, uint32_t p_uniformBlockLocation, uint32_t p_bindingPoint = 0);

		/**
		* Bind a block identified by the given name to the given shader
		* @param p_shader
		* @param p_name
		* @param p_bindingPoint
		*/
		static void BindBlockToShader(OvRendering::Resources::Shader& p_shader, const std::string& p_name, uint32_t p_bindingPoint = 0);

		/**
		* Return the location of the block (ID)
		* @param p_shader
		* @param p_name
		*/
		static uint32_t GetBlockLocation(OvRendering::Resources::Shader& p_shader, const std::string& p_name);

	private:
		uint32_t m_bufferID;
	};
}

#include "OvRendering/Buffers/UniformBuffer.inl"

其具體實(shí)現(xiàn)在UniformBuffer.cpp中。我們先看看構(gòu)造函數(shù)代碼:

OvRendering::Buffers::UniformBuffer::UniformBuffer(size_t p_size, uint32_t p_bindingPoint, uint32_t p_offset, EAccessSpecifier p_accessSpecifier)
{
	// 生成buffer
	glGenBuffers(1, &m_bufferID);
	// 綁定UBO
	glBindBuffer(GL_UNIFORM_BUFFER, m_bufferID);
	// 分配內(nèi)存
	glBufferData(GL_UNIFORM_BUFFER, p_size, NULL, static_cast<GLint>(p_accessSpecifier));
	glBindBuffer(GL_UNIFORM_BUFFER, 0);
	// 將緩存對(duì)象m_bufferID綁定到索引為p_bindingPoint的UBO上
	glBindBufferRange(GL_UNIFORM_BUFFER, p_bindingPoint, m_bufferID, p_offset, p_size);
}

在構(gòu)造函數(shù)中直接創(chuàng)建了UBO的buffer,并綁定到索引是p_bindingPoint的UBO上。這里用到了OpenGL函數(shù)glBindBufferRange,如無(wú)需指定偏移量與size值可使用glBindBufferBase函數(shù)。

UniformBuffer.cpp中Bind()、UnBind()過(guò)于簡(jiǎn)單不再分析。往下接著看有個(gè)static函數(shù)BindBlockToShader。這個(gè)函數(shù)主要是顯式綁定一個(gè)uniform塊到p_bindingPoint索引,這樣可以綁定同一個(gè)緩存。這里使用到了glUniformBlockBinding函數(shù),這個(gè)函數(shù)主要是顯示指定BUO的索引,可以保證多個(gè)不同的Shader程序之間UBO的索引是一樣的,但需要在調(diào)用glLinkProgram之前調(diào)用。

void OvRendering::Buffers::UniformBuffer::BindBlockToShader(OvRendering::Resources::Shader& p_shader, uint32_t p_uniformBlockLocation, uint32_t p_bindingPoint)
{
	glUniformBlockBinding(p_shader.id, p_uniformBlockLocation, p_bindingPoint);
}

void OvRendering::Buffers::UniformBuffer::BindBlockToShader(OvRendering::Resources::Shader& p_shader, const std::string& p_name, uint32_t p_bindingPoint)
{
	glUniformBlockBinding(p_shader.id, GetBlockLocation(p_shader, p_name), p_bindingPoint);
}

// 獲取UBO的索引位置
uint32_t OvRendering::Buffers::UniformBuffer::GetBlockLocation(OvRendering::Resources::Shader& p_shader, const std::string& p_name)
{
	return glGetUniformBlockIndex(p_shader.id, p_name.c_str());
}

但在Overload引擎中,調(diào)用這個(gè)方法是在調(diào)用glProgram之后調(diào)用的,而且索引值使用的是GetBlockLocation獲取的,這也是UBO在Shader的默認(rèn)索引值,所以這個(gè)方法應(yīng)該是可以刪除的。我注釋這個(gè)方法使用上沒(méi)有發(fā)現(xiàn)什么問(wèn)題。

最后看一下如何給UBO設(shè)置值,其實(shí)現(xiàn)是在UniformBuffer.inl文件中,主要使用glBufferSubData函數(shù),指定其偏移值與數(shù)據(jù)大小即可。

	template<typename T>
	inline void UniformBuffer::SetSubData(const T& p_data, size_t p_offsetInOut)
	{
		Bind();
		glBufferSubData(GL_UNIFORM_BUFFER, p_offsetInOut, sizeof(T), std::addressof(p_data));
		Unbind();
	}

	template<typename T>
	inline void UniformBuffer::SetSubData(const T& p_data, std::reference_wrapper<size_t> p_offsetInOut)
	{
		Bind();
		size_t dataSize = sizeof(T);
		glBufferSubData(GL_UNIFORM_BUFFER, p_offsetInOut.get(), dataSize, std::addressof(p_data));
		p_offsetInOut.get() += dataSize;
		Unbind();
	}

三、OpenGL的SSBO

Shader Storage Buffer Object(SSBO),著色器存儲(chǔ)緩存對(duì)象,其行為類(lèi)似于UBO,但其功能上更為強(qiáng)大。首先,著色器可以寫(xiě)入buffer塊,修改其內(nèi)容并呈現(xiàn)給其他Shader或應(yīng)用程序本身。其次,可以在渲染之前再覺(jué)得其大小,而不是編譯與鏈接時(shí)。在Overload中,燈光信息是用SSBO存儲(chǔ)的,看以下Shader片段:

layout(std430, binding = 0) buffer LightSSBO
{
    mat4 ssbo_Lights[];
};

在著色器中可以使用length()獲取ssbo_Lights的長(zhǎng)度。

設(shè)置SSBO的方式與設(shè)置UBO類(lèi)似,不過(guò)glBindBuffer()、glBindBufferRange()、glBindBufferBase()需要使用GL_SHADER_STORAGE_BUFFER作為目標(biāo)參數(shù)。

四、Overload對(duì)SSBO的封裝

Overload是將SSBO的操作封裝到類(lèi)ShaderStorageBuffer中,具體代碼就不分析了,與UBO大同小異。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-728320.html

到了這里,關(guān)于【Overload游戲引擎細(xì)節(jié)分析】UBO與SSBO的封裝的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Overload游戲引擎細(xì)節(jié)分析】編輯器對(duì)象鼠標(biāo)拾取原理

    【Overload游戲引擎細(xì)節(jié)分析】編輯器對(duì)象鼠標(biāo)拾取原理

    ? ? ? Overload的場(chǎng)景視圖區(qū)有拾取鼠標(biāo)功能,單擊拾取物體后會(huì)顯示在Inspector面板中。本文來(lái)分析鼠標(biāo)拾取這個(gè)功能背后的原理。 一、OpenGL的FrameBuffer 實(shí)現(xiàn)鼠標(biāo)拾取常用的方式有兩種:渲染id到紋理、光線投射求交。Overload使用的是渲染id到紋理,其實(shí)現(xiàn)需借助OpenGL的幀緩沖

    2024年02月04日
    瀏覽(29)
  • 【Overload游戲引擎細(xì)節(jié)分析】鼠標(biāo)鍵盤(pán)控制攝像機(jī)原理

    在上文中分析了攝像機(jī)類(lèi)的實(shí)現(xiàn),在計(jì)算投影視圖矩陣時(shí)需要給攝像機(jī)輸入其位置及轉(zhuǎn)動(dòng)四元數(shù)。這兩個(gè)量一般通過(guò)鼠標(biāo)鍵盤(pán)來(lái)控制,從而達(dá)到控制攝像機(jī)的目的。本文分析一下其控制原理。 Overload的攝像機(jī)控制實(shí)現(xiàn)在類(lèi)CameraController中,其有三個(gè)個(gè)方法HandleCameraPanning、Hand

    2024年02月08日
    瀏覽(25)
  • 【Overload游戲引擎細(xì)節(jié)分析】視圖投影矩陣計(jì)算與攝像機(jī)

    【Overload游戲引擎細(xì)節(jié)分析】視圖投影矩陣計(jì)算與攝像機(jī)

    本文只羅列公式,不做具體的推導(dǎo)。 OpenGL本身沒(méi)有攝像機(jī)(Camera)的概念,但我們?yōu)榱水a(chǎn)品上的需求與編程上的方便,一般會(huì)抽象一個(gè)攝像機(jī)組件。攝像機(jī)類(lèi)似于人眼,可以建立一個(gè)本地坐標(biāo)系。相機(jī)的位置是坐標(biāo)原點(diǎn),攝像機(jī)的朝向Forward是攝像機(jī)看的方向,再給定向上的Up軸

    2024年02月07日
    瀏覽(36)
  • 安卓游戲開(kāi)發(fā)之物理引擎優(yōu)劣分析

    安卓游戲開(kāi)發(fā)之物理引擎優(yōu)劣分析

    ????????在安卓游戲開(kāi)發(fā)中,物理引擎是模擬現(xiàn)實(shí)世界中物理現(xiàn)象和技術(shù)的核心組件,它能夠使得游戲中的物體和行為更加真實(shí)。物理引擎通常能夠處理碰撞檢測(cè)、動(dòng)力學(xué)模擬、剛體、軟體、關(guān)節(jié)、碰撞響應(yīng)、摩擦力和更多物理效應(yīng)。 ????????不同的物理引擎有不同的

    2024年02月21日
    瀏覽(26)
  • Redis底層封裝細(xì)節(jié)

    日常我們程序員在使用redis做緩存的時(shí)候,很少會(huì)直接使用到RedisTemplate直接操作k-v鍵值對(duì),而是通過(guò)對(duì)RedisTemplate原生代碼的封裝,來(lái)構(gòu)建我們?nèi)粘1阌谑褂昧?xí)慣的代碼來(lái)操作數(shù)據(jù),這里我分享一下日常基本的對(duì)RedisTemplate底層的封裝原理和使用方法 以上是我日常使用過(guò)程中對(duì)

    2024年02月16日
    瀏覽(16)
  • 數(shù)據(jù)從發(fā)出到接收的細(xì)節(jié)介紹{封裝與解封裝}

    數(shù)據(jù)從發(fā)出到接收的細(xì)節(jié)介紹{封裝與解封裝}

    目錄 前言 一,數(shù)據(jù)封裝的全過(guò)程 1.1,應(yīng)用層的封裝形式 1.2,傳輸層的封裝形式 理解: 1.3,網(wǎng)絡(luò)層的封裝形式 理解: 1.4,數(shù)據(jù)鏈路層的封裝形式 理解: 1.5,物理層 1.6,總結(jié) 二,網(wǎng)絡(luò)數(shù)據(jù)傳輸 三,解封裝 3.1,物理層 3.2,數(shù)據(jù)鏈路層 3.3,網(wǎng)絡(luò)層 3.4,傳輸層 3.5,應(yīng)用層

    2024年02月16日
    瀏覽(14)
  • Easy Rules規(guī)則引擎(2-細(xì)節(jié)篇)

    Easy Rules規(guī)則引擎(2-細(xì)節(jié)篇)

    在 Easy Rules規(guī)則引擎(1-基礎(chǔ)篇) 中我們已經(jīng)簡(jiǎn)單介紹了 Easy Rules 規(guī)則引擎的使用示例,這節(jié)我們?cè)斀饨榻B一下規(guī)則引擎的相關(guān)參數(shù)配置實(shí)例還有組合規(guī)則。 Easy Rules 規(guī)則引擎支持下面參數(shù)配置: 參數(shù)名稱(chēng) 參數(shù)類(lèi)型 必選 默認(rèn)值 rulePriorityThreshold int 否 Integer.MAX_VALUE skipOnFirst

    2024年02月11日
    瀏覽(25)
  • 搜索引擎排名因素有哪些具體的細(xì)節(jié)?

    搜索引擎排名因素有很多,以下是一些常見(jiàn)的因素: 密度和位置:搜索引擎會(huì)考慮在網(wǎng)頁(yè)上的出現(xiàn)頻率和位置。密度指的是在網(wǎng)頁(yè)內(nèi)容中出現(xiàn)的頻率與整個(gè)文本的比例。的位置也很重要,例如,如果出現(xiàn)在頁(yè)面的頂部或標(biāo)題標(biāo)簽中,則

    2024年02月07日
    瀏覽(30)
  • 回爐與剖析C++封裝特性 - 重新認(rèn)識(shí)C++,完滿呈現(xiàn)全部?jī)?nèi)部細(xì)節(jié)

    回爐與剖析C++封裝特性 - 重新認(rèn)識(shí)C++,完滿呈現(xiàn)全部?jī)?nèi)部細(xì)節(jié)

    ??前情提要?? 本章節(jié)是 C++ 的 深度剖析封裝細(xì)節(jié)特性 的相關(guān)知識(shí)~ 接下來(lái)我們即將進(jìn)入一個(gè)全新的空間,對(duì)代碼有一個(gè)全新的視角~ 以下的內(nèi)容一定會(huì)讓你對(duì) C++ 有一個(gè)顛覆性的認(rèn)識(shí)哦?。?! 以下內(nèi)容干貨滿滿,跟上步伐吧~ 作者介紹: ?? 作者: 熱愛(ài)編程不起眼的小人物??

    2023年04月13日
    瀏覽(16)
  • UE4/5C++多線程插件制作(十九、異步資源讀取封裝,細(xì)節(jié)修改)

    目錄 MTPResourceLoadManage MTPThreadInterface MTPManage.h MTPManage.cpp RTPAgendy RTPAgendy.h ?RTPAgendy.cpp

    2024年02月14日
    瀏覽(22)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包