本帖最后由 shane007 于 2023-9-6 16:01 编辑 4 _/ X: R2 q# y9 p2 M$ ~
/ Z" b( P9 k9 ?; Y生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。; b7 y4 N6 A' u* `( |$ \8 `
: h/ F; ]/ B, `( A3 O jchinese.txt保存游戏中所有不重复的汉字。
- D$ |# @- j/ y( Q* Q) S; mhook dll在初始化阶段,执行initialize部分代码,初始化字库。
+ ?9 N7 I5 H% k" _# s: V4 s: T! W. a显示部分依旧可以用glCalllists方式实现。: u* f) N* x1 U/ q P" k# k
3 E1 s* x( e) V
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码
, r% u! s) G. B9 U; M U$ g9 X
( e6 X; W; ~$ T: Y& x
2 L9 N5 P% ~- Z8 ?1 p. r- #include <stdio.h>
% x% ^8 l0 D, n. S7 t - #include <stdlib.h>
% I \7 c# h" D. w a - #include <GL/glew.h>
' k% {0 D9 D1 Y* R9 L - #include <GLFW/glfw3.h>
5 |2 d. c" L) l% f - #include <windows.h>% e1 O5 H1 x6 o$ V' C. ?4 _
- 3 k6 Z M) M9 n
- GLuint fontListBase;
; r8 g0 m1 R X" ~3 _+ v) R# }* y - HFONT font;# w# \5 B9 l9 e4 Z' M
- GLuint fontTexture;
U x& ^5 K; I3 N
4 B5 s6 } H* L8 Z+ r- void initialize(const char* filename) {( E1 {+ f* Q! R
- FILE* file = fopen(filename, "r");, _. M9 X$ O% V% i; G0 j. w
- if (!file) {
5 E0 F0 L8 L& g% Z - fprintf(stderr, "Failed to open file: %s\n", filename);: i8 \) P' g# h( K9 o' ^" d
- exit(EXIT_FAILURE);
/ q/ G; O& B" Y$ _( b - }: M; I( A6 B7 _3 y* N% y
1 U. s0 \+ H$ U5 G% Y- char chineseChars[128]; // 用于存储中文字符& |. U |* y6 \/ Z% }
- int chineseCharCount = 0;/ R. T; u1 ^$ |! R) V
- $ B# b7 t+ a/ }
- // 读取中文字符并存储到数组中
s2 A* p& Z9 |' G; J - while (fgets(chineseChars, sizeof(chineseChars), file)) {; \% i$ M+ s5 E l* q' Z
- for (int i = 0; chineseChars[i] != '\0'; i++) {
0 N* o6 M* {, s! |1 J+ C - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
% D7 C/ [) {6 b; o8 { - chineseCharCount++;
' c5 J, m8 \5 x' W% n - }3 d" N1 w, P8 J: I1 _, K6 W
- }& O( D& O# u+ v2 E3 x
- }
2 Z- \4 J& ]2 k - 1 b+ }: v1 Y# |" W- {2 _
- fclose(file);
5 t; w: h; T, ]# A4 ~; n - + Q" ~" B; @2 _
- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表, a% V$ J! \7 z
- $ Y% m* v, e H+ Q, f" X
- font = CreateFontA(
: k3 m9 u- c' o- v0 } - 48, // 字体高度
* s& q2 ?) J' ? - 0, // 字体宽度
/ ~. a, H6 @, _4 D" e- v - 0, // 倾斜角度
3 O [+ P1 b7 ^' z/ w - 0, // 倾斜方向
% a& I% h8 v( g) s" ?! v - FW_NORMAL, // 字体粗细6 z3 s5 C: L* K+ L1 i1 k
- FALSE, // 是否为斜体
6 m9 |$ g" h( b; ~. m - FALSE, // 是否有下划线
2 s* G' K6 K9 d& H - FALSE, // 是否有删除线: ^2 v7 y5 e* U$ u! ~4 z
- ANSI_CHARSET, // 字符集
% M9 }7 F. p& Q9 m8 B" r - OUT_TT_PRECIS, // 输出精度: a8 l: D4 O. f7 `& W
- CLIP_DEFAULT_PRECIS, // 剪切精度, c" N: I# m8 I1 B5 }
- ANTIALIASED_QUALITY, // 抗锯齿质量6 q/ H" z: @3 u
- FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch
. s' v+ W3 k( T p* g - "Arial" // 字体名称
* I$ n& Q8 ^# i! N }6 h* L" } - );. U6 Z7 X" ?7 ]0 N
- ! W. H! k) n( R8 X
- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄
) t$ W6 d% q2 r# r8 O" U* m - HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体
9 ~1 w, {: m; [" _- i - + G4 S( n7 R2 p1 w7 p
- int currentListIndex = fontListBase;
' a8 A4 \7 P. y" J! o
9 y& ^# \- ~! j. c- // 逐个读取中文字符并创建字形位图存储在显示列表中! y8 X* K4 }* O4 z4 [
- file = fopen(filename, "r");
% B5 f& Q1 s: x1 O0 } - while (fgets(chineseChars, sizeof(chineseChars), file)) {! f1 _3 u l4 Z x
- for (int i = 0; chineseChars[i] != '\0'; i++) {7 ]! V. X$ C( ^
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {2 z1 v0 y) Q/ V% T7 Q/ ~
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);1 O/ R6 {6 w' e5 d6 |' S
- currentListIndex++;: {, B4 p3 s% C, _! I+ K
- }0 C, Z W0 _5 N8 W
- }/ K' E$ F" i0 w: [
- }; R; {1 \- B" ]! N2 ]7 X9 t
- fclose(file);8 L0 f. i# ^# s' ~3 P
2 m" i! ]5 v+ |+ ~- SelectObject(hdc, oldFont); // 恢复原来的字体
0 I P7 z0 y% m0 ~( ~; y4 ^ Z, g
* ~7 l6 Z; n- W9 O% W- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图* s( S" U7 k: O3 D, ]8 w& }
- glBindTexture(GL_TEXTURE_2D, fontTexture);3 m! u+ c) V8 H3 b
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ x1 X3 t0 p) T! \9 k6 } - }! }5 Y+ K) }) N+ Z+ w2 C" F
8 X+ L6 n2 F& V! [) Z9 S& R- void renderString(const char* text, float x, float y) {2 k+ J. e6 B: W4 v E5 E
- glBindTexture(GL_TEXTURE_2D, fontTexture);
. n0 r3 B2 M7 U3 x) ^& {% `1 S - . f3 {: A% N4 B6 f4 h6 A! K7 d' ^/ u
- glEnable(GL_BLEND);7 Q; A! C0 w) }: x$ A+ ]
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
$ K* k! T. B3 U! s, J1 y+ v
$ q3 a6 `. y3 x/ m2 q' r- glRasterPos2f(x, y);' e( r j( ~+ r
0 H' h9 S# C$ w2 K; k, `$ A; l9 C- glListBase(fontListBase);
6 J# e5 a$ n9 E+ K3 O& J: v
: q7 A1 _& V( O- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本
6 g+ n& ~5 I+ G" H7 [3 u+ e
& \8 E& y$ F5 Q- glDisable(GL_BLEND);
& O4 k) C$ h. ~3 j; u2 e - }3 L& d S( i1 l' O& \+ L; N
- + S0 S! ]) Q! [4 Q
- int main() {! ^! y* `( @9 U+ a2 v; f" B- w
- if (!glfwInit()) {, m/ H2 _* f. W( c# C
- fprintf(stderr, "Failed to initialize GLFW\n");1 A( p. S+ y- ]! K+ H2 L9 M
- return -1;' i, [8 Z0 t- q2 H
- }
* k5 |. `! `8 J - ( M3 D7 r% `8 ?
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
$ ]; }7 h0 X- [6 m - if (!window) {
% ~7 y5 ^, a' I - fprintf(stderr, "Failed to create GLFW window\n");
8 o ~, o0 k4 x+ s+ J% j - glfwTerminate();' O' z& v- Z* {, q( P$ P s
- return -1;
; }% c7 P! W; U) D! E - }" b) V: K0 C* k: e% I
6 P; I% ~+ T. B. H- glfwMakeContextCurrent(window);% J$ z, a! T: E3 h
- glewInit();/ T+ I3 U& r: T, K
) @2 F" T0 N1 {& N1 b' L- initialize("chinese.txt"); // 传入文件名
$ n$ H# m0 ]) x3 H2 M8 B& X' W - ! l+ O* _( y2 D) d1 n! x3 Z
- while (!glfwWindowShouldClose(window)) {3 s2 O& m+ y0 _2 l" @
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);, a" z- R/ v' n# X- O% d% r+ j% o- a
- glClear(GL_COLOR_BUFFER_BIT);2 b1 p) Q. t6 I* e% x! J* }
# ?7 ?2 b: ~/ H# X- glColor3f(1.0f, 1.0f, 1.0f);
1 S& j9 y# {, w - renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本" \8 d0 R+ w. P7 }2 w) O ` g
+ M. h, \1 I8 x- glfwSwapBuffers(window);# Z! w4 U% m. A3 e( s' q3 t
- glfwPollEvents();3 ~/ n9 d8 K/ K4 @
- }
P7 ]) |- `6 ^/ ] - , M, g6 ~3 I6 W) m. d7 _$ l" H
- glDeleteLists(fontListBase, 128); // 删除显示列表3 `* Y6 S7 j+ v! A" q+ U, O5 M
- # x7 j9 }" B. ~; a
- glDeleteTextures(1, &fontTexture); // 删除纹理
. `! q+ i7 g; l
" t; U7 F! O# r2 [# ^- DeleteObject(font); // 删除字体对象
8 r/ `# y1 F( A3 y& h i$ S - Q; s/ A. i+ q* w
- glfwTerminate();- t9 ~/ H# t6 b! p$ b9 C' x2 a
3 C! N& ]1 n$ U+ k- return 0;
" N1 ?6 j+ N+ V; i) T( i - }5 z' ^ \: `0 Z6 Z/ t+ V7 @
复制代码
: O' i* I: m) j& c9 ?
% W9 O( w G; I
7 i) g2 c+ U8 H" M |