本帖最后由 shane007 于 2023-9-6 16:01 编辑 0 @1 @0 s# j, g; I
$ G* F, V* R0 M8 L8 m& X6 S+ ?
生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。; [8 R2 }+ n! z* [' e
* ~$ I. B# t. j: ~" Q4 e5 w! _chinese.txt保存游戏中所有不重复的汉字。
7 b Y$ }, d$ }( Rhook dll在初始化阶段,执行initialize部分代码,初始化字库。8 i5 K% ~$ d3 n: t( I! y
显示部分依旧可以用glCalllists方式实现。5 ^+ L) q* x( w s: n( A
9 X) C+ l: `1 ~6 ]% M# R- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码 " y0 _1 V5 H. G) S% K' S7 @
$ w0 _7 }. Y: V8 t5 b" T) [, x4 ]
4 n6 S5 q+ }1 f) j& E4 w: o- #include <stdio.h>+ e/ h2 q+ X7 w/ D/ k$ d- y
- #include <stdlib.h>
: k1 D" a' o: W" O/ {, o. k - #include <GL/glew.h>
9 L* r1 v9 a* r: p& f) @ - #include <GLFW/glfw3.h>2 X8 [( b" v( G- L; ?2 C
- #include <windows.h>2 P s9 K+ s% p7 F& q- q
4 _! T' Q, t" j& ^. z( R/ o/ T1 F- GLuint fontListBase;6 q% x$ H9 M0 o, j5 G
- HFONT font;
! s5 w s6 Z' G! N9 B$ Z G$ R! a - GLuint fontTexture;9 ~1 u7 E, f5 X) w/ J
- 8 Y) Y' j, s9 }* B6 A
- void initialize(const char* filename) {) C4 v: G3 n: n! T$ X
- FILE* file = fopen(filename, "r");
- g& b: B* m) B' p - if (!file) {
% _( q+ E/ A" Z: C/ A* | - fprintf(stderr, "Failed to open file: %s\n", filename);* M2 w, t9 D& g' s9 n
- exit(EXIT_FAILURE);
, ^6 k% B. H9 u' N - }: a7 d0 H# y( R7 r/ y ?
$ S- w% N* U) C$ M+ L) D- char chineseChars[128]; // 用于存储中文字符3 c l. B J" D) E! Z. l( k: p
- int chineseCharCount = 0;
8 f5 b4 ?* n' v5 Q0 ^ - $ l9 K$ n: b$ x+ Y# o6 \% T; D' o
- // 读取中文字符并存储到数组中
4 `. A4 S# y: Z0 J& F/ R: g/ i1 L2 Z - while (fgets(chineseChars, sizeof(chineseChars), file)) {
5 s) f& r) y" q2 z9 C' v2 R Y - for (int i = 0; chineseChars[i] != '\0'; i++) {0 |5 Y$ d& w( L. J9 L* F: w8 B
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
7 B: D# h" B S" l* [ - chineseCharCount++;
6 g, l- p5 a$ g - }3 i( z- S/ R. U! v4 a+ V/ Y
- }6 h& y9 N' _7 q
- }3 _; T5 J R" l" D( [0 K& ~: B/ k6 `
* s& g: |& y3 ^$ z- fclose(file);& W/ h. O& u/ s7 y' M9 ^
- 1 i) S7 z; B7 J
- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
- Z6 D/ `0 i* h - ( R" y9 `& x4 o9 Y1 ~" D- H/ t* t
- font = CreateFontA(4 w+ Q6 O7 }7 N" E+ y# a" W
- 48, // 字体高度
' Y8 C1 e& e4 E" S - 0, // 字体宽度
# {: g* m' ]2 f& B4 ^9 X2 u - 0, // 倾斜角度
3 x7 ^( ?9 F5 P. H9 U - 0, // 倾斜方向9 P, I* |1 L* J( n% @! [
- FW_NORMAL, // 字体粗细
' u) T, p! z M# Z, b" W- ~4 L' J$ T - FALSE, // 是否为斜体3 P" K5 l$ o n. e( F( u4 V! |
- FALSE, // 是否有下划线
* ~ _ S9 D( F: G/ D% d% P - FALSE, // 是否有删除线3 B& ~; P9 l7 l. S( @; H2 h- o
- ANSI_CHARSET, // 字符集
: F" v+ f. ?$ W" y - OUT_TT_PRECIS, // 输出精度
/ ?3 [8 \) ]2 [) p - CLIP_DEFAULT_PRECIS, // 剪切精度
8 G8 ~2 t+ k' k4 m2 z. S - ANTIALIASED_QUALITY, // 抗锯齿质量! l; q. i0 M3 r0 N3 G+ R, B( f
- FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch
) u9 k' v" M( u - "Arial" // 字体名称
' `, w- ?6 u" u7 s6 S' t( U* `6 H - ); [' U# T q3 v( Q
- 6 }: }" o6 l/ r0 a9 Y9 Q
- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄
) s4 i9 W4 g; }5 a& a) ` _+ J - HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体
! r: H# x+ t7 ?! ^' Z
9 Q% Z% t6 j) U, K2 ?2 B, W- int currentListIndex = fontListBase;
' h' f- q' t- L - & T4 t" m4 E$ _9 T; q! o) n
- // 逐个读取中文字符并创建字形位图存储在显示列表中5 D% o. M& z- i' R
- file = fopen(filename, "r");$ @& u, b% r$ P( Q- F
- while (fgets(chineseChars, sizeof(chineseChars), file)) {
) B6 p5 q$ f: B - for (int i = 0; chineseChars[i] != '\0'; i++) {2 T8 E$ L. G1 O3 P
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {9 ^+ _4 u9 q" v: N, \! P, C0 }% B3 G
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);
* g3 |/ |) L# M) u$ i - currentListIndex++;
- L6 B* N3 g& D; R! g; U6 I. p+ O - }, c! Y( I, G2 ^0 L, w9 ^
- }
* r2 p5 k+ E- C" b! h1 D2 ~ - }
6 M% p% W5 I% K/ U2 {& C Z% a - fclose(file);* H) P8 {2 E8 Q% y
- & D$ }: U2 T, U; O! o; C0 {
- SelectObject(hdc, oldFont); // 恢复原来的字体* s9 }4 W7 b! t+ i% Z! c
- & s0 Y7 Y: i' C& c9 B. z
- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图7 ?# t6 _5 N; y: O, Y1 T
- glBindTexture(GL_TEXTURE_2D, fontTexture);
7 |; i; d [* V2 T - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2 h. J+ F0 G9 L% B% a* D - }
$ i% |9 C1 p, H- O4 g - ; U. h2 T$ V) k$ }5 ]4 r- j- P
- void renderString(const char* text, float x, float y) {
5 P U4 ]) c- U' b k* [( k& ` - glBindTexture(GL_TEXTURE_2D, fontTexture);
, s3 z/ m; t: c
& ^3 r7 F& K9 Q- glEnable(GL_BLEND);! n1 o- j; u U h' L( ?" H
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);5 f5 v; w$ p- G7 g0 ]
- ' }6 X8 Z- C% n$ S, L6 z! Y7 p
- glRasterPos2f(x, y);
7 N( {! J4 m: Q& A$ p3 e7 _3 R) ]8 Q; X
: l" o0 w- g0 t2 A2 F' F; r- glListBase(fontListBase);8 e: i3 q2 l X: r8 n
- 0 t: l; M) m. X+ Z: D* K, d
- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本6 a3 S: ?3 }3 N4 W" M
8 m/ t/ A \" e7 G- glDisable(GL_BLEND);0 T3 n7 x. ?0 E& X# Y) C$ [
- }
* r5 w5 S5 j9 \
2 C2 u2 u5 j+ l! _% ?- int main() {9 r5 {! G4 q1 u) ?. I7 r) X
- if (!glfwInit()) {
9 c9 a2 t6 G9 P2 B - fprintf(stderr, "Failed to initialize GLFW\n");4 T6 k7 \ t0 I
- return -1;! F- [5 U0 p! P: Y4 j
- }$ n' p3 W0 f' m$ v
- ' e/ B w) ?7 J
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
/ @% B' z2 Y& F0 l& G" M9 ^# D - if (!window) {1 Y7 h* I$ R0 G8 [1 e2 Z
- fprintf(stderr, "Failed to create GLFW window\n");, X% w3 q& v+ M4 f: t2 S4 S# m
- glfwTerminate();
. ]0 w: p% j, ^3 U5 [5 A - return -1;2 o* r9 W$ O& r0 S$ L
- }- U$ K$ `5 H% {5 L6 @
- 9 `+ ^9 o5 Q" A; p4 k
- glfwMakeContextCurrent(window);
l% b5 x% v* [9 B6 g, K4 U - glewInit();7 \7 T# ~8 a" f. G. q. B
- " W0 Q% x+ {. j1 M( P, _5 u
- initialize("chinese.txt"); // 传入文件名+ Y9 V& M& l1 ^, ?3 E
7 T/ E3 D/ j |) ], W) R Z- |. {# J" [- while (!glfwWindowShouldClose(window)) {
/ n7 h& g0 L& m6 U7 V b3 _ - glClearColor(0.0f, 0.0f, 0.0f, 1.0f);) v, \8 @/ {. b. l% u. T
- glClear(GL_COLOR_BUFFER_BIT);! ^% t1 D& H& B' C
- 3 ]3 s# t+ {) H! c7 `
- glColor3f(1.0f, 1.0f, 1.0f);
# E) d: n- O. [# ] _0 p9 q - renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本8 |2 \" q) D( ]4 r" K/ m
9 V, B) X |, ~- glfwSwapBuffers(window);
3 d* J# E0 f# X K" `1 }! e - glfwPollEvents();
8 W6 Y4 a0 r- I4 ^" Q - }
) w/ }; V2 x9 K
% l0 I# q! v9 t0 H8 a( B- glDeleteLists(fontListBase, 128); // 删除显示列表' T# l+ r# U* O3 f# C, {) K
- " } s6 a; a7 V
- glDeleteTextures(1, &fontTexture); // 删除纹理
1 _* V; |# C. |! ? [- G - 5 z; ?3 w* A$ i3 l4 P
- DeleteObject(font); // 删除字体对象$ M. t e6 z, y
- ! H# C! e) T. ?( }& L9 j+ {8 O
- glfwTerminate();
# @, T9 N1 v8 u- W! L, r) t
, g& a6 X& k3 a- _# Q# r- return 0;. v1 Q& U) u# d% n+ s9 n! O
- }2 Y8 s& B7 ]- n) F
复制代码
/ L5 H+ Q6 f+ }8 [; m3 k
( d0 B6 l+ V- k3 E) c
& c8 J: R$ i2 U0 k( `$ A# {$ ` |