本帖最后由 shane007 于 2023-9-6 16:01 编辑 * Y, x1 z$ O' U4 O( D8 q1 v9 y
1 V/ W4 U S. ]2 d生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。# g% A* j0 Q3 A1 Z* _% S0 h; r z, g
# }- X5 d# @' R/ Z, V
chinese.txt保存游戏中所有不重复的汉字。
% R6 b) A# p6 I7 J7 Y6 fhook dll在初始化阶段,执行initialize部分代码,初始化字库。7 ]+ H# ^* `7 B
显示部分依旧可以用glCalllists方式实现。
, Y) u- t# |* ^4 E( S* D. m- e6 G1 k
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码
$ G( U+ W6 X( K8 }) s# Q9 ^6 j
9 m4 z/ E5 @& a" X& i! f
' D/ ~) S, s1 F8 |- #include <stdio.h>' r" P% Q& z# v8 n; s9 O
- #include <stdlib.h>
: U, I1 ~# a' A0 _% O% B$ E( [/ R, Q - #include <GL/glew.h>
$ z( ^ ^% M+ }1 V. e$ y' z - #include <GLFW/glfw3.h> ?% U3 w# a- X1 y9 r
- #include <windows.h>
+ U' C( V7 o9 z, n1 ?
l v5 H9 q& }2 P, q8 n; N/ x1 ~- GLuint fontListBase;& i) a5 n$ x- I$ r; s' C- F
- HFONT font;. Y' Z- N" i" v+ x
- GLuint fontTexture;; `( E. W8 h% G3 s1 L
u/ G3 R8 n0 A9 R4 p8 ?& Q* r- void initialize(const char* filename) {3 h3 u& L n- l& x. m
- FILE* file = fopen(filename, "r");
# M# q. ~& K: ~9 i0 k - if (!file) {
4 k3 C: F4 X: Z$ l5 t - fprintf(stderr, "Failed to open file: %s\n", filename);
$ ~) y3 I6 S: i$ T+ _) c - exit(EXIT_FAILURE);
9 Y7 @( ~/ r) u) h - }
+ n2 ~/ |+ z" E' s, A - 3 q3 t. G# s4 z5 o3 c2 H+ s" {+ \' S- |
- char chineseChars[128]; // 用于存储中文字符
3 |3 K4 J% M o4 U - int chineseCharCount = 0;
& j& b% @4 F( h! |) s1 D" Y
- j! d) b2 l5 S/ G- // 读取中文字符并存储到数组中
s$ N0 m. \+ `* N - while (fgets(chineseChars, sizeof(chineseChars), file)) {
9 ], F r1 x. _7 E a+ @ - for (int i = 0; chineseChars[i] != '\0'; i++) {
/ Y/ k+ u4 E {# U1 r% Y+ m/ e9 n - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {& y" }6 x! z: x
- chineseCharCount++;
9 [% m$ d% E3 H, t+ s - }) [, T6 U* q; i: K- h/ I0 h
- }$ W5 n- ?; q- p
- }
" ^6 k @" E% J$ }, s
6 u" z3 |( N4 {/ L2 }- fclose(file);+ ~1 `* V; w& [" K( w: e
0 k! {! m+ X& W9 _- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表, }1 f4 Z' S# k2 d3 W9 t
7 v6 q8 H4 b [4 o, J3 N- font = CreateFontA(
: M. w( g) i% ^+ D - 48, // 字体高度* N. S7 F4 q1 A1 x) h
- 0, // 字体宽度, @" A+ \" ^. o& D$ n# o
- 0, // 倾斜角度
0 d9 C! ^4 e5 K, Z8 z9 { - 0, // 倾斜方向
- u8 @6 v' M8 L/ w. m8 B' F7 F - FW_NORMAL, // 字体粗细, P2 }3 M' O: t/ i
- FALSE, // 是否为斜体7 w0 m s" \! E- j) q. ]- l
- FALSE, // 是否有下划线
# {6 D0 p8 O9 E+ e - FALSE, // 是否有删除线# }* U+ q B/ b, z" I# L$ L$ Z6 H
- ANSI_CHARSET, // 字符集
8 P: o* z# Z2 p9 d* y - OUT_TT_PRECIS, // 输出精度
8 X* _7 f! N, c/ K - CLIP_DEFAULT_PRECIS, // 剪切精度
4 L4 O$ |4 l" j - ANTIALIASED_QUALITY, // 抗锯齿质量: I) z0 y4 k% H5 c5 T
- FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch2 ]# i5 o* e6 S4 m# O: |
- "Arial" // 字体名称
+ @! l( }, w( ]3 }0 H/ ~" z" m$ D - );
# @% o5 F8 A8 q J1 V
0 I" q8 }5 h0 T! `- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄 |1 e h% b5 {9 J, r
- HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体; \9 ?2 p* z9 q! G' ^5 L) e2 x1 p
# J9 q8 }% j( L, j( d8 W6 H- int currentListIndex = fontListBase;
* Z- Y& Y1 y4 E
' Y$ T2 W; C) ?8 c; W+ q' }) c- // 逐个读取中文字符并创建字形位图存储在显示列表中
$ ]4 |, o- h6 p& Z6 o - file = fopen(filename, "r");$ N0 u1 E6 v# V
- while (fgets(chineseChars, sizeof(chineseChars), file)) {
1 c7 \3 f) }. N! ] - for (int i = 0; chineseChars[i] != '\0'; i++) {
! l0 K4 y, W5 i# H) h - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {2 i- L) L* I0 `0 z& P6 j) @8 o
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);$ ~, p, ^3 K! p
- currentListIndex++;" e5 x$ s1 D2 C" g
- }
- W# n9 {; U ~; z- Q A - }- \2 g& K3 h( g/ N/ N
- }
* ` P9 q1 I: b0 K8 T - fclose(file);8 U8 h2 g% V Q1 [, Q- r7 @
V8 @& N. A7 t" c5 @) J- SelectObject(hdc, oldFont); // 恢复原来的字体$ ]8 p8 Y: `& e
- $ u8 N$ }1 `; _8 j i
- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图6 L4 l- h% T" I
- glBindTexture(GL_TEXTURE_2D, fontTexture);7 f( L$ C/ L, t! f1 H5 ]) t) Z
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3 H5 A2 l* k6 S! M0 W& G - }
8 G( [. s3 X/ ^, M4 K
, @9 B; |* J/ \- R- j$ l- void renderString(const char* text, float x, float y) {+ o- ?' n) k' M
- glBindTexture(GL_TEXTURE_2D, fontTexture);
/ a0 \; p! v( b) m - ' S! H# M7 k5 I9 a
- glEnable(GL_BLEND);
2 C1 D. R i, p7 i7 z - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);( A0 O, F+ \* U& j; {
. B9 C' x! D+ Z8 e7 N5 e1 b- glRasterPos2f(x, y);
6 w( m' ]/ t( i; |7 B2 W - & b2 U7 v9 }4 ]0 k' t$ Q
- glListBase(fontListBase);4 Z3 e8 X |2 Q3 O' m6 O
- % ^' E0 v" f6 o1 b9 o
- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本, Q; V7 U% W4 K7 E& \) }4 L
1 |. F1 n) S% b! X- glDisable(GL_BLEND);
% j' P1 [5 m% D* D5 B - }
8 ^, h$ a. R2 Z9 k# | - & @6 ~5 m( d/ Y! i# m2 m& s
- int main() {5 v1 o/ d3 f9 S& F
- if (!glfwInit()) {
) f# D+ s1 j% i/ |6 h - fprintf(stderr, "Failed to initialize GLFW\n");! C8 m! a8 e' m' N* [" p
- return -1;
0 \8 a1 K; }1 p. v - }
+ t. a3 j/ V' F, n* R3 g. f% [. s# ^
# ^. v( ?, t5 u) P- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
6 U. J* {2 a! r7 k9 R5 H - if (!window) {
0 ^( c5 P9 z- n+ r: h8 P - fprintf(stderr, "Failed to create GLFW window\n");
o6 w- H8 Z# k. O9 z - glfwTerminate();
& M0 C- g' q+ t' W4 M- g4 x - return -1;5 |3 }, z' w8 ^" ?1 c% S$ ~ C, b
- }
* d5 T2 c2 T+ c
; U; N: o; J. R3 U* ?- glfwMakeContextCurrent(window);
4 W" r# Y, ~& B; V$ d4 }0 _0 D) {; C - glewInit();$ a; c; l4 w' j
& g) l: ]4 b% I8 M5 [& V- initialize("chinese.txt"); // 传入文件名1 O( u2 B( \, \
- 5 Z- p' d! l' ~; Z# ]9 F" f/ t
- while (!glfwWindowShouldClose(window)) {
- n+ X9 {" [, u9 }- R6 h3 v - glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
! n2 i( t+ X- _5 T - glClear(GL_COLOR_BUFFER_BIT);0 L- O/ c9 D2 |: _9 Y
0 B1 u3 l+ `* s6 C( G6 L6 M- glColor3f(1.0f, 1.0f, 1.0f);( {+ _# h5 P( q+ A v( O
- renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本6 _6 Y( [, v# Z A
- 0 n4 Z+ _* Q* Q4 B6 r# C
- glfwSwapBuffers(window);
+ t* N4 \1 c/ P3 p% K+ r - glfwPollEvents();
; a4 e& K1 J0 B - }
) K: A# _2 _4 R; ]; a% l( m - 2 O+ h/ h, n" v- x: Y7 ~/ ]
- glDeleteLists(fontListBase, 128); // 删除显示列表
) @0 L% F& O) o2 E# ?
; R+ H* {; r" y) d7 p- glDeleteTextures(1, &fontTexture); // 删除纹理" u; k1 P! u# ]5 B0 k4 z! r
- ) r2 I& E* d2 n+ P% F
- DeleteObject(font); // 删除字体对象
( V' ]2 t& r+ U/ U: w+ z
8 O+ w- x4 T- O" U6 v3 a1 ?- glfwTerminate();6 g6 A# ~3 ]6 X" l
" {0 O5 y# l! B* n- return 0;
! i' R1 ]+ {! V, G: f, H( R - }
/ E; M: @0 D5 K9 x3 `& ]
复制代码
4 A. a% D. d2 B
* T1 J1 n( d! Q7 [- b+ K- G- M8 C6 x% a
|