本帖最后由 shane007 于 2023-9-6 16:01 编辑 ( ~. s# V% y- b _
' L& e2 ]# T; q% {) U) w* ]6 b# W
生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。
0 w( p% U N; p" Z" p& K+ |0 q
% ^& [& X& K6 i4 a! Uchinese.txt保存游戏中所有不重复的汉字。# b9 `! f" M% r6 P, f+ P
hook dll在初始化阶段,执行initialize部分代码,初始化字库。
' @* D$ m+ l6 A- `. Y- P' X |显示部分依旧可以用glCalllists方式实现。
+ Z7 R ~" I/ |$ L
! j W$ i: }% j% @- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码 6 J0 M) Q' a, x% o0 u5 N# ?
& ^! {, s9 ?. c1 u; R5 K1 P5 }3 o! |, j# V9 k, ]& _
- #include <stdio.h>9 t) P" h4 H* E+ \& E$ M
- #include <stdlib.h>1 w) j: ?' s7 g8 m
- #include <GL/glew.h>
/ Z5 |# S9 J% {7 b' Y" d# t - #include <GLFW/glfw3.h>3 _+ v H1 i* i1 j" w
- #include <windows.h>5 Z2 [% t! X O# X% J4 D
: _" h& t c% q- C- GLuint fontListBase;
2 l4 R2 Y# K# Z( \! C2 h/ f. b3 _ - HFONT font;, M' ^) {! o0 B+ x1 ]1 X+ E5 d
- GLuint fontTexture;
4 T8 y! |- }7 u+ L: e
7 n& x x) P( p e, c( |- void initialize(const char* filename) {; p" n+ M$ `0 I( ^# w; U
- FILE* file = fopen(filename, "r");
6 _0 n7 b0 T7 K; Y; a - if (!file) {. w* d- o) _ V1 X7 o! [5 ^0 d3 E
- fprintf(stderr, "Failed to open file: %s\n", filename);
! o' F; R& g W% } - exit(EXIT_FAILURE);
& _ m# k0 Q8 u) S - }) S2 |$ M6 P# b
* G p2 c8 Z: }- char chineseChars[128]; // 用于存储中文字符
! ]" ?( C% j3 f% Z: L - int chineseCharCount = 0;5 T2 b8 \/ @8 E9 Q: [
2 m2 ] g1 c1 Z. C/ z- // 读取中文字符并存储到数组中0 Y: W8 V' ~" \: @
- while (fgets(chineseChars, sizeof(chineseChars), file)) {
# h, I, d6 @& F; K3 z! n/ Q8 E - for (int i = 0; chineseChars[i] != '\0'; i++) {" L. c5 u' a9 v
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {" z( f$ ~# B1 H/ {- O* E0 \4 c
- chineseCharCount++;1 v7 p1 n) ?0 e1 c+ o
- }4 y2 J1 z; z! K( c- v" ~
- }
& a$ g7 J8 X$ p - }
7 F# @) X5 }3 Y" _" z - + K+ g+ M9 t; e$ R
- fclose(file);
9 q: M; A4 M5 [: E- U& G& b A
' i+ a& R( y$ b G! _! ]" H- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
9 c; l, O. ~) d: l
+ \1 @2 {& c9 R- font = CreateFontA(
! K% s4 B, E" Z, g ^1 Y6 I* d - 48, // 字体高度
/ e e6 R$ X; T" Q" } - 0, // 字体宽度
, l9 H! ]4 }9 f+ F) @$ |' x - 0, // 倾斜角度; z. ^7 o3 p: H( d
- 0, // 倾斜方向+ v& {" F3 u4 s9 Q5 x) A1 t
- FW_NORMAL, // 字体粗细
; w+ f7 h" ^) J# H, X- d/ A - FALSE, // 是否为斜体
% X2 }3 Y" o3 B" ?- z+ ]! a9 r0 H - FALSE, // 是否有下划线
9 a* q" z+ N- u. i - FALSE, // 是否有删除线& m* ~' L0 r' b# K! z$ G9 \
- ANSI_CHARSET, // 字符集4 a" v& L0 l8 P8 _
- OUT_TT_PRECIS, // 输出精度
7 J. }& a- n* Z3 E* P' B - CLIP_DEFAULT_PRECIS, // 剪切精度1 o* w. J- I7 E& ?6 a. L
- ANTIALIASED_QUALITY, // 抗锯齿质量
3 c" ]) M$ P$ ?4 M - FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch3 q1 e ^( n4 A
- "Arial" // 字体名称6 x! _9 G4 W/ \9 R5 R4 V- d# @, P
- );
, X+ n! e. \8 J; H ?" q
+ c# Q7 n! F6 y- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄. o6 A5 @5 z/ x3 P, _
- HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体
5 x2 J- z4 s( _4 W6 q$ R5 j
2 c: d) J5 i+ N+ u# A$ d- int currentListIndex = fontListBase;7 g' K2 Z. ~+ O' b0 q5 k
- & `, c- F! v8 L# _5 R- u2 y9 H
- // 逐个读取中文字符并创建字形位图存储在显示列表中& q- _$ W1 Z" ], Q" K# m7 f# ~+ U, b
- file = fopen(filename, "r");: S" w! S; a: G0 Q
- while (fgets(chineseChars, sizeof(chineseChars), file)) {# e0 }: g9 ]8 L" Z
- for (int i = 0; chineseChars[i] != '\0'; i++) {
: w8 S/ b0 ^2 c7 I* k3 o& t% O - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
1 `# `# F& Q) ?% L$ @# n - wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);
c, c/ o" i, d- Y. D! s - currentListIndex++;
9 ]& W3 d6 q, |$ J- \2 u6 Y - }4 N7 Q5 Y7 j/ u1 z' v
- }
4 _2 |4 u* v; u$ O - }: y! Z/ z3 D) v: a# N2 n
- fclose(file);
5 x( \" |4 w. q* {3 @ Q4 R - 0 u7 R# b. Y6 o" [' x+ S3 z
- SelectObject(hdc, oldFont); // 恢复原来的字体( B0 O( j3 r `5 w
- 6 }9 S+ K0 T$ ~6 Y1 F
- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图: q+ b/ N! R7 d' s; u
- glBindTexture(GL_TEXTURE_2D, fontTexture);
6 G6 ]8 w/ i9 _* { - glPixelStorei(GL_UNPACK_ALIGNMENT, 1);- F! Y& q1 l, h' O
- }5 y( e) L- d% U9 p
- & L+ r( ?1 t/ u+ L
- void renderString(const char* text, float x, float y) {
' V+ B4 K* x, Y0 H - glBindTexture(GL_TEXTURE_2D, fontTexture);
, q" P0 z9 U6 b8 g - 8 K" p: u8 N w+ ^; w9 e% k. F. e
- glEnable(GL_BLEND);
5 U% W) z% p- a$ P - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);* G* \0 M8 P2 Q: x
- ) t& F( s; U* Z9 ]
- glRasterPos2f(x, y);5 j( ]" ^# C& V3 g
! ~, ?8 }+ s# Y4 c m* a) G- glListBase(fontListBase);; A7 V6 u1 E) C+ C
' N% q! E* d0 y- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本7 |, m" ]1 m2 v6 I) t# M0 B
7 q( Z E. T; V* L. ^. ~- glDisable(GL_BLEND);
/ K" w6 a/ E$ b% V- f' u' G6 \ - }! l( o5 u% L% v- `. k
- 6 u; g) i, U2 Q5 h- ~, s3 o
- int main() {
$ Y( k2 ?5 H7 D$ c. L- _4 Y* R# F - if (!glfwInit()) {
: C2 T* J2 B& N6 o9 N4 I - fprintf(stderr, "Failed to initialize GLFW\n");
J, B& G# R* O( f$ ~8 t - return -1;& x/ B" V. A1 |2 @1 t
- }
' `6 J; Y, U, [. W# x- r4 y
0 F- F' r( E9 I: N" \- ~- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
. q+ ^! [" i9 H7 f! C# ` - if (!window) {) b$ V; @5 f- l- d
- fprintf(stderr, "Failed to create GLFW window\n");
/ Y0 \' f% y7 j& j9 s+ F - glfwTerminate();5 h; _* Z& N1 \% b3 x( m
- return -1;
4 Z8 O2 K2 I3 O& b i - }
' |6 a8 }$ s. Y7 D - X. s) [0 V' r5 a
- glfwMakeContextCurrent(window);
2 T8 Q, j4 d, ]* p. i& \ - glewInit();2 ~/ o0 B6 Z+ ^, M B
3 S/ P& |# M5 W$ i9 l- initialize("chinese.txt"); // 传入文件名7 f+ R* E8 e" |+ B' v
- , I9 y5 c2 m4 H1 b6 i/ d
- while (!glfwWindowShouldClose(window)) {' E1 n g0 k. p/ w" a# [1 m/ P
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2 t' o. q- B3 o1 w& |, F6 H - glClear(GL_COLOR_BUFFER_BIT);7 T. s5 Q: H; s3 T7 Q/ v
- 5 a- N0 D J' w) Q8 l$ [
- glColor3f(1.0f, 1.0f, 1.0f);
% Q7 H& B( r1 D2 b; r1 s" V& x - renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本0 c1 H3 F6 U7 q/ U ^- s- g
- * `. D6 D7 u( n1 S9 G4 ?
- glfwSwapBuffers(window);0 F9 ?. ?# B; L
- glfwPollEvents();
3 l" e# ^% ^: |4 }4 L - }
a( }$ Q( y* L4 s/ b7 o2 j
+ U& y6 o& E3 L4 ~1 `8 `$ M, \; X2 D& l- glDeleteLists(fontListBase, 128); // 删除显示列表7 m/ D ~% n& g0 z7 X
- ( I/ U8 a0 O8 r! X" U, n
- glDeleteTextures(1, &fontTexture); // 删除纹理6 e1 U/ u" F2 ]- B# ?; ?
- : K: S. P3 @+ u: _: ~
- DeleteObject(font); // 删除字体对象
+ m! g: E* Q p% n - $ D2 k- e& m5 o3 G* H5 U
- glfwTerminate();
4 L% k: p* E# I7 |' c7 U - 7 E/ l2 i( c% x, m6 o: l; T
- return 0;
7 Y, b, [) [4 w" ]0 O - }
1 }+ P1 L( \! G4 r+ j
复制代码
3 @ X8 n& {" B* x$ O+ ?3 r1 g! h* ]8 F) z, Z! K
! I5 U% E1 p% K+ Q7 F3 X' \
|