本帖最后由 shane007 于 2023-9-6 16:01 编辑 0 Y1 D% u- g. c* a7 x
[* b/ m6 F" K- r( F/ y) k6 h# U
生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。
! I( ~% X' M) B5 H; f5 I6 K5 N: H2 `5 f0 K8 q: i8 V4 W9 Y2 p. _
chinese.txt保存游戏中所有不重复的汉字。& i( c$ D+ j2 P, |: }+ y
hook dll在初始化阶段,执行initialize部分代码,初始化字库。
; s6 w1 w, e% Y$ x9 f5 m+ W显示部分依旧可以用glCalllists方式实现。
# S& r8 a) c7 a3 B; U1 r. l
: f( [. k' i0 n5 ~7 V- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码 6 @6 U6 F5 T. l9 v) d! H: w
4 L3 F) `- z& w/ ~) l6 h- G
) `4 U% i5 Q. ~# g3 U
- #include <stdio.h>
3 f! Z5 |& ^& e* o8 i - #include <stdlib.h>/ n6 R0 {* N0 _& o I, R4 }* z( }- q
- #include <GL/glew.h> _% q5 G( i4 \* L4 o3 P
- #include <GLFW/glfw3.h>
" o$ v, C) M1 h! X$ E8 R6 J( |+ {) N - #include <windows.h>
! g3 |7 q% U6 w# U# R& r- o
. ]: N2 `& }. b- GLuint fontListBase; v; F* F- Q- U1 c$ b# C
- HFONT font;
- X* w9 G& B6 C5 ^ - GLuint fontTexture;- Z6 S9 I' |* @$ y3 [8 h6 `
0 k; o7 F: y. ^/ w- void initialize(const char* filename) {
0 v: m9 E. {5 ]( K3 R - FILE* file = fopen(filename, "r");
# P; R1 L0 }6 Z- ^: K. d - if (!file) {+ x5 F7 s8 v; s* J( @, A7 y
- fprintf(stderr, "Failed to open file: %s\n", filename);$ P K! G3 K1 d! v$ k q
- exit(EXIT_FAILURE);
1 b; H- e- U% @: b$ t - }
5 \; b: n$ i& z: `% Z; p |* a - ) r; [9 Q( w, G, i2 P: {: E# d
- char chineseChars[128]; // 用于存储中文字符1 u0 y1 ~& v* @0 F6 \
- int chineseCharCount = 0;
; h6 }, [ |) }/ u x/ I - & p/ G8 y% } B; y: w3 H" M9 [0 C
- // 读取中文字符并存储到数组中9 d* Y, X! h+ V) F8 p
- while (fgets(chineseChars, sizeof(chineseChars), file)) {: ?0 q C( u- T% n
- for (int i = 0; chineseChars[i] != '\0'; i++) {
' P) d5 {; }" [3 { - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
* o7 m/ x( r8 p) D - chineseCharCount++;0 _/ b0 {2 L! I- }
- }3 u- r. X! N% { W% V( C2 p/ h
- }2 R" I0 d: P/ ~! H* q9 L3 |
- }: I$ [: D3 v6 Q
9 s" r& q8 X4 n" y3 x4 ?. Q. E- fclose(file);3 x& L9 u- }3 f' m" _4 a
3 U: K) A3 R' o( t! T. c- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表! s) r4 R* M5 @( K* }' M
- 8 |9 h2 i; o+ l( c
- font = CreateFontA(
5 D- Y& n; g0 o/ T2 B% ~; e - 48, // 字体高度
/ }# X U6 k9 Y7 | - 0, // 字体宽度
+ [$ d( ], a) i - 0, // 倾斜角度 u# q! l6 `+ r/ O3 I
- 0, // 倾斜方向$ F2 L% S5 L/ o; }0 L
- FW_NORMAL, // 字体粗细
R: W& u4 U, p/ }% G: ~ - FALSE, // 是否为斜体, p; J7 Z: s/ ?4 }% h8 k6 k7 N
- FALSE, // 是否有下划线
" u( _, S$ E6 G# W R% v2 x - FALSE, // 是否有删除线
# X* Y5 M* ~7 v3 M4 a - ANSI_CHARSET, // 字符集
1 g3 t# l% S& [0 g - OUT_TT_PRECIS, // 输出精度
; t7 e+ {4 Q+ `1 [ - CLIP_DEFAULT_PRECIS, // 剪切精度& o1 c' }& W; P2 ^' S
- ANTIALIASED_QUALITY, // 抗锯齿质量( k+ P$ v; |; k' A9 r- b
- FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch" ]- l% T# p( N, d2 X
- "Arial" // 字体名称1 A! q# I6 F# A8 h- m0 z9 ~
- );: G6 E8 h ?; C1 c2 m3 W$ }
- + }7 T Y( H; c( `
- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄
9 U5 ?8 M3 e# a3 T6 q - HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体
0 a' ?# m3 T9 R$ }$ [ - ( P1 T2 q4 Y7 S$ \2 a1 I% E5 a1 p
- int currentListIndex = fontListBase;
6 y0 s* e8 c$ V - ( H* K) U% g+ I
- // 逐个读取中文字符并创建字形位图存储在显示列表中, c& g0 R+ D/ T" ?# a( R% M
- file = fopen(filename, "r");$ h+ w& O) ~/ x; m. n a
- while (fgets(chineseChars, sizeof(chineseChars), file)) {
' @; ^5 g7 o8 A+ z( r - for (int i = 0; chineseChars[i] != '\0'; i++) {! L3 w' `+ r$ |5 _! o1 U! }: e
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
) H, l4 i. W5 H% R, g; V - wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);
" l+ ?- [6 S, D( } - currentListIndex++;
/ K7 S, p9 i8 G' P' l C) p$ W2 W - }
+ g. s- G+ Y4 j. I z' E" Z - }
9 E' I& Y" K% k - }
4 C6 s6 ?7 k( A @/ l. m ] - fclose(file);( p: I0 u7 l! L: H- y
- : k2 A. L' P2 ]. Y! O9 F9 s
- SelectObject(hdc, oldFont); // 恢复原来的字体
/ g3 I+ T( a. B9 o
; W4 m* k3 h; w3 ^! k0 Q# p- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图9 A/ q4 ^6 b) c* \* q/ S7 F
- glBindTexture(GL_TEXTURE_2D, fontTexture);& G! o9 j$ g* y: @4 S
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
6 ?. h$ x6 E! u/ O - }3 ?% e: V9 \+ S
- ) \- T& [' v. S: A& G0 q/ h
- void renderString(const char* text, float x, float y) {
. j" @+ X0 C4 o f- R8 _ - glBindTexture(GL_TEXTURE_2D, fontTexture);
/ k6 \& P9 E* g1 e, x: G - + n7 a+ K# n) J# q- l
- glEnable(GL_BLEND);
0 x% B) p; k% V4 v - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); L* p8 n2 n* W, j |3 j- ^
: d. p- f. s/ e% m/ W! B) j7 ~) [0 C- glRasterPos2f(x, y);
; q+ e% I8 X* e {- U - : s x. H. v1 @8 t/ Y0 `- M- @( [; p
- glListBase(fontListBase);0 l8 m% h9 ?- b" D# B6 q. ]8 c
/ k Y6 G/ O6 d0 X5 l/ k, Z- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本) l h; c/ A: @" f$ U% p3 a8 u
% L$ q: q+ Q# r( ?- _- glDisable(GL_BLEND);
m3 j6 Q) ^1 L/ d - }
$ F: b7 _1 L! h x0 | - ; |# g- r. w7 q! g+ B# l$ h. r
- int main() {
6 Z9 a7 u% E! S. F - if (!glfwInit()) {
' e+ E4 e. b% r, O7 k - fprintf(stderr, "Failed to initialize GLFW\n");
! M C E1 G/ _ - return -1;
% P! t+ O0 ]% b( Z4 Q3 ~! p - }8 \% X* G- E9 V, q9 b4 L% h
- 7 G ?3 R S: D1 X
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);' X) J) {* e- X$ ?! P1 ?6 M# T
- if (!window) {+ U! B: ^- ]. _6 Q1 x( I$ t
- fprintf(stderr, "Failed to create GLFW window\n");' e2 _: k2 i1 q% [1 D" d
- glfwTerminate();
6 D) v# l7 Z: l5 p - return -1;) L& `. a& R' c& w" B. a; @
- }* [' s9 j9 @& X0 t0 y% G
- ! C7 S7 }2 z" @. }( g
- glfwMakeContextCurrent(window);
2 D/ i; k6 L0 p4 H9 B. q+ \% }1 O - glewInit();( K! K$ ]* d i
" \/ {0 H8 d5 h; a: v- initialize("chinese.txt"); // 传入文件名
- u" F/ S: l% k% Z( W( H" J
* Z: O# ~9 ]: P! z0 u- while (!glfwWindowShouldClose(window)) {
% p" h% R$ {* v- D. L# H - glClearColor(0.0f, 0.0f, 0.0f, 1.0f);5 X; ?4 i6 b1 q! x( i
- glClear(GL_COLOR_BUFFER_BIT);
( }7 R8 W9 X. H- h - ; ^$ \ [& W/ p/ B
- glColor3f(1.0f, 1.0f, 1.0f);
7 a( s% z U8 ]2 z) I# Y - renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本
) Z3 v- c3 j: e+ }& d$ ~, F
5 s" `" B7 O$ C% D- glfwSwapBuffers(window);2 l9 p- n* \( V
- glfwPollEvents();
' f# ?* G! J/ f! \/ b* P - }
1 x. g ^+ H) e3 Q/ O8 n n - 0 T1 i2 S! z; S: D6 Q
- glDeleteLists(fontListBase, 128); // 删除显示列表1 x( ]0 x+ X- ]% @9 B& A
8 y, X1 A1 K3 e' |! v) `! \2 M- glDeleteTextures(1, &fontTexture); // 删除纹理
8 |$ H! R A* Z2 \( K - 0 r9 E, B0 z2 H [
- DeleteObject(font); // 删除字体对象9 P# T" _+ r5 j) Q8 A+ a: i B
& h$ v! \2 L3 s( e8 s- glfwTerminate();8 O# z+ i: z- M+ w: w9 a
A; p( e; c# l6 Y# C' E P1 i' B( F- return 0;7 K/ J+ Z S: e, y& A) {
- }
! X0 B3 U/ V u: n7 ~7 E$ a6 I, D
复制代码
& `5 s4 z6 G! S# a2 v& j
! t" x3 z' P# K- C! `/ S7 a# v
; `; k$ ~5 j1 Y; S |