Tôi đã "hack" một trong những trò chơi yêu thích của mình từ khi tôi còn trẻ, và tôi đã quản lý để có thể chặn cuộc gọi OpenGL và tiêm mã C++ bằng cách sử dụng trình bao bọc opengl32.dll. Tôi đã có thể đưa ra một số cách sử dụng tuyệt vời cho mục đích này, nhưng mục tiêu hiện tại của tôi là triển khai các trình xử lý bài đăng glsl vào trò chơi cũ này để làm cho nó trông hiện đại hơn một chút. Trò chơi ban đầu được phát hành vào cuối những năm 90, do đó việc sử dụng OpenGL và mã kết xuất của nó bị giới hạn/nguyên thủy/lỗi thời.Tiêm bộ đệm khung
Tôi đã có thể tạo thành công các trình đổ bóng đỉnh và đoạn bằng cách chèn mã để khởi tạo và sử dụng các chương trình đổ bóng, nhưng vấn đề của tôi nằm trong việc tạo khung hình/hiển thị cảnh của tôi tới kết cấu để gửi đến trình tạo đoạn của tôi làm mẫu . Theo như tôi có thể nói, kết cấu tôi tạo ra thường là màu đen. Thật khó để tìm các tài nguyên có liên quan đến những gì tôi đang làm và kiểm tra các cuộc gọi thô (tôi đã cố gắng xác định nơi để chèn mã bằng cách đọc một dấu vết opengl của một khung hình duy nhất của trò chơi), vì vậy tôi đã không thể quấn đầu của tôi xung quanh những gì tôi đang làm sai.
Tôi đã thử đặt mã ở nhiều nơi, nhưng hiện tại, tôi đang ràng buộc framebuffer sau khi trò chơi gọi wglSwapBuffers()
và tôi đang hủy liên kết ngay trước khi cuộc gọi glFlush()
tiếp theo được thực hiện, nhưng tôi không chắc chắn nếu nhiều thiết lập viewports, hoặc hoạt động ma trận, hoặc bất cứ điều gì khác được tạo ra giữa những lần này là bằng cách nào đó rối tung với framebuffer.
Đây là mã để khởi tạo framebuffer:
void initFB()
{
/* Texture */
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &fbo_texture);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
/* Depth buffer */
glGenRenderbuffers(1, &fbo_depth);
glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 1920, 1080);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
/* Framebuffer to link everything together */
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_texture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth);
GLenum status;
if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
fprintf(stderr, "glCheckFramebufferStatus: error %p", status);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Đây là mã gọi sau wglSwapBuffers
:
GLenum fboBuff[] = { GL_COLOR_ATTACHMENT0 };
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glDrawBuffers(1, fboBuff);
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
Đây là mã gọi trước khi glFlush()
:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glPopAttrib(); // Restore our glEnable and glViewport states
... Draw an Overlay containing with fbo texture binded ...
Here là dấu vết gl của một khung hình duy nhất.
Đó là gần 800 dòng nhưng mắt opengl được đào tạo sẽ có thể xem những cuộc gọi nào được thực hiện khi nào. Tôi đã xóa vài trăm cuộc gọi vẽ mà tôi ít hiểu nhất.
Có lẽ hãy thử cập nhật kết cấu qua glReadPixels thay vì chỉ để xem phần còn lại của mã của bạn có chính xác không? –