本帖最后由 shane007 于 2023-9-6 16:01 编辑
7 Q+ c0 O5 z, E1 S4 Q4 k3 ]- [- H9 y
生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。- i, K( g w3 K0 F2 K
% L3 b. Q$ v8 S# F; |
chinese.txt保存游戏中所有不重复的汉字。) x, j, `8 _ \2 x
hook dll在初始化阶段,执行initialize部分代码,初始化字库。( Q& X/ \8 v$ x4 m( x q+ u
显示部分依旧可以用glCalllists方式实现。* J8 q* K; [: F( U, J3 v: n* g
2 n5 _( S+ \' n- `
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码
4 S6 T( @& Z {! d+ k) X$ N
% D1 ?. [, s& G$ k$ i* f0 A7 w5 y* Z0 J
- #include <stdio.h>+ ]: s/ N, l0 _9 |4 ]0 N" ?
- #include <stdlib.h>! L+ H5 N3 ?; ~8 D# u
- #include <GL/glew.h>& Y7 C% T+ ^1 w8 }6 K% ^/ u
- #include <GLFW/glfw3.h>
* J q' b. V4 z' @7 K, u9 ^4 m - #include <windows.h>7 e. D9 y8 Y8 ?; U; ^0 l$ s/ ^
! g$ \$ F) U! q2 x- GLuint fontListBase;
, M& s7 G' j) k- x2 H - HFONT font;) ~1 {* n8 e, p% Q+ A9 X0 M/ A0 f
- GLuint fontTexture;
5 u+ W# E# {) M
. i; G' g6 A& ~( {- void initialize(const char* filename) {
3 r7 Z5 _# t- A+ N' Z8 q - FILE* file = fopen(filename, "r");
4 ?$ x) ^* W5 ?; K/ Q0 ~* X - if (!file) {- w" r [& j% j- J/ w6 }
- fprintf(stderr, "Failed to open file: %s\n", filename);* X! e0 \8 U( k; `! ]4 `$ Q* I
- exit(EXIT_FAILURE);( I" R( H+ ]# @( K+ N* B5 A2 V3 u
- }
# }# p- f" e4 e$ `0 ?' w3 z - 3 c! I/ R9 o" V
- char chineseChars[128]; // 用于存储中文字符* X8 j" }/ }% d/ R
- int chineseCharCount = 0;
5 R# W4 Y( C9 X9 d4 U - 7 u- a( a& a; q2 ?0 a( Z5 c: f
- // 读取中文字符并存储到数组中
( |/ w2 Q6 {2 f4 T+ A) | - while (fgets(chineseChars, sizeof(chineseChars), file)) {
$ d0 W, Q! T3 t/ K - for (int i = 0; chineseChars[i] != '\0'; i++) {* c* m% P5 x. Z
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
5 H$ P5 v8 p# a+ V - chineseCharCount++;2 C, d4 V* y9 m& S P
- }
7 i/ o) ~: E6 F* G, _ - }
# m, [; L, M, N - }
& ?/ C& O1 B' M# O! ~1 I
$ `# Z& q+ S' M% B* J+ a q, c- fclose(file);
, e2 ^; l2 ` ?4 y+ p
7 g& n8 p! j7 {& Y- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
8 @' @2 G+ n& D% M( u' P' U - % V1 W% L& ], g1 n* W! H6 \
- font = CreateFontA(( g; h" A6 v- ]% \' P/ t* [$ d# L! P
- 48, // 字体高度; Y1 l. u1 X1 @
- 0, // 字体宽度 R2 ^8 Z, A& z) ^ [5 G- Q; H/ N
- 0, // 倾斜角度) I1 t8 P9 t5 C
- 0, // 倾斜方向
" p/ z: w/ Q2 m r* f - FW_NORMAL, // 字体粗细$ j+ S6 X3 @* {: X
- FALSE, // 是否为斜体+ n/ B% ~0 _: c/ C7 u' e5 j2 K
- FALSE, // 是否有下划线4 U* Y/ v; ]% @( n
- FALSE, // 是否有删除线8 p( H; Z# \" M& C! \
- ANSI_CHARSET, // 字符集
( m$ D% x: W8 Z/ e - OUT_TT_PRECIS, // 输出精度
& ?0 ^! t* _4 I# V; w - CLIP_DEFAULT_PRECIS, // 剪切精度
' r5 a2 n0 O) f9 [ - ANTIALIASED_QUALITY, // 抗锯齿质量
2 o* O. ~6 B7 m* p. T% }0 m - FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch
; ]5 y, P+ w8 e - "Arial" // 字体名称
C- [ H- f9 i7 {( J0 n - );
0 J# }+ `5 R9 G: }& T/ y% w- P$ z - / A1 x) w5 q( Q! O& f- g2 y
- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄
/ Y* T& c1 {& C- h ~+ {) E - HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体$ W! ~7 C- f/ w' a6 ^ e) s
) e' l; U# ]0 u$ m6 P' g- int currentListIndex = fontListBase;
7 T9 Z5 p3 d' [3 K1 j1 u) [
) Z- p7 x8 k" ], D- // 逐个读取中文字符并创建字形位图存储在显示列表中
* t, I6 O1 l: x, K9 v3 r- v - file = fopen(filename, "r");' _! t$ ]* Z, T4 M" L
- while (fgets(chineseChars, sizeof(chineseChars), file)) {
2 P! k2 r" |# }: J( [- P - for (int i = 0; chineseChars[i] != '\0'; i++) {
% N& t. E9 M `. e5 b! w2 q - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {0 L) f' W" j) |2 X. R& b7 L1 i3 I$ s& |
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);
4 T! C0 {6 e5 p% Z; C - currentListIndex++;
- A5 s: E6 r# O3 e, [" M - }
! h4 J& Z2 \9 ~% Y8 E5 [ - }/ J+ H* X- E8 \ n$ O- s
- }
7 U1 \% ~/ c- w. e: c - fclose(file);
: S) X1 y5 }# \7 W
* y% G6 i3 F% O! }1 D; U- SelectObject(hdc, oldFont); // 恢复原来的字体, K' r o: v3 o% n6 }/ S
; {0 w! ^0 q& V6 Q# G8 z% `- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图1 Y, I, a5 I. c. o1 M2 M
- glBindTexture(GL_TEXTURE_2D, fontTexture);
# Z7 F; a s7 K; |& ]5 K$ t: E" T - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);, a/ O+ o. R, \3 x! U
- }
2 b* s7 C6 g/ Q- k' g - 8 J. v+ s3 o6 x- g! ]8 c& l
- void renderString(const char* text, float x, float y) {
/ K: R8 V6 Q- X1 B - glBindTexture(GL_TEXTURE_2D, fontTexture);
/ F1 s$ i6 L. D& y2 q, q) W* r
7 {0 q2 a( j) u) J$ D" d- glEnable(GL_BLEND);* ^1 g: p0 T% z
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2 R+ E6 x3 x5 T6 f5 Z - . G' [) v u( o) \5 n1 }
- glRasterPos2f(x, y);
; w' t. q: E) B# y! T/ U- Y l, z - 2 q& W. z3 ^) D Z
- glListBase(fontListBase);
. l: b- e# u# B9 g9 z - 6 x) Z6 h- W% y+ k( P$ j
- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本, W# g) b* x, g( `5 i. f# ~, w
" m- U2 x% p5 J' C- glDisable(GL_BLEND);- m! c) P& |1 F* C/ v+ Z! S$ S4 ?
- }
. X' A) G) i: O6 A
- E7 n7 k5 b9 M. t& l; c- int main() {/ v* N" g! y+ \- _4 W, C
- if (!glfwInit()) {
- W g* e7 I5 `% a+ Z - fprintf(stderr, "Failed to initialize GLFW\n");
- |9 x* u1 O' A8 P3 c! x - return -1;
& Q' m- N% j8 E: |* i3 ~- n3 | - }
5 ]! U7 h5 P( o$ b& o3 x - $ N, t* t4 ]1 y
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
0 l/ \: Q( p- m! ]% u3 o4 P - if (!window) {
/ |; U4 s% G; k* ~6 [ - fprintf(stderr, "Failed to create GLFW window\n");
$ \ @$ `4 u' J8 m4 ?6 J3 I - glfwTerminate();
. b4 w2 {9 C5 O5 d' I) a2 q - return -1;
$ ]/ B9 T/ y! r - }
, X+ j6 |- S$ ~7 { - 5 z5 B: {! G8 w" W' I8 R" l1 ]2 `
- glfwMakeContextCurrent(window);
& q( W3 D0 e* U. I. l6 G) a3 q n& p - glewInit();
1 d/ e7 u! ^3 Y7 \9 Y - . c8 C5 w" `& i% `, Z" J3 e
- initialize("chinese.txt"); // 传入文件名
% r ?. v4 H8 Y& l- Y- K
3 [, u6 d% l) a' Y% G8 p- while (!glfwWindowShouldClose(window)) {
3 s* P$ q+ d% n5 k9 T1 B - glClearColor(0.0f, 0.0f, 0.0f, 1.0f);/ \ K2 {. I+ i' }: w7 e- I% Y
- glClear(GL_COLOR_BUFFER_BIT);
$ ~3 c) n3 U0 Y1 c2 r3 [ - 2 r7 D8 u2 F( ]
- glColor3f(1.0f, 1.0f, 1.0f);
4 d: m. ]! Z2 L5 g - renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本1 g1 Y5 C1 B& Y$ z# K+ ?& G
0 C ]4 m9 I& J# U: F8 |- glfwSwapBuffers(window);
; ]! l# B9 v) z2 Y - glfwPollEvents();
3 ^9 |2 }5 o+ C: l2 F* y$ @ - }8 P7 Z; o4 P. z5 m' |
9 R' Z, U0 \, x9 b: s8 X# F4 L- glDeleteLists(fontListBase, 128); // 删除显示列表
" `1 F, K5 R! |; U2 _* o+ d - ; d! e7 |$ {6 B! T) D
- glDeleteTextures(1, &fontTexture); // 删除纹理
# J+ Z0 e6 J* K- x9 n# u0 Z - 5 R2 F2 O' q# ` |
- DeleteObject(font); // 删除字体对象8 M( t3 o& o9 y
) v1 s( r" U- e+ B. A% J( n# P, [% |- glfwTerminate();2 U( F4 M3 H! S; |1 s; v3 v: B
, e( @; s7 [- A( r( H+ A/ R# N0 r- return 0;! g2 M+ D$ W) u/ \
- }$ a" x3 y* S( r8 G6 Z3 w
复制代码
+ {+ m4 k4 |! I1 |% h6 l0 O9 f+ \5 a2 V, T i
( x0 l' I: |( _$ r) ^" s |