本帖最后由 shane007 于 2023-9-6 16:01 编辑
- C; d+ J* N7 {
" ^ Q* T0 M# |# x- Y生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。, I8 z: j2 A8 V
* J# S: o$ x( e8 z; Uchinese.txt保存游戏中所有不重复的汉字。
2 J" O8 f% Y: Q" g; [* {& mhook dll在初始化阶段,执行initialize部分代码,初始化字库。. ~& `; J9 b% k7 W
显示部分依旧可以用glCalllists方式实现。
% r! V" J3 @1 \5 {7 e. Q* y U7 {5 ^6 c. u
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码 ! E# C9 K# B0 D- } }
3 y$ v$ P, N: Q) K6 _! v
; Y z* m% r+ x% M5 y% R/ p- #include <stdio.h>
f1 | y/ ^7 r1 C - #include <stdlib.h>
" E+ Y$ \) }! o+ ^. F7 ?* a - #include <GL/glew.h>- F$ J# y: B5 v% u: b' u) k8 [+ e
- #include <GLFW/glfw3.h>: @: N8 R( Y# _$ {$ J
- #include <windows.h>" ~ q+ Q4 P) P' K; d/ M
- 5 ~+ [- _$ h% B* t: l
- GLuint fontListBase;3 B! Y/ q6 p* s$ E( N5 C; D
- HFONT font;
' e% N- h3 ~0 T. J, G4 M+ t( u - GLuint fontTexture;
3 R- e! A4 j2 s6 ^
" k6 Q3 b. {9 n" t- void initialize(const char* filename) {, `0 L. P0 s9 ]/ Q
- FILE* file = fopen(filename, "r");
& ?& \" r: M6 I f. y2 W( v - if (!file) {
8 H& Z2 J7 h' X. n0 p& y4 w - fprintf(stderr, "Failed to open file: %s\n", filename);! p7 e% X; D" _; S5 Q
- exit(EXIT_FAILURE);3 _9 c: u' K9 R3 l* V
- }& D2 T7 @1 R9 `, K
; `; l$ k$ `+ F1 N5 ?& `- char chineseChars[128]; // 用于存储中文字符
# i1 M d+ E+ X6 C) O9 e - int chineseCharCount = 0;
4 y: y/ n% B2 N' h1 U% T - # m3 [; h5 d. W" R6 B/ `3 m
- // 读取中文字符并存储到数组中
! ^5 K; C2 W, ^. H; J - while (fgets(chineseChars, sizeof(chineseChars), file)) {8 ~) f# f# |# C$ q# Y; K0 q. N8 ^
- for (int i = 0; chineseChars[i] != '\0'; i++) {
/ z3 |! e( ~- {0 j- Z! M - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) { j5 X" j+ A% e! w
- chineseCharCount++;
+ v& |- a. D# T6 O- T0 t0 B - }4 w1 z/ B/ H5 `# a( n4 n. n9 P
- }3 M- W4 ]# R, S. z
- }2 f9 C* i: d" d' D# n" J
# Q4 Y( o& z) `1 g9 `* d: Y- fclose(file);
, o! e# M3 i7 A1 h3 ^0 U- r
* J( j2 l# P3 J8 @/ H3 l! m1 @* ?- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表/ y' V3 t7 ~+ C$ H3 C/ M
- 0 F4 M! E, Y+ ~3 E7 Z' I
- font = CreateFontA( }9 ]2 d+ x# A2 f
- 48, // 字体高度
% \' E6 H" H3 a7 Q! q1 p p8 | - 0, // 字体宽度
2 i& i4 a" ?1 j8 L- S4 \6 f. W- y - 0, // 倾斜角度
4 w1 P; B* k" ?! m& X8 { - 0, // 倾斜方向$ R: d v& L+ T" @- a
- FW_NORMAL, // 字体粗细
$ b2 x, O0 f+ c4 [+ p* x - FALSE, // 是否为斜体1 U1 { }/ e3 U7 q5 \( c2 _
- FALSE, // 是否有下划线- S' X7 i% y; `. |
- FALSE, // 是否有删除线3 x9 f5 C. R0 ~3 O1 b+ r4 s
- ANSI_CHARSET, // 字符集
( B7 C7 c: w' L* Z- i/ j$ D - OUT_TT_PRECIS, // 输出精度
2 M$ q7 z% z. N1 y" o - CLIP_DEFAULT_PRECIS, // 剪切精度4 I% T+ R; I1 u, G9 T; `
- ANTIALIASED_QUALITY, // 抗锯齿质量8 b8 v- V5 J6 H- b
- FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch
, f( W2 f& Q0 ~" k+ N3 K - "Arial" // 字体名称
$ F5 x5 A6 g+ J" ?3 Y - );
* G5 }9 e' F0 X% s& _, |! F. v
* R s: P2 i2 f) J- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄" ]: F; i: y& t/ W# Q/ a1 u
- HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体
+ d9 k& @ T+ _/ z( o$ J* s7 R1 S - ( d* z7 i/ C3 }1 i2 @; d! z+ J& J
- int currentListIndex = fontListBase;
2 t2 l7 x7 s1 _( J
& e; }* g5 Y& ]& t1 I' _- // 逐个读取中文字符并创建字形位图存储在显示列表中2 L# v5 O- `, a( U
- file = fopen(filename, "r");$ C; F) ~" V' d* a% v& f
- while (fgets(chineseChars, sizeof(chineseChars), file)) {2 k5 T! P2 t# k$ _. v. j _
- for (int i = 0; chineseChars[i] != '\0'; i++) {- e8 z" M% f4 c3 ~9 m& l& R
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {% h. n$ W7 M/ T5 ]! V
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);* d7 H2 i: }8 }
- currentListIndex++;, ]& k8 z5 s6 U4 t m! }
- }
2 S) b% l7 @8 v - }
* H- H7 f" T& l3 G! d - }
# g. M- {7 E! E4 [6 y - fclose(file);
9 D _: }0 l3 n) d! ?& D0 J* l - * k3 t* l- x/ |
- SelectObject(hdc, oldFont); // 恢复原来的字体
5 c8 B: f& W2 ^" ^# K0 E. O
( |9 o* l" s% I+ Z+ u( o- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图
2 k# ?' x0 ?" l8 } - glBindTexture(GL_TEXTURE_2D, fontTexture);9 M2 v9 t( _/ _2 u
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
% O+ x. v8 d p - }' l% c; C9 Y5 S+ U
* J3 S8 }& b7 d: P- void renderString(const char* text, float x, float y) {
$ j, Y o$ y- z8 v$ F& n - glBindTexture(GL_TEXTURE_2D, fontTexture);; |4 {( \4 W* B7 y/ z% B6 T" r
* M% o" u& y: ^7 h- glEnable(GL_BLEND);4 i' ~( V& v! m4 K
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);$ S/ f/ s7 m* m9 |" q* s' U
( `" [0 K' A9 P8 @' N: c! ?6 G$ H- glRasterPos2f(x, y);' q: Q" t j" i' Z* O
' s8 ^6 n* q% T5 ^" `0 g) g- glListBase(fontListBase);/ i, n8 t+ x2 w7 Y- w" }8 D( o
4 l6 z& I* \; ^7 c& L# l# G5 J- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本
. d$ C: j. s5 w - . m/ e5 b" m3 ^& Z/ \2 k
- glDisable(GL_BLEND);
/ m G, I9 Y" ?) i# X: d: I - }
" F$ l: r2 U* S" F [8 z: Q - ! A) J1 ~+ C4 b8 C
- int main() {: q u& [' l. x# ^, T+ u1 M! R' w
- if (!glfwInit()) {
2 P1 a6 u: ], i* G - fprintf(stderr, "Failed to initialize GLFW\n");, S* |& }7 j' u7 \
- return -1;
& x5 h$ J" I* m( N2 P$ b - }
# t( k) h5 A1 ~5 m - " h+ i0 a. R! Z4 t7 }9 \
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
- V& p5 C/ E. A" N - if (!window) {8 @' Z) D+ H0 e
- fprintf(stderr, "Failed to create GLFW window\n");
$ x" g k& U0 ], t3 B( M9 I3 D( B - glfwTerminate();
, k& }% Z% N$ u4 g2 [ - return -1;
" M6 J4 Z- `3 n/ ~+ w: n - }
$ K: g" U2 O- C+ k# d& ]6 m, O - ! w" z; ]# [. w( |& J; I8 ]
- glfwMakeContextCurrent(window);! M7 H/ d3 R: q8 S) n
- glewInit();
5 v6 F( t1 A2 H$ u9 ]5 @1 }# _( w9 O
2 a& G1 @& Y. f. `8 T- initialize("chinese.txt"); // 传入文件名- `( r- t- U. P/ q5 e# N
- 8 f- l4 u% a* n, c
- while (!glfwWindowShouldClose(window)) {: Q+ U& x* ^) m3 Q0 ^ p, Y6 V. M
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f); t' h. M6 V- w6 z9 A/ L
- glClear(GL_COLOR_BUFFER_BIT);
0 c9 f' V" e/ r' Q2 R' f* b; e
9 L+ @/ M0 a( s" T1 b' S1 q- glColor3f(1.0f, 1.0f, 1.0f);' S C' ~% K8 g$ V8 {- v/ S9 z
- renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本3 q$ X+ R( P& H* z1 q$ I
+ Z* ~, n4 S* R- glfwSwapBuffers(window);
! ]* `" S& }( m. C - glfwPollEvents();
w" e- h. b- u9 L' h/ d) c - }# W3 w1 X. \# S9 U5 g$ r4 _
9 d1 L/ K0 ?5 \2 E* g- _0 R; }- glDeleteLists(fontListBase, 128); // 删除显示列表7 ] ^! s! q8 h. P& Q l
- - H* T5 O, V' h/ O! h
- glDeleteTextures(1, &fontTexture); // 删除纹理
0 [; v( N* Z; P; { - # q7 m, w* z# ]
- DeleteObject(font); // 删除字体对象: s0 ?& u) N5 e$ f2 g7 {1 E3 W) E9 { u
- u5 m7 D, F {5 x9 G
- glfwTerminate();# E! g" W0 J" r, _, {3 B: R* j
- , h. ^! n# a! r0 |" _5 ^- a+ l
- return 0;9 D7 Z! e5 {: Q7 ], u7 v3 Q
- }" d. g t# u# J( w# m
复制代码
4 O, I9 N: ]. ~: b1 D+ l
, X' C X( ^# L. z
2 v h, z. n5 F |