本帖最后由 shane007 于 2023-9-6 16:01 编辑
6 d, d4 T9 f! Z/ a3 v* v( Q
% T1 m( y( O1 O# o生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。5 L/ F/ q ^% y1 M
8 m) \2 U3 ?: y3 {7 H3 M1 Y9 g' j0 `
chinese.txt保存游戏中所有不重复的汉字。
+ `/ M% U) j; {/ Chook dll在初始化阶段,执行initialize部分代码,初始化字库。$ H6 V# s- N0 V3 Q/ ^1 v
显示部分依旧可以用glCalllists方式实现。
E& W8 j4 {2 u' I7 T: D5 @7 A" D" [. J0 z K0 Y( b0 L
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码
% V0 v* ?$ N, v7 k& H1 r6 ]
) g& h+ m# W" W, ?$ O% l b4 p) n+ `/ M
- #include <stdio.h>& C3 |4 B2 ^- G% |0 n
- #include <stdlib.h>. @+ J. p; E5 \: L8 ~* n
- #include <GL/glew.h>
$ V: @0 X% P( s, i6 W7 ?3 | - #include <GLFW/glfw3.h>
& D% T( z3 r, `- u6 j - #include <windows.h>/ i% w. @( S: _& T; E
- ?5 T: l1 ]3 u$ R- GLuint fontListBase;
% P% l* a9 y7 V( A2 o+ W& W+ `/ ]0 R - HFONT font;: X$ S' I' J; x: Y0 `* y, L* t
- GLuint fontTexture;
9 @" g: v8 i+ D! X - 2 J( g2 n, V- L9 _4 F
- void initialize(const char* filename) {
" t6 n; \) b& F, I( [' K3 { - FILE* file = fopen(filename, "r");
7 M0 Q8 F" z. A" v% f$ H4 p2 t5 o - if (!file) {
. }1 s7 Q4 u8 v - fprintf(stderr, "Failed to open file: %s\n", filename);
5 H% x& q7 z4 W8 q - exit(EXIT_FAILURE);6 h& I) }7 g; {9 A
- }
' m' g j# ]0 _/ [ - 1 T6 W) ?. i h( m6 Y
- char chineseChars[128]; // 用于存储中文字符
2 [3 ?- h7 }( \; v0 t: o/ u - int chineseCharCount = 0;
9 V) R; V6 U/ N% e; f; C
6 Q$ V( `5 I2 f/ C+ B& U- // 读取中文字符并存储到数组中
; L& `6 B! i# j5 g, | - while (fgets(chineseChars, sizeof(chineseChars), file)) {# w: [( D1 g6 {7 @! w! C0 l- l
- for (int i = 0; chineseChars[i] != '\0'; i++) {$ w/ P% |# S5 p# V. m+ E
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
4 z! A* S: Z6 o9 m2 m7 I7 a - chineseCharCount++;" T0 _; R8 g9 J# [+ e
- }
* F2 u: u& Z k' E- O1 @4 A, |" g - }
R% u/ G! Y; h9 G+ S) I+ M$ P - }/ J2 m! ^+ e, V) `( f! ^5 p: J
' n7 z; |, Z" L2 d- fclose(file);' ^# f7 s1 @' U! V+ r# |
- : L7 I9 F1 _- Q) i9 N
- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
[' L, ?5 _9 Q - 8 c. N* i: @; o& H6 o4 {
- font = CreateFontA(
" x+ G+ k( J0 v7 R; o - 48, // 字体高度
! q7 L1 e" H4 }" S V - 0, // 字体宽度
2 V/ S% k, ?& i `/ D - 0, // 倾斜角度' I* m9 ^$ w6 j
- 0, // 倾斜方向
$ z% a; H+ q- Z+ S8 w9 A% K: ? - FW_NORMAL, // 字体粗细2 y# [0 z' N1 k' ]2 w. x' I. |
- FALSE, // 是否为斜体
* l4 ]* u p8 Y2 Q& A. F - FALSE, // 是否有下划线
, e+ K* N/ X4 x; O' ?$ S0 c - FALSE, // 是否有删除线
2 C8 W- Z6 S9 L! ^+ t2 x. @7 I - ANSI_CHARSET, // 字符集
5 Z3 W h2 ~4 P9 m' w - OUT_TT_PRECIS, // 输出精度
6 U9 E8 m6 i* o/ Z) I5 a" Z; S2 X* T - CLIP_DEFAULT_PRECIS, // 剪切精度
( E4 v1 U! o2 ]. F6 S9 b7 k - ANTIALIASED_QUALITY, // 抗锯齿质量
' J4 b8 j; B4 A9 c' K - FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch
! @7 Q0 t3 E: T! i8 q" v! ^7 p - "Arial" // 字体名称) ]9 R' W0 J2 ]( g
- );
, }. y" O/ ^& o - : f* W0 Z2 x1 U; U& `( k
- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄! {- V' W3 [5 p) U+ e
- HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体' F9 Y3 n4 {% \6 m( y7 W( Z( e0 h
- 4 {. a R+ p1 V3 C, T. g9 Z1 |
- int currentListIndex = fontListBase;
; j0 v0 {1 c4 F+ f% c9 r
! Y* B' z- z U. R v' x- W3 B- ]; F- // 逐个读取中文字符并创建字形位图存储在显示列表中: m# l$ |' W; Q* }
- file = fopen(filename, "r");
$ i6 ]0 v' E* X: M/ S* { - while (fgets(chineseChars, sizeof(chineseChars), file)) {5 M7 C9 d$ }+ o+ X
- for (int i = 0; chineseChars[i] != '\0'; i++) {
. t0 F( r: a0 c0 B8 d2 v% y - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
0 C( V; y9 T& m9 y: w6 G% z - wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);4 d* h% Z1 b9 W: F( g+ G: p9 T
- currentListIndex++;7 R5 n7 C7 c1 A( }& b, \3 v5 b8 d
- }: P' ?/ N& r |+ X9 ?1 i
- }
3 l1 B: P O2 q - }+ U! _6 l7 o8 N
- fclose(file);
2 T B% e9 }% p6 ]
" V5 D, b0 t! Z! F0 ~/ X0 u- SelectObject(hdc, oldFont); // 恢复原来的字体* l: w# G) Y, P1 c" z j0 O
4 ^# b% Z. p; e; p* ~; G- z- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图
" ? J) m1 {7 C, F; _1 E - glBindTexture(GL_TEXTURE_2D, fontTexture);- K4 q3 _$ Q& f0 N; [
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
) A8 H+ R; ^( L" p% I - }; T' v1 c) b' y6 j, n4 B
1 D/ t: b0 Q% P) G9 W' I( K- void renderString(const char* text, float x, float y) {- @3 |( |4 O' l; [/ N) m
- glBindTexture(GL_TEXTURE_2D, fontTexture);' D2 |( z% ]& P$ a
- ?" E, y1 r* ]( @) q; M
- glEnable(GL_BLEND);
# K' m# U3 M! g - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
* e3 g; G& [* x9 b* D - 6 [4 U! }! }6 M. D* |; d
- glRasterPos2f(x, y);
6 i. ^ D4 w9 @3 _: ~
8 `, ~- K+ M% w9 \% c6 k5 h" y- glListBase(fontListBase);% R: R; W k8 R0 }5 A2 D: t! H7 W
& Z7 @) w# B$ |, Z+ t) N! T- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本
% W' L: E) Z( n$ ], G - - q2 a; t& z/ Q/ \/ D7 l) \
- glDisable(GL_BLEND);
- G/ J% Y, R% k1 g1 R/ t' J9 W - }
& E( X6 q/ b9 E+ ] M; a - 9 H0 I! ~9 o$ u1 @- T
- int main() {& Z6 I* H0 \( L- N) N9 z3 F0 V
- if (!glfwInit()) {
6 X- k) O; y2 ]: w" j - fprintf(stderr, "Failed to initialize GLFW\n");
4 x( b/ S- O7 Z1 o8 E' O) Q - return -1;
# L7 i. a1 D& w1 j( Y( | - }
3 Y+ S$ f1 @7 n9 y' d - + A" @" `- B! {( {
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);/ E" t6 c1 O! Y
- if (!window) {8 b4 k: V% h+ Z- n
- fprintf(stderr, "Failed to create GLFW window\n");
( t4 L0 v0 d/ t$ i/ d M7 J P8 n - glfwTerminate();
9 z/ j' W( Y/ a$ m - return -1;
1 t9 u% [* \5 o2 O - }) r- D% I5 G7 S! ?% m7 C
- ( f$ B4 \; F* w5 U
- glfwMakeContextCurrent(window);1 w+ H/ U% L( k. ^0 C9 o3 ^( e* n
- glewInit();# @ m8 F' ~8 E# J! y
* V# ^/ |( T8 B5 d! C$ |) T- initialize("chinese.txt"); // 传入文件名
+ w3 y8 T/ V. K0 Y - / A5 N! |' M$ P# C3 j
- while (!glfwWindowShouldClose(window)) {/ s3 b. C1 J6 P! ^' ]: w9 }
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);( S L8 x- m& S0 j, U/ |
- glClear(GL_COLOR_BUFFER_BIT);
* g2 k8 Z k) L; Q - 7 {+ A3 F; {5 J( a* Y9 U) D
- glColor3f(1.0f, 1.0f, 1.0f);! O+ Z/ P" K; L0 _0 a/ h- j; V
- renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本' b& j7 V2 e$ {
' a2 |4 }" x0 q( s8 F% H2 Y- glfwSwapBuffers(window);: \- |; ]2 A# ~" W4 @, G% e
- glfwPollEvents();' V* E! g1 Y5 d. E+ S
- }
; H$ P# i& _9 i* q1 P8 p7 U
0 @% B( }+ `+ t* [- q1 t9 I/ V- glDeleteLists(fontListBase, 128); // 删除显示列表/ p) O, |8 G7 U: S
- ) ? `2 v2 F% E
- glDeleteTextures(1, &fontTexture); // 删除纹理
8 t) x* E$ }7 o/ f
9 \- H& ~3 h* G7 u- D- DeleteObject(font); // 删除字体对象
8 }; R. E; q! N/ ^* D
' j+ J. I% f6 a& j- glfwTerminate();
5 K# A+ I; J; v+ D. A0 |
% ]" V9 v, R" |& H6 R2 J: u- return 0;1 p3 N6 i5 \$ a' q; }
- }
1 ~$ e9 l! b; j' q* _
复制代码
% F4 B: }) G: T" a1 B% Q/ h, h( @' i% L- X: r2 T1 `
7 r7 K" b/ {& j3 M) w6 [9 E% x8 E |