gpt4 book ai didi

opengl 将纹理传递给程序 : once or at every rendering?

转载 作者:行者123 更新时间:2023-12-01 15:56:02 29 4
gpt4 key购买 nike

我有一个程序有两种纹理:一种来自视频,另一种来自图像。

对于图像纹理,我是否必须在每次渲染时将其传递给程序,还是只传递一次?我可以做吗

glActiveTexture(GLenum(GL_TEXTURE1))
glBindTexture(GLenum(GL_TEXTURE_2D), texture.id)
glUniform1i(textureLocation, 1)

就一次?我相信是这样,但在我的实验中,如果不涉及视频纹理,这就可以正常工作,但是一旦我添加了我在每个渲染过程中附加的视频纹理(因为它正在改变),获取图像的唯一方法是在每个渲染帧运行上述代码。

最佳答案

让我们剖析一下您在做什么,包括一些不必要的东西,以及 GL 做了什么。

首先,您在代码中进行的所有 C 风格转换都不是必需的。只需使用 GL_TEXTURE_2D 等代替 GLenum(GL_TEXTURE_2D)

glActiveTexture(GL_TEXTURE0 + i),其中 i[0, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1] 范围内,选择当前事件的 < em>纹理单元。只要您不使用另一个有效的单元标识符调用 glActiveTexture,改变纹理单元状态的命令将影响单元 i

一旦您用当前事件的纹理单元 i 调用 glBindTexture(target, name),纹理单元的状态就会更改为引用 name 指定的 target 在着色器中使用适当的采样器对其进行采样时(即 name 可能绑定(bind)到 TEXTURE_2D 并且相应的样本必须是 sampler2D)。您只能将一个纹理对象绑定(bind)到当前事件纹理单元的特定目标 - 因此,如果您需要在着色器中采样两个 2D 纹理,则需要使用两个纹理单元。

从上面,glUniform1i(samplerLocation, i) 的作用应该很明显了。

因此,如果您有两个需要在着色器中采样的 2D 纹理,则需要两个纹理单元和两个采样器,每个都引用一个特定单元:

GLuint regularTextureName = 0;
GLunit videoTextureName = 0;

GLint regularTextureSamplerLocation = ...;
GLint videoTextureSamplerLocation = ...;

GLenum regularTextureUnit = 0;
GLenum videoTextureUnit = 1;

// setup texture objects and shaders ...

// make successfully linked shader program current and query
// locations, or better yet, assign locations explicitly in
// the shader (see below) ...

glActiveTexture(GL_TEXTURE0 + regularTextureUnit);
glBindTexture(GL_TEXTURE_2D, regularTextureName);
glUniform(regularTextureSamplerLocation, regularTextureUnit);

glActiveTexture(GL_TEXTURE0 + videoTextureUnit);
glBindTexture(GL_TEXTURE_2D, videoTextureName);
glUniform(videoTextureSampleLocation, videoTextureUnit);

你的片段着色器,我假设你将在其中进行采样,必须有相应的采样器:

layout(binding = 0) uniform sampler2D regularTextureSampler;
layout(binding = 1) uniform sampler2D videoTextureSampler;

就是这样。如果绑定(bind)到上述单元的两个纹理对象都正确设置,那么在每次片段着色器调用之前纹理内容是否动态变化并不重要——在许多场景中这是常见的地方,例如延迟渲染或任何其他渲染到纹理算法,因此您并没有完全用某些视频纹理开辟新天地。

关于你需要多久做一次这个问题:你需要在需要做的时候做——不要改变不需要改变的状态。如果您从不更改相应纹理单元的绑定(bind),则根本不需要重新绑定(bind)纹理。正确设置它们一次,不要管它们。

采样器绑定(bind)也是如此:如果您不使用着色器对其他纹理对象进行采样,则根本不需要更改着色器程序状态。设置一次,不用管它。

简而言之:如果不需要,不要改变状态。

编辑:我不太确定是否是这种情况,但是如果您使用同一个着色器和一个采样器分别用于两个纹理着色器调用,你必须改变一些东西,但你猜怎么着,这就像让采样器引用另一个纹理单元一样简单:

// same texture unit setup as before
// shader program is current

while (rendering)
{
glUniform(samplerLocation, regularTextureUnit);
// draw call sampling the regular texture

glUniform(samplerLocation, videoTextureUnit);
// draw call sampling teh video texture
}

关于opengl 将纹理传递给程序 : once or at every rendering?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39786138/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com