То, что вы хотите, это связать текстуру с шейдером, а затем визуализировать эту текстуру. Я мог бы плевать сквозь мили спецификации документации OpenGL, но я собираюсь дать ощущение, что моя интуиция дает мне:
Я не думаю, что это возможно.
То, что я знаю, возможно, однако, это то, что вы создаете объект буфера кадров (FBO) и визуализируете его. Сначала вы должны сгенерировать FBO и прикрепить к нему текстуру того же размера, который вы хотите обновить.
GLuint fbo_handle, fbo_texture_handle;
GLuint texture_width = GetTextureWidth();
GLuint texture_height = GetTextureWidth();
// generate texture
glGenTextures(1, &fbo_texture_handle);
glBindTexture(GL_TEXTURE_2D, fbo_texture_handle);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture_width, texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// generate framebuffer
glGenFrameBuffers(1, &fbo_handle);
glBindFrameBuffer(GL_FRAMEBUFFER, fbo_handle);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_texture_handle, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
LOG_ERROR("Could not validate framebuffer);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Если вы хотите обновить текстуру, вы должны выполнить следующие шаги.
Сначала вы прикрепляете FBO:
glBindFramebuffer(GL_FRAMEBUFFER, fbo_handle);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, texture_width, texture_height);
Теперь вы можете отобразить полноэкранный квад с помощью шейдера, который выводит обновленный цвет:
vec4 frag_texture = texture2D(TextureID, gl_TexCoord[TextureIndex].st);
vec4 frag_updated = frag_texture + vec4(0.0, 0.0, 0.0, AlphaPatch);
gl_FragData[0] = frag_updated;
И тогда вы должны скопировать полученный кадровый буфер в исходную текстуру.
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_handle);
glBindTexture(GL_TEXTURE_2D, original_texture_handle);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texture_width, texture_height);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glPopAttrib();
Тем не менее, вы должны учитывать следующее:
- Как часто вы обновляете эту текстуру?
- Если вам не нужно обновлять его каждый кадр, стоит ли этот метод снижения скорости?
- Можете ли вы создать несколько версий этой текстуры и циклически переключаться между ними?
- Есть ли другой способ добиться того же эффекта?