本帖最后由 shane007 于 2023-9-6 16:01 编辑 $ d1 d8 ~8 F0 H3 m1 ~
) U: ?5 B3 K, {8 w( g# a* ?生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。$ T: {- n5 E' v; e3 N" z$ S: f1 ~
" B# c+ p6 d1 [: Z7 lchinese.txt保存游戏中所有不重复的汉字。8 H" d% V. P9 S7 g
hook dll在初始化阶段,执行initialize部分代码,初始化字库。7 [8 Q+ S# }" n1 V1 R
显示部分依旧可以用glCalllists方式实现。
1 C! S8 [8 p) ^2 ?% g7 e
& f2 J5 I& h9 y. O2 d' i* Z- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码
$ V& p. j- E' [$ i Q# c; y! e1 o/ Y/ K( @8 W6 a3 P' F F( i: T
# ^& g) M3 _7 q) r% u+ V
- #include <stdio.h>! c2 f0 V6 t% {
- #include <stdlib.h>
- W5 H! s! [ ?. u# [; Z( { - #include <GL/glew.h>' r/ D9 O2 i2 L& k; z
- #include <GLFW/glfw3.h> q0 ]% b$ Y: O' Y7 r1 j5 ^
- #include <windows.h>
, A" }4 L! ?/ `- D6 I5 o$ `/ K
) @0 s1 q2 }2 Q- GLuint fontListBase;
: x9 ?+ F0 @8 Y0 x - HFONT font;: I+ h) k; r) u% D- m3 q6 r
- GLuint fontTexture;
4 N6 i7 M+ N* G7 i( K
6 _0 n3 e, T; V3 s5 X- void initialize(const char* filename) {* d. g( L/ X, a6 t4 l- l
- FILE* file = fopen(filename, "r");- W6 w8 o# G5 Q$ L$ t; I- d0 d, \4 m
- if (!file) {1 b' W, @1 x$ H0 u
- fprintf(stderr, "Failed to open file: %s\n", filename);
6 k y( c0 {; Q* m* b& f8 p/ G) y - exit(EXIT_FAILURE);3 v' G; x3 ^/ R4 _- h
- }
/ k. E. W( T+ ~8 M- U+ @
; M, f) Y/ }6 A i- char chineseChars[128]; // 用于存储中文字符' k$ u0 U' U$ g$ L; R
- int chineseCharCount = 0;: n P+ ~, K. r8 I* b, p. ~3 `
0 F7 y2 b& B( I- // 读取中文字符并存储到数组中
. G7 q, l+ s7 i' T& d3 ^& N - while (fgets(chineseChars, sizeof(chineseChars), file)) {
6 J: S" Q! A! n# I9 B: [# T - for (int i = 0; chineseChars[i] != '\0'; i++) {
* L* X% B& u: o' E3 X' h" j - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {5 l1 U) h4 n* r
- chineseCharCount++;5 S5 ?) C2 [# H% Y! [# X9 A
- }- w8 r& Y$ ]5 I5 M# {
- }
' P" c9 ^2 b: V6 g1 ~# e4 L1 |% Z - }3 N7 }7 r' @; H
- - o. L! z4 Q% f4 ^: [, E
- fclose(file);
; b4 b. \8 w$ h7 z3 e+ r
4 o% e7 a; t2 R0 v7 |- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
& X9 q6 Q/ `8 o$ g# X N! u
$ E% B! o- J7 [& d+ G: E- font = CreateFontA(9 F0 e9 \5 j9 J
- 48, // 字体高度
4 Y, |: z1 W7 M; S - 0, // 字体宽度
$ l6 W" c1 @- o - 0, // 倾斜角度
4 g9 @! v' l0 s - 0, // 倾斜方向
& Q: F ^. ]2 Q" a G - FW_NORMAL, // 字体粗细
6 f0 `1 T0 j9 t - FALSE, // 是否为斜体, b6 W0 {* G" B# c5 X$ D, L
- FALSE, // 是否有下划线
7 i% n1 [6 G8 X4 h" o0 E5 } - FALSE, // 是否有删除线
0 d! ]$ a3 `7 R. c - ANSI_CHARSET, // 字符集+ v$ U) u: W9 m( o
- OUT_TT_PRECIS, // 输出精度
- Q* j* Z1 w# o1 ~' e8 ] - CLIP_DEFAULT_PRECIS, // 剪切精度
5 _* U8 e4 z6 {; Q - ANTIALIASED_QUALITY, // 抗锯齿质量 R3 P+ e _9 m7 P" V5 A
- FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch. h) R" g. `' t3 e! E
- "Arial" // 字体名称
& p# H, N5 ?8 E5 Z, j - );3 {2 P; x9 N; D" |: A' R
0 r4 h: x. I) p" x. G- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄3 m- a7 ]- G! K$ e8 d; b" a- k) ^
- HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体7 l. f" J8 h8 [: b
- * c3 c, X) E: H6 @% m
- int currentListIndex = fontListBase;4 B* }. e+ l: P( c4 D
- / |6 L+ ]# L" K u" l
- // 逐个读取中文字符并创建字形位图存储在显示列表中
* g7 S8 K; t1 }! O# t* e7 l - file = fopen(filename, "r");
9 Y1 c& |( ~8 j& O2 K2 f& t" q- N - while (fgets(chineseChars, sizeof(chineseChars), file)) {5 |% O- P- ` X- }
- for (int i = 0; chineseChars[i] != '\0'; i++) {* C" l" r. e2 ^# f, |
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {/ p7 p8 P0 ]' e% O( q& R# { a
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);/ K. x" X" X/ ?* L* S. k3 B
- currentListIndex++;' u8 u$ N- V D$ |+ l* ~
- }! Q K) I9 a: w G2 V
- }
, L) \( _3 ~% h3 G' v - }
& u4 D' d+ V# | - fclose(file);1 |+ @: H( n$ ^9 T% |& R
% k) V% t" o/ @7 n- SelectObject(hdc, oldFont); // 恢复原来的字体5 Z4 V8 a% @8 D0 C4 G
- X0 W$ @0 O0 s1 Y- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图
/ v, F8 C8 C" H% m2 z! ]1 ^, ? - glBindTexture(GL_TEXTURE_2D, fontTexture);
0 b7 x/ ~8 F# z6 L" J2 o) N2 H - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
; e+ j& g" P& Z- \+ m - }
* j# H e6 l/ {4 _* I( n& \, e: T3 v - + N) q. O: u: h8 d4 T. ~: r
- void renderString(const char* text, float x, float y) {" [$ ^8 K7 z7 G8 d5 t, N( M
- glBindTexture(GL_TEXTURE_2D, fontTexture);+ N9 i# m! F) m1 d7 G
3 Q* K4 |8 ~9 {3 T2 B8 q- glEnable(GL_BLEND);
* M: O3 e$ r4 ?) y+ d) U! m7 T2 a - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);" O% ~4 u u! r. M! w: [) C
" \7 K4 o5 K- w- J# A- glRasterPos2f(x, y);
: t" [( @4 p6 ~- Q - a& j( m) j, s
- glListBase(fontListBase);
+ A. H, Y' d1 d1 r - + U, \5 C! Q/ M! W0 X2 f
- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本
8 q5 B1 |- y9 `7 B- v& ?5 s - ; ]3 _0 [) X& \4 l/ M7 d- G
- glDisable(GL_BLEND);8 r. W- u( r- V4 z# I# D+ n
- }
$ Q2 h3 |! D/ i$ R. K
s, @" @8 e8 h! h9 d' G5 C- int main() { j' g! S+ M3 W# w; g& Q
- if (!glfwInit()) {
8 w( E% g$ X! x4 i/ M4 j4 F6 z - fprintf(stderr, "Failed to initialize GLFW\n");' X# \* N' o0 W
- return -1;
5 |0 u0 k# P* I1 o - }
, {! k |9 {1 y% M" ? - , P! C" Z2 ~5 x0 l. Y
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
, i. H3 i" l: Q9 |* X) E6 U - if (!window) {, f: n: q) e7 s
- fprintf(stderr, "Failed to create GLFW window\n");4 f, m0 q8 y# Q* a# ]( A
- glfwTerminate();1 B* _: I; L1 r! ^5 [2 e
- return -1;0 k6 ?0 A$ E: Q B- |$ c
- }
6 u. ?1 J8 j, a5 A8 D - 2 ~! I/ B; A6 h+ t
- glfwMakeContextCurrent(window);! l; A _) N3 e) w1 s: p) f& K$ a2 ]+ i% d
- glewInit();% e' y- b! {# D0 {, ], \8 g6 i. Z
/ S0 D, p" F" ~: q+ H! f0 l( i2 w- initialize("chinese.txt"); // 传入文件名# u0 y$ V# U8 e* T/ R( k+ T
- 0 }+ T9 ?$ ~5 H) X4 x
- while (!glfwWindowShouldClose(window)) {
1 u+ o/ a7 w, e; P( N5 G7 g - glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
& E, W# t. T3 Y- D - glClear(GL_COLOR_BUFFER_BIT);
+ L. O0 d4 L& u& H( b - , g- [/ E& _2 U5 x
- glColor3f(1.0f, 1.0f, 1.0f);( `+ @$ u' }- x8 g+ l8 }7 h& ]6 @
- renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本0 `5 U3 ^1 B9 e
5 g x* J# G! y8 p* z) | p- glfwSwapBuffers(window);
- E U2 j; X: S! ]6 c" g - glfwPollEvents();3 W. {9 n, U8 Y* h- g
- }) Q# G- w. k' r8 z( U" [1 G: |
$ X1 F& {, G) ^. B+ s5 P+ t/ n8 z- glDeleteLists(fontListBase, 128); // 删除显示列表
. R; i* _8 i& @ - . E9 r C/ H6 Z8 I/ P5 w, {' s. r! H
- glDeleteTextures(1, &fontTexture); // 删除纹理
+ K2 I; l% n: O. P' ` - ' i% V0 G0 I1 o0 v
- DeleteObject(font); // 删除字体对象
# ]' B5 D) P2 b+ M
, U# u M0 F: g: _4 |- glfwTerminate();
) y9 W: k( `* i
+ l! t0 a6 s! `/ z& t- return 0;
& ^, @* O' ^/ I* w+ ~7 e& Y - }
( w9 c, h6 b8 V* l: q
复制代码 * r" j& m: O O- g _) j
. m- _ ?0 o1 i# n& r$ c& q! L
$ L# @( P# ^% o1 e( x+ {6 ]* e
|