本帖最后由 shane007 于 2023-9-6 16:01 编辑
+ F+ B ^) {2 u/ s* [5 Q ?% j' Z3 T8 S
生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。
7 t: L' B% N& {+ v
2 K6 U8 w) | I4 F" P8 lchinese.txt保存游戏中所有不重复的汉字。- z. c" p) E1 p2 j; E4 ?1 I
hook dll在初始化阶段,执行initialize部分代码,初始化字库。
: g( s" o" y% o/ F& v$ M6 X K显示部分依旧可以用glCalllists方式实现。
7 [: r7 u* _8 @- j- @0 E* i5 j% M2 ]+ a" y/ H4 }
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码 * w3 ^% B: a5 Y- U7 L K
1 _' _% N, @* ~3 S1 a! O: h" w" L2 n# ~4 w# ]- v& G H' P4 D
- #include <stdio.h>
$ a1 q9 A1 ]3 } - #include <stdlib.h>9 Z7 ~& Y& c, x9 m# I# H. ?7 E( H
- #include <GL/glew.h>
0 I6 \0 g2 F% o7 n - #include <GLFW/glfw3.h>
$ h+ ~9 R8 P7 \0 A6 \$ y% a, q6 M - #include <windows.h>
. I2 z: ?/ g/ n) M1 q( {% w ` - , e: h0 }, M H) Q4 u9 |
- GLuint fontListBase;
8 N9 p( c* Y' ?% f, C - HFONT font;4 w1 V" O! E3 v$ e
- GLuint fontTexture;
; P1 V V0 Q3 E. R D
4 g5 A C9 k; q0 t- void initialize(const char* filename) {+ x, G. b+ W+ ^8 ~4 @
- FILE* file = fopen(filename, "r");
% N9 B6 f) d3 r" f9 A - if (!file) {0 L, V/ M! g2 V" r* c
- fprintf(stderr, "Failed to open file: %s\n", filename);
+ p; f- B: D6 ?! c - exit(EXIT_FAILURE);& I$ c2 a4 t; D( D) U$ b
- }) b1 A* Q1 q5 G! S: O
# B- D" J8 C3 y9 B; R% D/ F- char chineseChars[128]; // 用于存储中文字符
) y6 O4 s. @% P. |( t8 Y0 z( w - int chineseCharCount = 0;5 n: d/ a5 U! L* C4 c
7 A: O! j$ I$ X- c& Z) Q% {5 e- // 读取中文字符并存储到数组中
# |. n: H! J- Y0 T( @7 l - while (fgets(chineseChars, sizeof(chineseChars), file)) {
2 e* w" _' l1 B. N. [ - for (int i = 0; chineseChars[i] != '\0'; i++) {
$ I6 R! S* L0 j1 I* }4 C! ? - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
( i7 X0 B1 r) k* H7 L2 i - chineseCharCount++;3 e- |7 G" \, v/ M- q6 v+ a
- }1 t- V& r5 s* V# z+ C3 V! V! w
- }( S0 n+ C5 `5 y
- }
, I9 E# |2 Y* | - # n$ U9 D+ e* q' r( @8 Q1 ?
- fclose(file);
+ e# \9 |# V- d0 r( @ - & l a' P2 R. l' C8 d% s7 w8 M! ?
- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
h# z: f' \# Q/ v4 R, h/ w$ `2 m - Z4 g: g, L( m6 {* j" j
- font = CreateFontA(
" a- W* }; r7 g0 G0 }+ C; x - 48, // 字体高度
. w: M' B3 c" `2 E' c+ ]7 ~& h - 0, // 字体宽度
4 L: _1 l$ M& \* I7 e6 N - 0, // 倾斜角度
+ G6 l! d) D+ s+ Z) [5 A7 N - 0, // 倾斜方向
6 i9 p1 Y; i3 M' h: _* r: @( { O - FW_NORMAL, // 字体粗细5 N2 H# c* j7 ], M+ W. ]6 h3 ]
- FALSE, // 是否为斜体
! ~9 @' k* n) E Q( b1 ? - FALSE, // 是否有下划线
! B9 n3 _+ A- _, v2 a3 a3 Y - FALSE, // 是否有删除线
6 a7 ^8 t% X4 I( s - ANSI_CHARSET, // 字符集
6 P9 o {1 s) O2 l& r - OUT_TT_PRECIS, // 输出精度& x8 v9 \# Q. h; W7 M$ w
- CLIP_DEFAULT_PRECIS, // 剪切精度8 q7 T- ~# s- @, B9 r; |) d) C
- ANTIALIASED_QUALITY, // 抗锯齿质量
% I" R; I4 J) i+ o9 {: i - FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch) s, t8 \3 m9 D7 S) ?2 C5 W' ~8 U
- "Arial" // 字体名称
# [7 b0 j- l1 L ?9 A- z0 y* P - );8 ^2 p- t: S% J: T' y |) o/ T+ ?
- ' V$ J7 v0 v5 i
- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄( s. t9 O+ W5 X3 A
- HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体
! X% O* l0 ?6 S6 o3 H5 ]( ] - . @5 O+ w, j4 h& ]& f# w4 @( D$ n
- int currentListIndex = fontListBase;
/ t! C# X; J9 w' h/ O1 ` - , S- a- t l: Q6 l) T3 w+ h
- // 逐个读取中文字符并创建字形位图存储在显示列表中4 W* f4 s7 S7 N9 g0 p: O# O
- file = fopen(filename, "r");$ |0 i9 ?) \. Y- a4 e6 ^( c6 ^
- while (fgets(chineseChars, sizeof(chineseChars), file)) {; I, X0 N8 U* V. Q8 a
- for (int i = 0; chineseChars[i] != '\0'; i++) {
# m# r: n+ S" y) f3 U' { D/ J - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {1 E$ u7 J! v" T L/ _0 v9 W
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);! t m" a, Y* }& ]9 [" ^: F
- currentListIndex++;! b8 j8 o! a1 \+ B% w
- }1 ^) H- p( n) w8 u5 O
- }
+ k# m7 i6 b: X& w5 x - }
$ V" I4 r' e( M3 X! j0 k - fclose(file);2 Z6 M. d, M1 h! I7 D0 ^
- 5 k% A6 G! t& F( D1 S' |3 k) H
- SelectObject(hdc, oldFont); // 恢复原来的字体
* S# N+ W. b6 Z# m; _ - - w* |) m, w2 R2 y7 `
- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图, S3 B; {4 S; D
- glBindTexture(GL_TEXTURE_2D, fontTexture);
' S$ a6 c0 f2 @1 n - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
, ^2 K% t! g! Z/ T+ t! n1 m - }) w+ u0 r; K+ H/ L1 w0 ?* ?0 N ?
( r6 ]5 q) t3 u- void renderString(const char* text, float x, float y) {! C& @/ W. i6 b
- glBindTexture(GL_TEXTURE_2D, fontTexture);
6 r' K7 I6 }$ j: m0 n& [
4 ~: n. {4 l1 O/ j- glEnable(GL_BLEND);5 s$ K% p, V! e6 t4 S+ p
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);1 ~3 J8 E& y2 A. G+ a
- : B( U- m$ Q7 M7 L l
- glRasterPos2f(x, y);, {$ C, H! H$ s) Q& Q
- " i. m9 F1 m# Y, i/ f4 n
- glListBase(fontListBase);4 @ r3 x. p# t# G
- ) {6 I9 H1 O& F/ ]& X
- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本
$ f: t" @( w; S; m
9 l7 `5 Y$ C% z: v4 r; t0 E- glDisable(GL_BLEND);
- \0 Z' B2 H/ k1 T" J: i) \ - }
0 ?% X( g6 d% t5 {5 M: I - ' [$ z' D9 ]; L6 }
- int main() {/ y% P$ h ^8 B2 w- a& R( }3 A
- if (!glfwInit()) {, B" O6 k( H: u3 b2 J# a
- fprintf(stderr, "Failed to initialize GLFW\n");
4 w. S" _6 T9 _. I; R6 t - return -1;6 Y: M+ r" X7 J# I5 f
- }
0 E8 M, I/ f% B z: p8 A
K7 `( ?9 T( b4 e- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);2 D9 n+ m L0 z- D3 ?
- if (!window) {. z9 r+ U( ~. o' X# h+ L- g
- fprintf(stderr, "Failed to create GLFW window\n");6 J' k( U# q7 L8 y' U# G
- glfwTerminate();3 T, M$ `& `2 |! a* B6 ~+ |9 @
- return -1;- m7 L F# V% E( b+ y
- }
; q( t% S' Z3 V- g, r7 u' @* Z* V - * q; ~* B/ U$ V8 W" Z
- glfwMakeContextCurrent(window);7 w2 l O( \ k
- glewInit();
7 y8 Y4 D# @* ^4 N, m9 r, N* M
$ k& }7 b( F" z1 f8 W A- initialize("chinese.txt"); // 传入文件名
2 h& W6 c9 d O! f. ]( `# S
$ n9 X7 W, F) S, L3 `" j- while (!glfwWindowShouldClose(window)) { Y: l8 n" [' l; o1 \# X
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);2 R# B/ s; e4 M* B/ \" X
- glClear(GL_COLOR_BUFFER_BIT);
. x2 S* u: g( S: M: W$ @
1 n$ M' [: T! P2 C$ T' ]- glColor3f(1.0f, 1.0f, 1.0f);5 O9 y, w2 Z" }2 {2 ]3 a: Y
- renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本
) B" P, t8 r+ ?# C6 O& l
: b$ X' ?! B1 b3 R! U1 F& F8 y- glfwSwapBuffers(window);
& w5 k) b4 i a: g - glfwPollEvents();# J- V. ~- B$ C% g) G [
- }$ x9 l3 {! l! @# l- L9 _
- 9 n/ M* {5 m4 ?7 t% _% U
- glDeleteLists(fontListBase, 128); // 删除显示列表
# h& f: p! C; d" {, } - . q: _6 ]; p# \- E# \- t, n6 G
- glDeleteTextures(1, &fontTexture); // 删除纹理
% Y4 R+ l$ S/ i7 R8 l4 M# ?0 X
6 k) w. v% p* t( l* m9 d- DeleteObject(font); // 删除字体对象2 a% d1 x* q$ n! }
8 G8 \" |4 }0 m) M* f- glfwTerminate();
2 m( q2 P: [! {+ U& g. H+ c - 8 n1 B3 R: @, J$ x% O2 A" Y3 W
- return 0;2 Q# {5 g8 }0 c
- }
# y' k1 F- L2 a6 d2 |) A
复制代码
& d% W4 K$ l. t) K& l' L0 u) s. B8 G9 X7 T2 M: E6 K) o! V V( z1 L3 E' J
5 Z% V; ]7 V: ~/ J |