本帖最后由 shane007 于 2023-9-6 16:01 编辑
3 r F) c: F! t$ w: V
- n' }* l/ k1 k生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。
) J- X8 I/ o" \* A2 ~0 A" h6 c2 }* ^3 B) I4 I6 w1 r- P$ ?
chinese.txt保存游戏中所有不重复的汉字。
! N. ?2 Q: i) R$ w8 Z# Jhook dll在初始化阶段,执行initialize部分代码,初始化字库。! h! e2 ^" t& }- h ]! p9 d& F
显示部分依旧可以用glCalllists方式实现。% s2 {. M3 \ g; Z7 V
+ O0 \" [, K/ O6 c6 d- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码 ) ]9 g2 M+ |" e
$ d# k: b0 P4 \- S0 c5 ~+ y# @( ?: x) `5 i2 Z8 e3 x
- #include <stdio.h>2 v/ V0 W( A( D* d. d! D
- #include <stdlib.h>
$ a+ [5 ]6 Y+ x/ k/ `2 y- E/ t - #include <GL/glew.h>: p5 y4 d( N( e6 J8 Y5 T
- #include <GLFW/glfw3.h>( R: Q" k( V, `5 K2 {
- #include <windows.h>
6 O n; \ V) S1 D6 r9 n; X
* m3 [# G& z# `& E! M- GLuint fontListBase;
! S! @. _, K: D$ ?2 ^: L) m - HFONT font;
0 }$ Y# e0 s; E% R O8 B4 Z0 C+ ^4 ` - GLuint fontTexture;5 @5 s) x, i/ D, I) P, ^6 z- }5 m# ^
- ! p I6 L7 h) V, z2 z* c
- void initialize(const char* filename) {
+ o( Q' i9 b: t3 m1 ~ - FILE* file = fopen(filename, "r");
1 K; k6 |6 y) N: h5 z - if (!file) {$ N! e: w( V) P/ }4 L4 p' Z4 O
- fprintf(stderr, "Failed to open file: %s\n", filename);! \2 v& Q# |" t2 e- G, B0 w
- exit(EXIT_FAILURE);* g n8 A- p8 C' a4 t# T9 @
- }- h# E' m( R. W: k5 M8 q7 v
2 @8 j. A) m$ o7 y- char chineseChars[128]; // 用于存储中文字符
7 N n; w( Z9 K! e7 n6 c" } - int chineseCharCount = 0;
, I" u* e* Z0 g4 T
, O+ X2 u3 y8 N; u, t& r% `- // 读取中文字符并存储到数组中
* U9 G) W2 r7 i/ l/ W7 R - while (fgets(chineseChars, sizeof(chineseChars), file)) {
2 c! k: Q* M/ E& _6 c - for (int i = 0; chineseChars[i] != '\0'; i++) {
% ]/ @- M1 s; y3 S i$ k; k/ c - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {
/ F' @/ t6 d, `- @ |" L6 Q9 W2 h - chineseCharCount++;
5 x( M2 y2 G! D, l - }; G7 J' T2 w2 }# {5 f
- } o: k v: }- ^7 V+ v
- }
- J- z- J* m n1 R) f$ B7 z1 |
9 T) P1 n; Q8 }4 H" H: y, j- fclose(file);
7 r" c3 ~( [7 e5 Q. w8 R; i - 9 P; l& w* a6 f" S0 W u. I
- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
# H: h' V- i$ ~3 C8 P
1 s. [2 q3 @5 r7 o, Y- font = CreateFontA(& M2 i1 w: d/ I# W( A F# ]
- 48, // 字体高度0 e9 S" }* M- q D4 k
- 0, // 字体宽度$ s# ]; N$ g3 E/ E7 P
- 0, // 倾斜角度) w7 x% J9 {' P" T- b& q5 n
- 0, // 倾斜方向
/ c8 a9 d8 h5 | - FW_NORMAL, // 字体粗细9 \! U0 Q7 P( l5 F% J; e6 @
- FALSE, // 是否为斜体* f3 Q2 q, C2 R9 T; O
- FALSE, // 是否有下划线
. k' j2 Y$ W& @; O# q) `3 u3 ^* e - FALSE, // 是否有删除线; H( W# B/ Y8 m: o7 `1 N& @
- ANSI_CHARSET, // 字符集
; r6 ?- W( t% u* ^% P( W$ c - OUT_TT_PRECIS, // 输出精度) ^: k0 a) r. t
- CLIP_DEFAULT_PRECIS, // 剪切精度+ L: c6 V0 Z: {6 z+ }$ h' s8 w" v3 g
- ANTIALIASED_QUALITY, // 抗锯齿质量3 i5 F+ j9 I5 Q/ c" J, g! P% @% i+ i( x
- FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch
$ t! {; {1 Z6 B) f9 n0 Z - "Arial" // 字体名称7 e4 Z$ T& I8 f8 q4 p
- );- B, X" ^& ~1 \1 {8 T" s: {
. k+ ^: f2 e# \4 n* \6 V1 t- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄
. ~8 I; G+ I% n5 t* `% `1 q - HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体& j% j, E# E# p3 e7 H0 q
- + [, }8 e; e' @* C$ a2 D& ^, C; Y
- int currentListIndex = fontListBase;7 j6 S5 e: a7 g, F: H& [. S2 h; I
. f: u/ S: O2 u% p0 f- // 逐个读取中文字符并创建字形位图存储在显示列表中
/ u0 f( I; X- a$ f6 p9 w/ ]8 d: H - file = fopen(filename, "r");
8 E- @$ m9 x0 l9 q - while (fgets(chineseChars, sizeof(chineseChars), file)) {
4 c) ]( ? ^( P% ~2 Z4 Y' F - for (int i = 0; chineseChars[i] != '\0'; i++) {- Z; p3 x$ O4 I( S
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {1 J0 K7 S% U z2 O! \
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);' I% F9 w0 d7 p4 G6 ~
- currentListIndex++;6 h5 z' n& I9 l7 K0 x$ d- l
- }
! P7 c1 J! e) l) \1 h - } k$ {4 q; t6 R- {" ?: w
- }3 b# T8 N$ v u
- fclose(file);
0 n% \( L6 e' p - ' j% Z6 l3 d6 W7 @5 N, n
- SelectObject(hdc, oldFont); // 恢复原来的字体
% }7 w" H. ?* A% f - v% |! j, s }, J+ V( e
- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图* C& f0 ?; ?8 N) c( w
- glBindTexture(GL_TEXTURE_2D, fontTexture);( }1 G E( r9 g/ _5 g
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);2 i @& J) j4 h: B* b& I- O
- }
+ p9 b6 l7 s! M6 ` - # Q4 d Z# y% e( I8 {
- void renderString(const char* text, float x, float y) {6 ^5 i- e' Q/ V3 A2 E- w* \8 M U
- glBindTexture(GL_TEXTURE_2D, fontTexture);# w) ^1 _3 x. d1 @* a1 v- H' Y
1 `) J8 X5 V9 D8 \5 ]2 e/ Z- glEnable(GL_BLEND);
0 w9 q2 [' N5 ]( g0 D4 Z - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);0 T3 D4 q- b* p5 H
- $ [ K+ \3 O: R) J) k
- glRasterPos2f(x, y);
, A) G3 |' m z( c, g" P& T - , u" u& l( f/ ^
- glListBase(fontListBase);5 ^, `8 Y" y: w1 p4 V
2 L7 o: O0 e7 s" z1 V2 H6 P- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本
0 L- a' B% S# H+ O# l$ ? - + a9 |) G. D% Z- a3 P5 t- L/ q0 `% A
- glDisable(GL_BLEND);( g3 ]9 j1 ^' I6 b$ j' x
- }
! |1 a# K' a7 W3 O. d - ( A% I: ~! e r$ g" @+ V+ N
- int main() {
" M% p* g7 g; z: ^- ]3 L - if (!glfwInit()) {
: c' T B) H# |, E4 O+ l* } - fprintf(stderr, "Failed to initialize GLFW\n");
7 x+ l8 M0 U+ J0 N; l. W3 V0 [3 q- u* o - return -1;
; k; _/ u2 Q6 u$ G' j - }8 @6 q+ P: T" x A8 k3 M
- , }# Y$ i. v% l* R
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
# @( q, v' t$ y7 ]) I) l' n. _, o+ l - if (!window) {8 I; t a4 s0 Z2 M5 {9 f8 X3 [
- fprintf(stderr, "Failed to create GLFW window\n");1 E, u/ p+ b- K6 g) ^4 C6 X" L8 b
- glfwTerminate();8 C0 I& w: d* a- i& t8 a
- return -1;8 Z4 m6 A- p8 |
- }
& {1 O9 ?% p! l: R7 }( K- {
; y" @# D; v9 K7 L5 H- glfwMakeContextCurrent(window);8 v9 }& j3 J4 X( w
- glewInit();
% ^; w' B- g1 Z: Y3 [6 W0 _* Y
7 Y" I5 w K1 v8 M7 D- initialize("chinese.txt"); // 传入文件名6 c2 i a- Y2 R) c3 {3 |& E% \8 u
- " T6 ~5 C+ e% a @/ L6 x
- while (!glfwWindowShouldClose(window)) {
4 _- J) t; p" U' E! A) e - glClearColor(0.0f, 0.0f, 0.0f, 1.0f);3 P! s) @2 ]) y+ F3 j7 g, }* `8 a
- glClear(GL_COLOR_BUFFER_BIT);
* x O3 b6 ?4 X4 ^: p6 c$ D5 k
1 ]2 y+ \/ P- }. T8 U. ^; ?- glColor3f(1.0f, 1.0f, 1.0f);
~9 Q5 X- Z8 `/ T- d% D# f4 R - renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本+ \* x Y6 s! l8 T2 F+ @# s" b, E
- % ]5 q2 M- d0 K+ v
- glfwSwapBuffers(window);- p& Y; }5 r0 |
- glfwPollEvents();
8 T4 \) @' q+ f2 X, z2 P1 V - }) \ E* M6 G* S( _/ K" `
/ g5 B0 x U. t. A8 n- glDeleteLists(fontListBase, 128); // 删除显示列表& I7 b6 u* c' P! l# x% Y
6 {3 K+ ^6 @. C- glDeleteTextures(1, &fontTexture); // 删除纹理
( I, }5 C& \( G8 V
6 l& i8 U" E1 ]- DeleteObject(font); // 删除字体对象9 K: q* }2 S% J# a2 M! j4 V
- ; C9 j) G, f: u7 N8 R, B
- glfwTerminate();
- d5 a9 K' F" y - + i6 v4 b( b# J2 y7 s: z
- return 0;
3 t: Z# b5 J+ ?( m2 K. i$ C' g, _ - }
3 \' ~- R w- m5 c ]" K0 l
复制代码
% ^. B7 S% u3 v W! W
* d# J5 |+ `5 u- D( G
" k' \! s4 U0 E4 U9 G# S |