O que você deseja é vincular uma textura a um sombreador e renderizar nessa textura. Eu poderia cuspir por quilômetros de especificação de documentação do OpenGL, mas vou dar a sensação que meu instinto me dá:
Eu não acho isso possível.
O que eu sei é possível, no entanto, é que você crie um objeto de buffer de quadro (FBO) e processe-o. Primeiro, você deve gerar um FBO e anexar uma textura a ele com o mesmo tamanho que você deseja atualizar.
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);
Quando você quiser atualizar sua textura, siga as etapas abaixo.
Primeiro, você anexa o FBO:
glBindFramebuffer(GL_FRAMEBUFFER, fbo_handle);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, texture_width, texture_height);
Agora você pode renderizar um quad em tela cheia com um sombreador que produz a cor atualizada:
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;
E então você deve copiar o buffer de moldura resultante para a textura original.
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();
No entanto, você deve considerar o seguinte:
- Com que frequência você atualiza essa textura?
- Se você não precisar atualizá-lo a cada quadro, esse método vale a pena de velocidade?
- Você pode gerar várias versões dessa textura e alternar entre elas?
- Existe outra maneira de obter o mesmo efeito?
Se o seu hardware suportar, a extensão GL_ARB_shader_image_load_store permite gravar em uma textura.
fonte
GL_EXT_shader_image_load_store
. Isso significa que sua resposta provavelmente está correta, mas ainda não é prática em campo. É uma merda. :(Sim, é possível, textura / imageLoad é para leitura e imageStore é para escrita.
fonte