本帖最后由 shane007 于 2023-9-6 16:01 编辑 / V& y9 I: ?3 {! E
3 D3 u/ {0 ^ N q7 {( n生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。
" K$ q4 S* V$ ]% z0 s! V! m W( e4 D% d' S' q
chinese.txt保存游戏中所有不重复的汉字。
9 ~, `( c+ C @; e, mhook dll在初始化阶段,执行initialize部分代码,初始化字库。' H) s T O4 B. e
显示部分依旧可以用glCalllists方式实现。$ a* u& L; g9 i: B" g( r) t
* V2 Z: w/ O8 Z- n5 J% {
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码 * w! s& q$ v' U, N. m! k; e% w
9 ?" i% r* ?7 |' R: s" M6 ^
3 u# X& C, ?$ ]% q/ Z- #include <stdio.h>
4 k1 P a8 H1 T! `6 m - #include <stdlib.h>
7 b E0 x. m% \# W% Z1 Y: U. u- \ - #include <GL/glew.h>
9 S+ n( N: p: _4 S, Y3 i5 h# ^/ S" u$ T - #include <GLFW/glfw3.h>
* k/ [6 i t1 A8 k - #include <windows.h>2 ?1 q$ h, v" N0 x! c: J
" x8 _5 q, z5 D, l3 ?9 g- GLuint fontListBase; O4 M) J6 m; l6 N
- HFONT font;
% C: F6 x5 N/ d - GLuint fontTexture;2 z8 ]3 d C( U! u
- ( F4 z( H! Z4 ]" S+ Y
- void initialize(const char* filename) {' i8 J4 i; E! t1 C
- FILE* file = fopen(filename, "r");
/ ~: |( A/ k. I4 b7 G' w - if (!file) {
( r" w7 o) \! L/ u* u$ L7 ]$ c - fprintf(stderr, "Failed to open file: %s\n", filename);
2 H3 u# Q; x1 |, Q! D' e n( t$ c - exit(EXIT_FAILURE);
6 Q) [2 I7 F b' w" D% a1 H - }3 J5 J4 q+ `; m2 H* R$ C
) Q$ H$ D/ y$ m+ a2 B9 p2 O- char chineseChars[128]; // 用于存储中文字符
: W1 z/ B- `6 v# f7 t - int chineseCharCount = 0;) ^3 j" ~, Y7 U" c1 q. H- r
- ( W: o1 } Y u9 g( p# W @
- // 读取中文字符并存储到数组中& p) L* u2 L1 u8 e
- while (fgets(chineseChars, sizeof(chineseChars), file)) {4 T/ u$ `% ?- x& M$ A1 S; T
- for (int i = 0; chineseChars[i] != '\0'; i++) {
* c e# C. d" X- q5 v( \ - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {$ c# v+ I9 ~: I; A0 s" P# I) y' Q
- chineseCharCount++;- v- @8 O" f+ \/ t7 m, x
- }. V* p( g5 Z- ?# y/ H
- }4 \/ b0 i5 \0 y0 G. q
- }
1 e) i+ c* Z& }2 ?6 _" c
- i7 g6 d. G- R* K- fclose(file);) C. x# I+ L( B5 D2 I
+ ?+ K( q% h2 |+ a o6 w- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
2 r& G5 g* a6 A; Y/ W: m2 o - 8 ^2 e: _$ U& a, X3 g f: p
- font = CreateFontA(; F @3 O0 W& l* J% o
- 48, // 字体高度
6 j# r) e$ k/ Q. C; a5 b - 0, // 字体宽度9 M2 s8 K' I' Z* g* \( T) A
- 0, // 倾斜角度
( Q; \: A7 ?& ^1 ~ - 0, // 倾斜方向
2 F, Q- G% G3 x; _8 F- S& n) p# S - FW_NORMAL, // 字体粗细
4 a$ S2 ^; u4 s - FALSE, // 是否为斜体
2 |# c9 t( ?$ @0 U% `8 ~/ b8 k4 h - FALSE, // 是否有下划线
+ n$ {0 k4 _% l7 v U: w% F$ f5 Z - FALSE, // 是否有删除线
1 C0 E. k# f; m - ANSI_CHARSET, // 字符集$ w, [0 G5 O7 E: n; Y' n9 C/ C, l
- OUT_TT_PRECIS, // 输出精度# f {( O* I6 T4 \7 _
- CLIP_DEFAULT_PRECIS, // 剪切精度
: ]% V2 r: a1 l0 m# V0 ~ - ANTIALIASED_QUALITY, // 抗锯齿质量
/ y: ~8 n$ S" b6 e1 z6 `- D - FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch
( H8 X! c2 L0 l3 V: e) W, S6 W - "Arial" // 字体名称
' p( x; l* E* x - );
0 w; V, T: D' b2 C5 \! \, g% U
% F( G- U- s: u) |# k" T& D- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄
1 A6 D3 _, H! y - HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体0 z3 E, W+ {, V) o# Q
- ( L9 L$ {6 c3 n& w
- int currentListIndex = fontListBase;# Y4 }7 T) ?" }5 C* e! @3 \3 L4 R
/ d( Z: ]; j7 Y, T0 `- // 逐个读取中文字符并创建字形位图存储在显示列表中
. I S6 y/ X# R4 G1 O - file = fopen(filename, "r");
9 t' \ b0 d! H. ` - while (fgets(chineseChars, sizeof(chineseChars), file)) {
3 J, @) x/ a0 o3 j4 P1 K, g# I - for (int i = 0; chineseChars[i] != '\0'; i++) {0 S. E, s# @8 v n" c; C$ v
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {: T' g# O6 _3 Z( X% q
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);' M) d" W. G; [! `
- currentListIndex++;3 X5 l) s! N' N; j2 U
- }
8 O+ N D3 y* e& N0 o; {3 q) y - }
3 _" `5 M5 s" |, x6 ~' t+ u0 e) X - }# I3 j" W+ [0 P, e% ?' O
- fclose(file);" W& S9 ~6 [' ]* J- `1 t6 r
- 7 `( |& q) ]& O, Z
- SelectObject(hdc, oldFont); // 恢复原来的字体. d% H$ X; l7 d7 P$ D
- , j2 {$ _1 O- Y: b4 L4 C4 ^/ K' Z
- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图1 G, d( S- k/ D- Y9 w
- glBindTexture(GL_TEXTURE_2D, fontTexture);
3 y4 x ~% @4 m3 v3 U# m" s; Q( u - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
, k3 N8 @( Z0 _% j& X/ E# z+ L2 Q - }5 A2 V* u3 H* n* i) C( Y
- & n, m8 j7 g4 @" g8 S+ S
- void renderString(const char* text, float x, float y) {. s; y6 ]* J5 J& C) [$ G
- glBindTexture(GL_TEXTURE_2D, fontTexture);
6 ^% x- k8 X, C7 d+ T
! d/ x* @& `2 E, @ X- glEnable(GL_BLEND);
( X+ \7 m& `! Y& e - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);+ q" Y! l8 [" e" y( u- B+ X, i6 h
5 {. p6 |" W1 c2 w V* n- glRasterPos2f(x, y);* q! K m, o/ q/ G
- % l+ K2 E5 E2 m& M5 a! L
- glListBase(fontListBase);9 F/ N+ k: [1 j2 i7 I& _+ p2 a9 ^; J
( e* b0 Q+ Z. P5 B: U0 O- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本
^7 x4 G/ W; T
/ s) H& b& b1 w" \4 O e; j% ?3 p- glDisable(GL_BLEND);
# y8 s% ?1 {# |& Z, A - }
4 r( b ?2 J; d
9 N( ]& ?5 t$ `- int main() {) o: }3 k! F1 d
- if (!glfwInit()) {
]/ B4 u/ e a+ L/ N' P - fprintf(stderr, "Failed to initialize GLFW\n");$ Q+ f# t1 j- K7 U+ L/ T, {' S
- return -1;1 s, s5 U0 K6 y* l+ H: A
- }% V4 ]( u" P$ D
- ! i2 m o3 _& @* H$ [! r) O
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
# @( m6 k3 K; v, e/ c - if (!window) {. b5 r$ m9 G' C( ]& E
- fprintf(stderr, "Failed to create GLFW window\n");
e3 d0 j" D0 i1 W - glfwTerminate();+ U4 S* }! o( o8 |3 j
- return -1;: \9 a0 m8 k P8 ~/ K
- }. Y C6 g1 J3 b9 ?' z
/ T/ W" i1 n) Y- glfwMakeContextCurrent(window);0 C3 x8 O9 n/ f- T# j3 p2 V. A( y
- glewInit();
0 ~9 g6 Y: r) P( s I& A - 5 T9 m3 L+ Q2 H+ x
- initialize("chinese.txt"); // 传入文件名
8 ^0 J( q% c( @7 D3 Y7 l" g" @
6 ]1 [: w1 a, e" D% L _( e- while (!glfwWindowShouldClose(window)) {
: V4 t; ]; I( o/ @! w - glClearColor(0.0f, 0.0f, 0.0f, 1.0f);4 S, ?8 F0 A( W$ V9 B
- glClear(GL_COLOR_BUFFER_BIT);
# u; r, U5 g) I- ? - , _: w$ g9 T. d6 h( q
- glColor3f(1.0f, 1.0f, 1.0f);) A3 b; g; s3 ~2 a4 G- o
- renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本5 }( L7 m/ K# p0 x8 K" b
- ( X/ [. z( n' E; G0 w! q
- glfwSwapBuffers(window); H6 Z7 M$ B( k' w4 f! V; C9 ?1 k
- glfwPollEvents();
# l# U5 q% F+ o+ C9 h6 \" r# Z - }
9 ?, X; L0 F: B) m
2 n/ |7 c& b" L, s1 m- glDeleteLists(fontListBase, 128); // 删除显示列表/ {+ O7 A/ J/ N9 H4 r
) K7 E b& `8 g! b- glDeleteTextures(1, &fontTexture); // 删除纹理% I7 N8 _" u, v
- ( b% T& V. |) {! g
- DeleteObject(font); // 删除字体对象
/ e ]: P+ M) f6 l. v, m
; i' q7 L' G7 f% k- glfwTerminate();' f! I& R: q9 w7 F+ M& H
- ! G$ r9 j0 k' L5 U# y+ ]
- return 0;
: k8 ~5 @# p; A) N/ X( f - }- N" {0 y8 y, {( ~3 F
复制代码 # U G" l1 f8 K/ c/ T4 X+ P
! u6 w4 m6 \( A/ N% {# J7 i
! f: |" v. T# ~2 s |