本帖最后由 shane007 于 2023-9-6 16:01 编辑 - H' N$ Z4 a& F* z5 v8 z
! U* S0 E8 J& _' `* C* V) D5 F生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。
8 ?3 O( \- ]+ N4 e
, y3 P9 R: T8 L5 a! |chinese.txt保存游戏中所有不重复的汉字。
' W' i2 \" I3 m. w3 {3 B/ Rhook dll在初始化阶段,执行initialize部分代码,初始化字库。
0 n9 c& i* `: M) |- W% o显示部分依旧可以用glCalllists方式实现。9 E6 X9 o9 j3 C3 _: G4 w0 w7 D
w$ a4 z7 X" |: ~7 y9 n! B
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码
' \0 ^4 f7 ]! w ?9 I, g; @! o- k a! }! U& s+ C: F
$ I" S% J' Y6 x7 z9 f/ @- #include <stdio.h>
* ~! s0 a0 a( k7 A' [ - #include <stdlib.h>
* O; K5 s$ @. @3 M6 u7 I; A - #include <GL/glew.h>
" U' r! S' f( a* k4 l+ \ - #include <GLFW/glfw3.h>
; i( [9 v( { i - #include <windows.h>
c1 h# \) [% O+ _4 O) B; H - " K: r* v- s4 ^9 I* c
- GLuint fontListBase;5 l! \4 Y) Y/ C6 R" ?
- HFONT font;
2 z% H& H" j( d/ Q - GLuint fontTexture;
! v2 M9 M2 U+ o9 i& S
* P9 G7 F6 e. U( N) s- void initialize(const char* filename) {/ l9 z2 s% v- x1 u8 ?
- FILE* file = fopen(filename, "r");& _$ [9 h- N! Z% k: O8 T, S# t
- if (!file) {
1 V) ^" b9 a! |7 i2 z - fprintf(stderr, "Failed to open file: %s\n", filename);
4 v/ i& H6 r/ k" @3 }* `- @3 S# B - exit(EXIT_FAILURE);0 }6 c0 e2 e) D2 ~7 |3 v
- }
2 S P' {9 Y. X7 s
9 i7 a, y: `9 Z c# y% J$ F. [- char chineseChars[128]; // 用于存储中文字符. l% ^, t7 T$ i+ Y- x
- int chineseCharCount = 0;0 @* l* Q9 B& o/ M/ f
- 9 X. ]6 o: b! t: I# |! Q
- // 读取中文字符并存储到数组中
! T1 S8 b7 k( y: E# U6 j - while (fgets(chineseChars, sizeof(chineseChars), file)) {- i6 ^7 [( C/ B a* @
- for (int i = 0; chineseChars[i] != '\0'; i++) {
% A( I- y- h6 s7 {8 ` - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
* I G3 b) T6 J8 t/ W( T - chineseCharCount++;; T; n6 p1 U+ H# t
- }
' _( L: R, S5 z3 U* d& U% x - }+ a$ E# d/ E% k* j/ k4 \
- }
n% H. D0 v! T- J: _% D
3 W; q. k( h0 q# e- fclose(file); K# j$ Y1 r$ G1 ^; G* n: l
) g- Y6 R% F' l8 M( Q, ]8 S- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
0 M5 K2 J z% [# y$ L# J$ k" r6 Z
+ w( K& A) p, w8 a4 f0 q; ^- B- font = CreateFontA(
( `7 u$ I6 V9 y5 I' J7 d' Z - 48, // 字体高度
5 Z5 S+ `9 \$ E* y& T- |$ { - 0, // 字体宽度7 U* u v4 Z) \8 [, _
- 0, // 倾斜角度9 e3 H x, J5 B& A: `0 i; ^
- 0, // 倾斜方向0 `0 D+ M' V/ Z8 u, T$ s# u
- FW_NORMAL, // 字体粗细
8 }2 L, b' l7 ^3 l: e2 e3 @ - FALSE, // 是否为斜体2 u Z- M+ G1 f R# K+ ~
- FALSE, // 是否有下划线
3 d$ }5 r, X' {2 l" v( p, j( W2 a - FALSE, // 是否有删除线. L, D6 b H4 j; ^! S0 I# U
- ANSI_CHARSET, // 字符集
( P/ h4 Y( V% W8 h c - OUT_TT_PRECIS, // 输出精度5 g/ C# K! m$ _' J. b
- CLIP_DEFAULT_PRECIS, // 剪切精度2 R7 Y8 z% I6 @ V+ ~' \
- ANTIALIASED_QUALITY, // 抗锯齿质量
+ j; `+ Q/ X: T8 Q6 P# ] - FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch; V, j, |$ w1 ?# D N+ t
- "Arial" // 字体名称
* ]% N2 v+ i# H+ O/ |" D; C - );
2 q" H7 L& c7 v
2 F/ U8 W0 G2 k( _ J. O- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄
+ \6 Q- Q& ?' h* Y - HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体! k3 C; @( G' p" S) _9 V6 C, V
8 S7 K- k2 t1 Z( a; C- int currentListIndex = fontListBase;
$ O1 R# ] a4 q& k6 B- S5 s - 0 ~& q Y' P7 O! \& {1 R
- // 逐个读取中文字符并创建字形位图存储在显示列表中
) T& P9 O& r ^/ }" C% H - file = fopen(filename, "r");
8 K, i- P0 f( J7 ~' b - while (fgets(chineseChars, sizeof(chineseChars), file)) {; S, h, K1 @9 j( K% ?" E3 D8 y1 W
- for (int i = 0; chineseChars[i] != '\0'; i++) {7 h- `, e+ L8 R% s0 c3 Y
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {1 Z: X# T. f; {# K) [$ J
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);
% C( s+ K: ]2 H3 W - currentListIndex++;; k0 t" z: X5 d5 P9 d
- }+ \5 Y8 I S- E2 L3 k; s' ]8 p, G
- }9 L! h' k9 ]! M+ Z/ c
- }
+ a- ^4 C+ ^3 X/ c7 l3 p - fclose(file);
! V1 n1 ^# O0 t3 g
$ x9 g) P1 P( n+ _; {3 E- SelectObject(hdc, oldFont); // 恢复原来的字体& W1 Y, A3 @: Y8 B: u* l1 p: a" {. Y
+ O3 g3 h% V) N. K- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图
n! f+ z; r! ^ - glBindTexture(GL_TEXTURE_2D, fontTexture);
5 C$ F) Q# U0 b - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);: |& x) V, ~- N4 X% e2 P* H1 ]$ p- Y$ ]
- }# ]5 N( }" F) [+ q* t$ i) o# }
- + ?# Y' H2 F, W% J$ K) L* a- | G
- void renderString(const char* text, float x, float y) {6 P( b5 a! D5 m
- glBindTexture(GL_TEXTURE_2D, fontTexture);! l' s/ t7 G. t6 v' J' z$ P: K
- # Y" F& R! }0 |. c1 h) F9 P' d
- glEnable(GL_BLEND);( B: @+ O: ^, C$ b: f
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Q3 Z. P" V( I
* N! {& Z: Y, h/ L3 n) R% D- glRasterPos2f(x, y);
+ _, | C+ L6 y - 9 E2 F) g) G3 N2 I7 e _ C
- glListBase(fontListBase);
) V/ T, A+ V, g5 a3 W1 t
' M% v6 l1 ` F8 b& Q- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本 t, \' ~: f" [$ o, G
) `+ h, L; g& B9 b1 V2 j& t5 i- glDisable(GL_BLEND);% f/ S4 W% n7 l2 s( I7 s& I
- }
8 {; W: x$ [) ?8 T& l- s/ f# f4 } - ; x8 @4 ?' Y( y2 `( d% |9 F. }
- int main() {1 r' R A5 J1 ~ s
- if (!glfwInit()) {
$ u2 N' F- r+ t( ? - fprintf(stderr, "Failed to initialize GLFW\n");
1 y* Y, {- M; a% ?; k* ^0 N1 H+ _- { - return -1;
- X! t ^ E" k8 ^' j - }
+ R& I5 L! S* S N0 p - - f- p9 L# P, o- N- n c! V
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);( |& u$ i9 ?* ]* b
- if (!window) {
4 f4 Q* [3 y& P' @ - fprintf(stderr, "Failed to create GLFW window\n");
& ]9 V- \1 S5 S3 Z3 M! C - glfwTerminate();
5 D: }$ u s; T8 c. W) b - return -1;
1 J) x$ K% m6 n9 s - }
' F& f' t9 h# k; M
) d/ K; P( O2 o" w- glfwMakeContextCurrent(window);
Y$ u8 |2 u5 i7 K4 S - glewInit();
8 b% Y% M) w- h- c$ a
" `0 | k! U9 d5 e- initialize("chinese.txt"); // 传入文件名) G# b. l; f7 k) W& o
- ' [1 I# X& J! J- O; c
- while (!glfwWindowShouldClose(window)) {& I# V w* e/ j- A7 \
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);9 I1 G& J- _6 k' O" T
- glClear(GL_COLOR_BUFFER_BIT);3 [& Q6 ~# F8 Q. _6 w0 f
$ E1 }2 o: r d9 q* G$ t$ `! d- glColor3f(1.0f, 1.0f, 1.0f);4 T G& ~4 A6 A
- renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本
7 t" x7 ]# n6 b* n$ h$ e- S! J
9 q! u/ F/ Q. O- glfwSwapBuffers(window);9 k! Q2 R* g6 ~4 V# t% B
- glfwPollEvents();6 m8 R+ y0 `1 r5 f* _
- }& ^" a+ H3 P, V- I6 u3 F
" a- {0 y$ T. ~5 T7 c8 s- glDeleteLists(fontListBase, 128); // 删除显示列表( A# e/ I% F" {/ ?9 n: V
9 w8 N$ u- ? u6 }- glDeleteTextures(1, &fontTexture); // 删除纹理
5 S! y$ @! w! U4 |2 _$ _6 y( V - 5 ~! b/ [3 p1 C* ^) V
- DeleteObject(font); // 删除字体对象
& s; u( \ c8 l3 L0 X - + [7 @- G: ~; m
- glfwTerminate();
. `# [* T! l% N" ?1 V1 @; s: s/ d
, |# v1 P6 G2 A; Z# ?) ?5 K3 G- return 0;
[3 e5 W4 u2 R, A - }
# y @ x. C2 c. B! l
复制代码
' D$ B f( \$ c$ m% h* F( s5 d/ K9 o! d! p& t2 _% X
8 G D/ o& h+ R
|