本帖最后由 shane007 于 2023-9-6 16:01 编辑
9 U5 J5 O0 \- ?9 _( g8 e1 P1 } W) _' I8 l
生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。
5 ~% N4 K3 i0 \ g$ _
. h0 {" s2 K) X$ c, e) K! u( q& Dchinese.txt保存游戏中所有不重复的汉字。8 V3 F3 U2 F9 e, {, p ^
hook dll在初始化阶段,执行initialize部分代码,初始化字库。: {- ^2 f. Z, v, w; X2 N: X
显示部分依旧可以用glCalllists方式实现。
' w0 W. b4 T. k. p. u3 ]) T1 \3 C( I8 T( b! q+ b
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码
; e+ B, |6 ]8 R& u
6 _" ?/ s0 S4 f0 ~+ g/ j) m& a
- #include <stdio.h>. A: N7 j5 u9 p- u
- #include <stdlib.h>: F o. G; L& Y
- #include <GL/glew.h># i+ K4 ~) C/ G, M5 n- m$ B
- #include <GLFW/glfw3.h>( }0 C# |* ^; ^0 n- Q! _; D0 L
- #include <windows.h>/ l/ A6 V9 e! C
6 o# R6 `. s9 |$ b- GLuint fontListBase;# Q5 B9 D9 | O9 L7 v" h
- HFONT font;! T/ }3 w( V& a5 ^, o/ _( Z; ~1 `) _4 ~
- GLuint fontTexture;$ |# x; J" g9 M' t5 K& R
- 4 D1 Q4 E# X) f& P3 @: F; V
- void initialize(const char* filename) {' f# D* G" k5 g- v# C" T# [6 W
- FILE* file = fopen(filename, "r");% u3 R' B) z* |' v: a" F4 y
- if (!file) {
5 M, N$ o7 x& [ - fprintf(stderr, "Failed to open file: %s\n", filename);& D5 a7 `: H# w" d- X
- exit(EXIT_FAILURE);
- E$ R4 m( P" M - }. {& ~9 n$ D6 `" N& Z o
1 g, a" n/ f; w r# ]+ o- char chineseChars[128]; // 用于存储中文字符1 s/ m! t" m) `: c3 d
- int chineseCharCount = 0;4 g2 s4 ^1 F" d V4 i3 H6 b
: l: z( u1 G# R+ q- // 读取中文字符并存储到数组中5 @5 Y; ]4 v) I
- while (fgets(chineseChars, sizeof(chineseChars), file)) {
( h: ~2 C2 `. p4 I& U - for (int i = 0; chineseChars[i] != '\0'; i++) { @: H) a- @2 D2 y$ j
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {( f$ y, e+ M, y; C1 P& o7 b/ R
- chineseCharCount++;
0 U/ |6 y4 O! o; t - }: y+ Y3 p* ^& ]" G k1 G B7 v
- }
/ j% i% t) H2 _0 s - }7 f U" h8 B- ?9 a) G" d+ l
- # `1 F. L( z& s6 P) Z; F/ q+ G _$ ^
- fclose(file);# J2 L! A0 V) I& M3 x6 H5 F; U$ _" P! Q
- % R$ W" x: t" y/ w' j
- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
& \% l; f/ w* m0 i/ o( T; f
0 M5 R+ L/ T( F T+ i- font = CreateFontA(7 P1 F0 L# F. T
- 48, // 字体高度
1 X0 ]2 i9 |* h3 h* S - 0, // 字体宽度
+ C5 {+ h7 \% ~* J- k4 p2 O* L, O+ n - 0, // 倾斜角度
7 s C! i3 A* u0 d$ F, J - 0, // 倾斜方向
$ `7 O: O! Q4 L' J# I3 s! ? - FW_NORMAL, // 字体粗细3 S& U2 ?% r5 ?5 c) @
- FALSE, // 是否为斜体 x7 N; g. P7 `. B" S
- FALSE, // 是否有下划线
2 H6 n8 W$ F$ Y/ Z - FALSE, // 是否有删除线
( H7 L: Z i G& b* x - ANSI_CHARSET, // 字符集) B+ X# m9 j$ `$ [2 L# z" W
- OUT_TT_PRECIS, // 输出精度
+ U! h4 V# b6 X2 D9 b3 Y7 h5 o - CLIP_DEFAULT_PRECIS, // 剪切精度; {1 T; {( _3 {% I% L" W7 T
- ANTIALIASED_QUALITY, // 抗锯齿质量
# J. c9 N( \' q8 p% y: G - FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch8 H( L6 {3 p7 A* D2 |
- "Arial" // 字体名称
! x' u7 i0 f, s8 B - );( J" p; T' I- u! R3 C' {3 y
' {( U- P. ?0 x O4 n- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄
b3 e9 }: r8 E8 k5 t2 j) _4 v - HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体7 p' H0 u4 ^( a% `5 R
/ e; t- R# S: C7 h9 J3 c/ x- int currentListIndex = fontListBase;( c, \, k" }! x2 B$ [
$ _, X- z4 i3 b$ V9 H3 l4 K; r% t- // 逐个读取中文字符并创建字形位图存储在显示列表中7 y5 b, \7 R9 {& Z) ^
- file = fopen(filename, "r");
6 F( M! Q) T( f+ S2 b - while (fgets(chineseChars, sizeof(chineseChars), file)) {5 o% w: T" C- q4 N8 z
- for (int i = 0; chineseChars[i] != '\0'; i++) {
- ?5 r- ^; E q" t% \6 ~8 B& h - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
4 F, W" p* Y% }2 o9 M* o - wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);
# a9 q/ _5 s. ? - currentListIndex++;. r. D' o" d, E* s; O/ ~& }
- }' t( z+ S0 H' [! u$ V2 z1 Z
- }
4 x& ~6 ~1 g0 `" g2 B: H- Q - } f" ~- ?4 h7 \1 ^3 U+ [% ]$ c9 r# ]
- fclose(file);( h! ]+ x- N' s+ i. I1 h
- " V2 T1 t& [: m/ k
- SelectObject(hdc, oldFont); // 恢复原来的字体
" H1 B# [$ o8 j& Y- u - % Q% k! d) A4 F" V+ X3 c3 S
- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图
' ~$ D2 K* |: S( {2 O - glBindTexture(GL_TEXTURE_2D, fontTexture);
0 J: M7 I, \; T - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1 J0 R+ [3 t& K3 u/ T; o - }& T$ m" \" Z3 s( u* Q. Z. V# P
- : D# N! S! w0 C- S w3 M
- void renderString(const char* text, float x, float y) {
- d: L$ T$ l- x! S6 o - glBindTexture(GL_TEXTURE_2D, fontTexture);
& y) h: x2 f( B7 @: T) d - : ^$ P& R- o6 \ h6 A ?$ y. I
- glEnable(GL_BLEND);
1 o; K; z( m) P - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);, I0 U/ u) P5 C7 a
- 7 }% O" s$ U, \8 _6 O& i! D( L
- glRasterPos2f(x, y);
0 K% B; m v i# o
& M3 l" k; C* X9 V3 ?- glListBase(fontListBase);) K3 B# l& w- _& C! u
& b. i; D1 Y" U' L) a- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本
* d9 ^5 _) m' B1 z- z - / K* {" n% n9 E" C) o( q3 D0 d
- glDisable(GL_BLEND);
4 W+ |8 _! A7 @# S, h. g. m4 ~( z/ } - }
2 |8 Q5 ?6 S0 |8 j4 {3 {8 M
, l$ X3 H! {8 [6 c1 ^5 l, V- int main() {
/ a: `# s: X i3 x/ v - if (!glfwInit()) {$ F" l) o, Y& r3 F1 i3 c
- fprintf(stderr, "Failed to initialize GLFW\n");: ]6 c3 r* W9 r+ W$ Z
- return -1;3 P( j7 `3 g$ a/ [0 u' y. ]3 e* v4 |
- }
- V( E# S" U! g( W( h) H$ A - 0 g" v+ ~+ [9 U8 e d2 z) j3 L
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
9 N' D$ y5 ]5 j+ p0 i" E( M - if (!window) {5 t' ?" G; {. C" r; E( T `5 k
- fprintf(stderr, "Failed to create GLFW window\n");! k+ S$ ~9 v! @: z
- glfwTerminate();1 p ^) i2 ~& z. n/ v
- return -1;
* f1 x9 O# A3 g$ B4 A" v - }
" `% I, }" h( j; P4 p4 \ - 9 h9 A: u7 e! k) x
- glfwMakeContextCurrent(window);! K& S5 \ H4 N7 m1 y, w# d
- glewInit();
$ i5 a4 R. [4 x8 r" L- c8 M5 w
* H' u% \! A2 J! `5 f8 M. K8 ] f8 c- initialize("chinese.txt"); // 传入文件名 _: n5 P# r T, S- M( D
% T" L7 p D* ^1 |+ V. v- while (!glfwWindowShouldClose(window)) {
2 n- W# s1 I; K - glClearColor(0.0f, 0.0f, 0.0f, 1.0f);9 m; p' y, Z# G9 l
- glClear(GL_COLOR_BUFFER_BIT);/ P7 C) ?* C$ z2 c
- 2 p* A/ K1 T2 B7 j+ |1 _8 k; O
- glColor3f(1.0f, 1.0f, 1.0f);
7 D9 ^" l2 k8 K* j2 y% @- n7 W - renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本0 T" {3 c1 E/ r+ I0 e% x
0 B O! O+ C# `7 i- glfwSwapBuffers(window);/ ?) \. [$ s/ ^$ F8 i
- glfwPollEvents();! A+ C3 U% x9 X' v1 W/ N, T8 I
- }
7 s# t, W2 t) Q& p, n {
' ?. Y# t" O( A. ^9 ~% h* ^- glDeleteLists(fontListBase, 128); // 删除显示列表- J y8 p+ ^8 ?6 B( r
0 e+ c; x2 [( m& ?0 L9 ]1 p: Z- glDeleteTextures(1, &fontTexture); // 删除纹理# W) ^3 t* C9 R7 Q1 |+ @' D1 W
- 6 @& u, G0 O( `9 G# c
- DeleteObject(font); // 删除字体对象
, g+ H' f& g7 t: _
; W9 ]4 e1 c; K- glfwTerminate();
1 Z# E$ L8 L* I& q& Z/ u: W$ Z q
- [) n# M5 ?) \7 m; r- return 0;
0 A) g' | K6 C- d! i: R - }! L3 G* ~; A9 B ^% V
复制代码
, p7 P( X9 h. R* ?) I4 c! Z4 Q% S1 j) v3 n i
- R" {) }' S0 ]5 C9 S# @& Y |