本帖最后由 shane007 于 2023-9-6 16:01 编辑
' @ V7 h: \' G: i2 G! Q* [7 B* I" q% Z4 i
生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。
0 i. V/ o+ m- ] D& e7 w, w6 [
3 R/ r$ N+ O) `: Z3 L2 q- R% Pchinese.txt保存游戏中所有不重复的汉字。7 a4 _6 I) J; y. o+ }, U# X
hook dll在初始化阶段,执行initialize部分代码,初始化字库。
0 ^1 ~8 M/ o: P8 v, s& k- b显示部分依旧可以用glCalllists方式实现。% G/ z9 ? ]3 B
, d' S& L7 u5 `9 `- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码 , c" e( b% E6 e! U* Z9 U6 z
4 Y; G; C& b" G2 k
" U" Z1 ^2 o q' a' n' K$ F- #include <stdio.h>
: z5 e$ H! ^9 K1 k ~+ ?9 \ - #include <stdlib.h>4 @9 m$ a" A: z7 v
- #include <GL/glew.h>
! p% @( ~3 y x - #include <GLFW/glfw3.h>2 ?! O! J% j5 V& P
- #include <windows.h>- S. a( Q$ e3 G
" E9 O8 j; n* K- j% G- GLuint fontListBase;
9 S2 p8 b0 ?+ o - HFONT font;( ^# L6 [) u0 r. p: }* R: S. W) H# K# `7 i
- GLuint fontTexture;$ p$ A2 p; ?* Y' W2 j/ p
- 8 w9 ~8 x: k+ N7 G% d% `3 K) d" ?- S
- void initialize(const char* filename) {8 h; X- [, W7 s; Z% ?
- FILE* file = fopen(filename, "r");% t! G8 w+ U6 K5 X! F9 ~. [
- if (!file) {
& x: u! W8 U7 M) ]$ E! J5 ~ - fprintf(stderr, "Failed to open file: %s\n", filename);6 h1 l8 Y, g! X* Y& O3 _$ T
- exit(EXIT_FAILURE);1 d- ]/ y/ b0 x( `+ E. S3 v
- }4 N" \. }% s' p
/ a- z; o5 ]! f7 V M, G- char chineseChars[128]; // 用于存储中文字符, @$ j. L2 x" p6 G. X7 ^
- int chineseCharCount = 0;6 e y9 K0 a6 m7 i$ Q4 b
0 j8 Q% s$ q/ ^& B0 P8 ~: s6 m5 Z- // 读取中文字符并存储到数组中
! ^6 v3 r% R7 o+ Q - while (fgets(chineseChars, sizeof(chineseChars), file)) {* B: \! U1 F; _3 N! h- D
- for (int i = 0; chineseChars[i] != '\0'; i++) {# j1 D, t' s1 R1 L ]
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
. p5 ]( @% g+ a - chineseCharCount++;; D6 c2 c5 j$ a2 b5 A
- }# h" N1 J# d5 p* R! H
- }( K+ s' ^& O" x$ s
- }
& x! W4 j8 y" t" ]
' c" ]* Q+ v, |- fclose(file);
. L9 b( Z8 u9 e; r( p, } - " a: k! c9 d$ b: z, J( Z
- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表4 H9 x: n2 g3 D; \ d$ |
7 R4 I! r' K3 x$ v7 Y- font = CreateFontA(" f+ O2 S$ p* x/ f
- 48, // 字体高度7 A. U0 t) n( R$ f0 ^3 c
- 0, // 字体宽度* g% a7 p9 t: x$ N6 o! u) L/ \) u
- 0, // 倾斜角度
9 j; l! X E+ q - 0, // 倾斜方向: s4 ~2 u- R1 ~7 j2 A4 ^! y' i
- FW_NORMAL, // 字体粗细
; ]% t, G6 @% j" F# ~, u - FALSE, // 是否为斜体- \0 B" ^+ I+ S7 i' P ?$ s- }
- FALSE, // 是否有下划线
; S% R$ J% R& x) z1 M1 K9 m3 m0 g - FALSE, // 是否有删除线
( \, z% w$ V9 v4 t# L0 ?8 n - ANSI_CHARSET, // 字符集2 s* p2 E1 H# D9 N8 q
- OUT_TT_PRECIS, // 输出精度5 t3 ~% @0 h D7 N+ P+ g
- CLIP_DEFAULT_PRECIS, // 剪切精度
+ l" r" d( \6 i - ANTIALIASED_QUALITY, // 抗锯齿质量! _5 k9 `+ a& g+ X- m5 q y# a9 V
- FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch1 b! O$ \5 x ]+ ?) p- u; w# m
- "Arial" // 字体名称
3 `% D0 Y6 q0 J' Z. R, a/ d" V; j. J - );0 s m t) y+ Q s" z3 E+ C" S1 Z
/ G' K- v6 r0 ^' I( L- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄
7 w/ ?+ x/ ]0 r+ z9 U0 |6 _6 U - HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体
6 ?8 h0 v2 T$ v r6 t5 h9 Z4 K - ! Z$ W7 U% A7 C$ ]3 s6 F& y0 p
- int currentListIndex = fontListBase;( ~# P# X4 E% t7 v+ T
0 ]+ x; D% t! e- // 逐个读取中文字符并创建字形位图存储在显示列表中: i+ r5 T9 L# b. W: ~
- file = fopen(filename, "r");
) z$ s5 J; V' ^+ g8 N4 H - while (fgets(chineseChars, sizeof(chineseChars), file)) {. Z8 L5 q$ J+ s# L: {5 P; R
- for (int i = 0; chineseChars[i] != '\0'; i++) {0 p% L3 ~8 I8 t
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {3 K; y, ~" L' l1 |8 j/ d
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);
% o9 i, ?, b2 u. T' Y - currentListIndex++;; q4 b- u( {6 r0 e% a
- }
3 z+ f, T# q! J* y' K3 a, b - } S3 @& j0 r. `8 i8 E
- }
8 M. O3 `4 m' D) C) O9 K6 G' L - fclose(file);
8 H$ T+ G* H8 i# o' \. S# ~' A - 1 M4 ^+ e4 T0 S: I4 k: Y1 |1 @
- SelectObject(hdc, oldFont); // 恢复原来的字体
. B9 M/ B% L7 d: u8 V+ `7 @# U2 J
$ S8 B ]$ F" d) M+ R8 s7 x. `$ h/ v- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图
$ s7 r5 E- Q0 h! Y I/ }1 {8 K. s' i - glBindTexture(GL_TEXTURE_2D, fontTexture);
d4 X) }& Z1 V! T9 I( | - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);6 E4 A: g. [8 n* W" \3 _8 j5 D% L
- }' b* l+ K7 q, }6 _; ~$ b/ g
- - d, y* h$ S/ {5 x3 F# F
- void renderString(const char* text, float x, float y) {
. B: O* C! ~0 X6 H! K - glBindTexture(GL_TEXTURE_2D, fontTexture);3 H/ |2 x* [& ?1 H% d5 D" Z
- $ W# I( D7 k: S L) }
- glEnable(GL_BLEND);4 n$ k) N K: Z
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);0 ^! t! y+ A/ c
- h( `) U8 Y: o$ P- glRasterPos2f(x, y);
6 I; \4 o. J% b$ g( U
* X! L3 _0 w5 P! k8 a" Y- glListBase(fontListBase);
8 K3 x: m, d. Q) O - 6 J' ~- D4 Y, l) J# F: h
- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本
+ J( ]. c. B5 ?2 U0 X2 g4 q$ l
C0 W- c% B1 h- h- glDisable(GL_BLEND);
" y4 @7 k1 I6 d9 f1 _ - }
' Y6 K6 B2 H) {: y) Y - ; T5 {7 F' m8 b
- int main() {
# [, e1 E J1 E/ Q8 n - if (!glfwInit()) {
! w2 V, M! t8 x5 N. J6 u - fprintf(stderr, "Failed to initialize GLFW\n");; j4 p5 @/ \% U: ]( c
- return -1;( V0 _1 m. s) Z, d8 s
- }' F" @$ a5 M) P7 B2 z
7 {% o4 k0 R+ @6 j& F; P- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);) T: n" ^& S2 q
- if (!window) {
4 l: D; r! x; v% d k: J( M - fprintf(stderr, "Failed to create GLFW window\n");. F$ t8 c( C: r* X3 _1 q
- glfwTerminate();9 l* ~+ m+ ]# k1 `; y
- return -1;" T* D, {( J% e% h& P: [. l
- }
a Y: H) ^/ S - ; ]1 Y2 v! _) J9 W: y- c q
- glfwMakeContextCurrent(window);
: U& V& Y& _# R/ v# i* l% Q - glewInit();' F9 e; E" U% e& n ^3 O! P+ A) v
: d- u0 R. ?. Z9 H p. a1 \' T- initialize("chinese.txt"); // 传入文件名+ G* C h- R/ Y c% y
4 i" w" \* u K: ^2 L- while (!glfwWindowShouldClose(window)) {) W: M- V( |& C/ `6 p$ ^; W5 E
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
% C; a$ d0 F+ i9 V; o% @5 J2 I - glClear(GL_COLOR_BUFFER_BIT);
0 |# B- q3 y5 X1 j$ i" u
. @( f3 D% E- F6 z! C7 |- glColor3f(1.0f, 1.0f, 1.0f);# ?( q2 L& e) {8 ?/ X- ^
- renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本. h& m1 p' Y4 f' n3 k
6 I' V4 K4 r. M6 t0 u3 O3 G0 [ G- glfwSwapBuffers(window);# s, v' d. P4 P- ~$ Y. G7 m! L, D; P
- glfwPollEvents();
6 [# A( n% \& e, V - }% z, s2 g2 L& }# e% @
& _* p( p1 N* O. i6 E; w, [- glDeleteLists(fontListBase, 128); // 删除显示列表
- s) p+ ]0 ]4 n9 O1 B; W - 4 m7 `7 x: @! j9 c% G
- glDeleteTextures(1, &fontTexture); // 删除纹理
a4 |" N h: U1 U
0 ?4 V! t" N5 ~. \' i T- DeleteObject(font); // 删除字体对象
1 z& [/ [5 a- R& {1 p3 s: T - 7 G. K* @5 M/ r2 k, C% V( _$ O9 r
- glfwTerminate();
" E q% z1 o+ z4 v - S6 g3 \$ \0 ?, U q, A
- return 0;
% q+ W# A2 e& C3 |2 M - }1 _6 x8 Y/ g- n/ G# K
复制代码
; c6 t$ B& W* I) D! [ l( `; u6 [; e W
, X" @' t" g( _! k |