简体   繁体   English

OpenGL - 在同一个 object 上混合两种纹理

[英]OpenGL - blend two textures on the same object

I want to apply two textures on the same object (actually just a 2D rectangle) in order to blend them.我想在同一个 object(实际上只是一个 2D 矩形)上应用两个纹理以混合它们。 I thought I would achieve that by simply calling glDrawElements with the first texture, then binding the other texture and calling glDrawElements a second time.我想我可以通过简单地使用第一个纹理调用glDrawElements来实现这一点,然后绑定另一个纹理并再次调用glDrawElements Like this:像这样:

//create vertex buffer, frame buffer, depth buffer, texture sampler, build and bind model
//...

glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
glBlendEquation(GL_FUNC_ADD);

// Clear the screen
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Bind our texture in Texture Unit 0
GLuint textureID;
//create or load texture
//...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
// Set our  sampler to use Texture Unit 0
glUniform1i(textureSampler, 0);

// Draw the triangles !
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)0);

//second draw call
GLuint textureID2;
//create or load texture
//...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID2);
// Set our sampler to use Texture Unit 0
glUniform1i(textureSampler, 0);

// Draw the triangles !
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)0);

Unfortunately, the 2nd texture is not drawn at all and I only see the first texture.不幸的是,第二个纹理根本没有绘制,我只看到第一个纹理。 If I call glClear between the two draw calls, it correctly draws the 2nd texture.如果我在两个绘制调用之间调用glClear ,它会正确绘制第二个纹理。

Any pointers?任何指针? How can I force OpenGL to draw on the second call?如何强制 OpenGL 进行第二次通话?

As an alternative to the approach you followed so far I would like to suggest using two texture samplers within your GLSL shader and perform the blending there.作为您到目前为止所采用的方法的替代方法,我建议您在 GLSL 着色器中使用两个纹理采样器并在那里执行混合。 This way, you would be done with just one draw call, thus reducing CPU/GPU interaction.这样,您只需一个绘制调用即可完成,从而减少 CPU/GPU 交互。 To do so, just define to texture samplers in your shader like为此,只需在着色器中定义纹理采样器,例如

layout(binding = 0) uniform sampler2D texture_0;
layout(binding = 1) uniform sampler2D texture_1;

Alternatively, you can use a sampler array:或者,您可以使用采样器数组:

layout(binding = 0) uniform sampler2DArray textures;

In your application, setup the textures and samplers using在您的应用程序中,使用

enum Sampler_Unit{BASE_COLOR_S = GL_TEXTURE0 + 0, NORMAL_S = GL_TEXTURE0 + 2};
glActiveTexture(Sampler_Unit::BASE_COLOR_S);
glBindTexture(GL_TEXTURE_2D, textureBuffer1);
glTexStorage2D( ....)
glActiveTexture(Sampler_Unit::NORMAL_S);
glBindTexture(GL_TEXTURE_2D, textureBuffer2);
glTexStorage2D( ....)

Thanks to @tkausl for the tip.感谢@tkausl 的提示。

I had depth testing enabled during the initialization phase.我在初始化阶段启用了深度测试。

// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);

The option needs to be disabled in my case, for the blend operation to work.在我的情况下,需要禁用该选项才能使混合操作起作用。

//make sure to disable depth test
glDisable(GL_DEPTH_TEST);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM