Ce que vous voulez, c'est lier une texture à un shader, puis effectuer un rendu sur cette texture. Je pourrais cracher des kilomètres de spécifications de documentation d'OpenGL, mais je vais donner l'impression que mon instinct me donne:
Je ne pense pas que ce soit possible.
Ce que je sais est possible, cependant, c'est que vous créez un Frame Buffer Object (FBO) et que vous le restituez. Tout d'abord, vous devez générer un FBO et y attacher une texture de la même taille que celle que vous souhaitez mettre à jour.
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);
Lorsque vous souhaitez mettre à jour votre texture, vous devez suivre les étapes suivantes.
Tout d'abord, vous attachez le FBO:
glBindFramebuffer(GL_FRAMEBUFFER, fbo_handle);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, texture_width, texture_height);
Vous pouvez maintenant rendre un quadruple plein écran avec un shader qui produit la couleur mise à jour:
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;
Et puis vous devez copier le framebuffer résultant dans la texture d'origine.
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();
Cependant, vous devez considérer les éléments suivants:
- À quelle fréquence mettez-vous à jour cette texture?
- Si vous n'avez pas à le mettre à jour à chaque image, cette méthode vaut-elle la peine de vitesse?
- Pouvez-vous générer plusieurs versions de cette texture et alterner entre elles?
- Existe-t-il une autre manière d'obtenir le même effet?
Si votre matériel le prend en charge, l'extension GL_ARB_shader_image_load_store vous permet d'écrire sur une texture.
la source
GL_EXT_shader_image_load_store
. Cela signifie que votre réponse est probablement correcte, mais pas encore pratique sur le terrain. Suce. :(Oui c'est possible, texture / imageLoad sont pour la lecture et imageStore est pour l'écriture.
la source