本帖最后由 shane007 于 2023-9-6 16:01 编辑 2 {/ }7 |1 E5 z0 I! b
$ h8 j/ ]! b, W) v/ y* ^9 e" R4 ]
生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。7 H. k( ^2 h$ a
& s K+ W C3 y2 @/ q/ P1 schinese.txt保存游戏中所有不重复的汉字。
- A# _/ C$ u; k# ~- Y# h5 ghook dll在初始化阶段,执行initialize部分代码,初始化字库。
+ w W. s% o3 J( L. S0 D显示部分依旧可以用glCalllists方式实现。8 U: c' z+ T, j0 b
. @) n, T, s1 t# y: U+ e! F
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码 j ? P+ K; x: F# H
: ^1 Z f) i1 A2 ^. A3 y
8 \% h* h' \: Q0 C4 O" m
- #include <stdio.h>" v6 T9 T, C) U7 X& g
- #include <stdlib.h>, Q+ L4 R" x9 u5 d$ F/ p- n
- #include <GL/glew.h>" r- a- }7 V7 i0 b) O& A
- #include <GLFW/glfw3.h>
8 E3 Q3 p1 s* l - #include <windows.h>( K/ s8 k8 |, K# c
- / f* L2 P1 R& ]3 m5 L# A
- GLuint fontListBase;
0 o2 S: h0 c1 E T; C% I1 T - HFONT font;* I+ F; |* t* ]- A
- GLuint fontTexture; w+ e1 w c8 E$ @3 B0 E$ w
- & V. n+ `# C+ n/ j
- void initialize(const char* filename) {
% o( @2 n3 A7 U4 l1 y" x3 c - FILE* file = fopen(filename, "r");
% P* O3 t: L; U; c% @, m& C, ? - if (!file) {: o/ o! ^7 g' Z" f# k
- fprintf(stderr, "Failed to open file: %s\n", filename);
# e& G. o9 z6 ]$ {- w& q/ s: ~ i - exit(EXIT_FAILURE);
9 W: j8 i. \. C1 d- Z5 F - }8 h% C. Z5 i) R: P( D
1 f6 Z: }8 @7 D% J4 z" E0 |- char chineseChars[128]; // 用于存储中文字符
! }# `- k8 L2 Z2 e - int chineseCharCount = 0;
8 w6 W4 J9 k% B4 u: D) D - ' J/ `5 T+ ] b; I
- // 读取中文字符并存储到数组中
2 M: @$ z' z/ ] - while (fgets(chineseChars, sizeof(chineseChars), file)) {9 q& R; d6 T; H( ^
- for (int i = 0; chineseChars[i] != '\0'; i++) {$ W p- n% P. I1 M3 l
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {5 F) s$ Y: }0 s$ @% b3 W
- chineseCharCount++;
$ g. O6 X, Q6 I, r& C; s - }
# b& f1 [ z n! K& J! | - }- Q+ I( y7 u8 ^8 K6 Y
- }% V9 ~1 o+ J' S) D& |1 K7 {2 k
! b6 j( v8 p6 F5 ]% }# `% L4 \- fclose(file);/ j% ^. v* w( v4 G S) D
0 P' |2 V$ Q& Z, T+ s, H- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
/ j: |3 Y$ N4 E f7 |( w - 8 B G$ {' d5 y# f a& e
- font = CreateFontA(; k# u8 n; o( o f4 K3 s
- 48, // 字体高度
6 a, r. ]1 p" M; b* |" S - 0, // 字体宽度) v' r! P) {5 v/ b% u
- 0, // 倾斜角度 y- _1 T! a& [4 j; Y
- 0, // 倾斜方向
& I0 X8 _5 ?$ _7 V( v! i- B' _# F/ l - FW_NORMAL, // 字体粗细
6 R4 l" B. a. N* R - FALSE, // 是否为斜体% B4 k/ ^! O1 F
- FALSE, // 是否有下划线! M, Q# J6 p. D% B$ I7 X& v
- FALSE, // 是否有删除线
0 o9 \* m5 ]7 O$ l/ r" G/ s h - ANSI_CHARSET, // 字符集
( I( ^+ \3 W! O3 O+ h! b( y/ ^% H - OUT_TT_PRECIS, // 输出精度! {# l2 j6 o) J) v- s5 ]
- CLIP_DEFAULT_PRECIS, // 剪切精度, ^0 t7 P+ w0 k& l4 V6 G& ~
- ANTIALIASED_QUALITY, // 抗锯齿质量
; H L) m* u: K, _* [0 x" f - FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch/ m5 g f3 a1 u6 y- L: o! M
- "Arial" // 字体名称% X/ D1 i! v6 r2 D) Q& ]
- );5 ~. r9 ]& c; N; @$ V( `+ Y, g# v
- 8 W' T3 J' s/ D [5 A/ T
- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄9 x2 }5 {# y# f" W. G
- HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体
3 s. n: A/ r' _% A% `
" j* D$ L) q8 d2 A" U) S- `" j% x- int currentListIndex = fontListBase;1 Z' @' l& D z) @
0 g6 N2 ]' Y, h& ^$ X" Z- // 逐个读取中文字符并创建字形位图存储在显示列表中
/ F, x w/ J' H- U$ W - file = fopen(filename, "r");
/ u2 u, S+ R6 ?- y1 A9 y4 e; N3 E - while (fgets(chineseChars, sizeof(chineseChars), file)) {. {; S# G! i& L2 R$ W; a* w
- for (int i = 0; chineseChars[i] != '\0'; i++) {$ F0 @1 O/ B5 {
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
5 O5 X7 w. Y* u, O - wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);2 ^3 t$ s5 h5 o N
- currentListIndex++;
- y4 U! g* f9 q1 ] - }
2 ^% _5 N- h0 G - }
4 i* |8 a( o% I - }
5 b- w. k2 m; { - fclose(file);& s4 `6 d! f& @1 z, x- q
- 4 u3 o+ B" f8 b8 F% ^& M9 d# F
- SelectObject(hdc, oldFont); // 恢复原来的字体
5 o$ E2 E7 P0 w
5 m, ~6 U1 G0 B5 t) R9 O- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图% B2 Y/ q5 G# r/ R, F8 R+ ]0 f
- glBindTexture(GL_TEXTURE_2D, fontTexture);* n0 O' q" O/ ^+ F& X: \
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1 f0 y+ S4 q% ?/ [; d# A - }
% |' y" _& P8 f4 O" A$ G3 t+ F: R- ?8 s - 0 w) ?+ C& y; b% C6 A
- void renderString(const char* text, float x, float y) {
; w) M4 t) k9 e5 R" c( ` - glBindTexture(GL_TEXTURE_2D, fontTexture);
6 G& X m7 \& k0 b/ P* X - \ Q- u2 c4 U" R. K$ Z5 a0 G' {
- glEnable(GL_BLEND);
1 g o6 Y& m( ]) B$ c* |- B) i - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);8 k, M$ a [7 Q3 o- _ g
- D6 j4 Z; _! h3 y9 f- glRasterPos2f(x, y);
* v4 J, _/ w. J( E - 8 w; D- G# d. J) f
- glListBase(fontListBase);. P/ t" y) L$ O6 Y
- 0 p( C' ?0 o! p8 n C" n$ m
- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本
- d9 _% |& [% }( T8 D% M
1 Q I! p1 r* t n1 ]8 Z0 n! O! K- glDisable(GL_BLEND);
' F" |# S$ c) {5 A" r - }! E& N! m. w0 E3 z4 o' V2 Z! i
' n8 l- X3 E ^( h" Q- A: `- int main() {$ ?% J# {' o* ~7 x8 ^
- if (!glfwInit()) {* F4 R1 B7 X' S ~" f4 z" _
- fprintf(stderr, "Failed to initialize GLFW\n");, E2 s$ `- C% h; M
- return -1;% c7 |, S& }: d2 I
- }
$ k( q2 ]5 e! f, A5 x, r9 ]: g& Q% Z - $ C8 ?8 ^9 A+ |. [6 d) r
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
" Q8 Y7 ^0 P: q. j - if (!window) {
3 a7 b8 b" T; F( r! t0 \/ ^ - fprintf(stderr, "Failed to create GLFW window\n");
! z4 f8 \* R0 C1 [$ I - glfwTerminate();0 ^; Z# R: i' l5 Q, g, u* u
- return -1;
; L' i8 q4 J/ M# ^ - }' {3 m) j- ? y2 ~% e* ^2 a6 u* i- O
- t; H" ]! w$ `- `) N9 N) `
- glfwMakeContextCurrent(window);
! {! p: f/ L3 I9 ?) _ - glewInit();
! j( Z; Z% e9 I" Q/ N3 X7 ? - 3 [( n! v% v1 E- t; X
- initialize("chinese.txt"); // 传入文件名
& x4 K/ z, D- ?( H) Z/ c" {% R+ W% I - / w2 r9 \; D0 @& C h" A1 S8 r
- while (!glfwWindowShouldClose(window)) {
/ y% j' j' p8 g3 e1 M% O% y } v7 G - glClearColor(0.0f, 0.0f, 0.0f, 1.0f);# d( }+ b/ c2 O
- glClear(GL_COLOR_BUFFER_BIT);
" X) V+ d5 g. U3 o5 J - 9 i/ X; ^9 q5 E
- glColor3f(1.0f, 1.0f, 1.0f);
9 v- F6 b9 o, U, D! @' y - renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本5 O$ @& ?& ?0 q, ]
- ( P/ o% M+ ^( |% M
- glfwSwapBuffers(window);
$ Q; e. s, g* h# v& Z - glfwPollEvents();
0 I4 Q) _6 j+ w( T# h7 l+ I - }
, K. K" `+ h: e( @$ {% U f/ w; C - / J5 \% w3 R1 I) Y, w
- glDeleteLists(fontListBase, 128); // 删除显示列表
! ^& v1 r4 D, ?7 p - & T7 F, s. q8 h) h! O! [% m% l
- glDeleteTextures(1, &fontTexture); // 删除纹理
' g+ K2 O) i3 l - : }9 ?' d9 [: T1 Y. p; r
- DeleteObject(font); // 删除字体对象
- [* _6 ^+ j+ M1 l" Q
3 z/ d6 w# T6 _& E; l- glfwTerminate();; R* w1 W0 T4 ~5 E$ [3 X
- & V( j9 Q' V7 _/ ?
- return 0;) g- O1 H& i, N7 Z; c% w
- }/ U. c. `& W1 h" Z8 c
复制代码 , Q7 J0 Z* l9 I1 g; l: f
& g8 g; g7 S& L$ [1 W1 N
" h% S4 P# m' u |