Những gì bạn muốn là liên kết một kết cấu với một shader và sau đó kết xuất với kết cấu đó. Tôi có thể nhổ qua dặm của đặc tả tài liệu của OpenGL, nhưng tôi sẽ cung cấp cho cảm giác ruột của tôi mang lại cho tôi:
Tôi không nghĩ điều đó là có thể.
Tuy nhiên, điều tôi biết là có thể là bạn tạo Đối tượng Bộ đệm Khung (FBO) và kết xuất với điều đó. Đầu tiên, bạn phải tạo một FBO và đính kèm một kết cấu cho nó với cùng kích thước với kích thước bạn muốn cập nhật.
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);
Khi bạn muốn cập nhật kết cấu của mình, bạn phải thực hiện các bước sau.
Đầu tiên, bạn đính kèm FBO:
glBindFramebuffer(GL_FRAMEBUFFER, fbo_handle);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, texture_width, texture_height);
Bây giờ bạn có thể kết xuất một quad toàn màn hình với một shader tạo ra màu được cập nhật:
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;
Và sau đó bạn phải sao chép bộ đệm khung kết quả vào kết cấu ban đầu.
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();
Tuy nhiên, bạn nên xem xét những điều sau:
- Bạn có thường xuyên cập nhật kết cấu này không?
- Nếu bạn không phải cập nhật mọi khung hình, phương pháp này có đáng bị phạt tốc độ không?
- Bạn có thể tạo nhiều phiên bản của kết cấu này và chu kỳ giữa chúng không?
- Có cách nào khác để đạt được hiệu quả tương tự?