本帖最后由 shane007 于 2023-9-6 16:01 编辑
9 \& u! N0 V2 q1 w5 l1 O( `9 V4 S# r( Q
生成了一段最接近于游戏原本代码的代码。把这个程序调通之后,将相关代码段取出,放hook dll的相关部分即可。8 m* u8 ] z. S3 Y9 c2 q, x
9 k/ v/ D. f" z, ~chinese.txt保存游戏中所有不重复的汉字。- [ u* ^0 N7 Z, z, w; q$ P
hook dll在初始化阶段,执行initialize部分代码,初始化字库。: f" y* T$ L0 d! R+ p2 r1 R( V" e
显示部分依旧可以用glCalllists方式实现。
- v d$ W' h- w/ N* A# D+ K0 n; F& n# B) {' n" t
- 这段代码会根据 chinese.txt 中的中文字符创建字形位图,并将它们存储在显示列表中,只生成 chinese.txt 中包含的中文字符。确保 chinese.txt 文件包含你想要显示的中文字符。
复制代码 " K" Q5 @. J" K; |; i
" Z. x9 f( F; l' H% C u, H+ f8 T4 O* o
- #include <stdio.h>
! Q2 Z, M& r T& _ ~# T+ ? - #include <stdlib.h>6 P' @, h9 y4 z( K4 b% m
- #include <GL/glew.h>
; z& `' J- }7 d% I; p- G* j - #include <GLFW/glfw3.h>- ?3 l" O+ s0 N2 b' k8 ~2 X* P
- #include <windows.h>) K! F" F. F6 X$ [& @
- : R+ `: T$ I; v- @) N) z( i. G
- GLuint fontListBase;+ \& Z: @( L, b7 ~5 M
- HFONT font;
# |" `4 t, B& t$ S, b" h+ _ L - GLuint fontTexture;3 x6 K5 Q% N$ p: ? \
/ o2 v8 x1 y# ?$ m0 ~& L- void initialize(const char* filename) {" C8 [0 u, J% f2 ]" |& P a
- FILE* file = fopen(filename, "r");
1 E3 ~. Y( w9 j& x2 M0 Z0 P$ R - if (!file) {
% L, @* s" R( }0 h - fprintf(stderr, "Failed to open file: %s\n", filename);- ^9 ?- L0 p% s1 i4 K; O! z. I
- exit(EXIT_FAILURE);! v! h1 t' O8 Z7 `+ q+ X: N
- }. S( e. j& P! n
0 c0 L# W: Q2 G6 [6 Q/ p- char chineseChars[128]; // 用于存储中文字符
7 ?* S( Z F0 p$ J$ d" W3 K5 x. ^" O - int chineseCharCount = 0;' x2 F: N) L8 B" Y2 ?
- 2 U/ A2 U6 C9 C2 C# w: o: j
- // 读取中文字符并存储到数组中
' W" Z( h' l, X& M4 O" c3 E - while (fgets(chineseChars, sizeof(chineseChars), file)) {" v% n- `; q w$ q- a4 v
- for (int i = 0; chineseChars[i] != '\0'; i++) {
0 J# G c. V# E. C+ _ - if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {$ P2 n$ I# I' Q' T! M
- chineseCharCount++;
* Y% `7 `! O. `6 j& z - }
5 L$ U: v% V9 i5 ^) ~1 l; u - }. T3 {- |+ A: \: V. F
- }
, ~; m: W$ H' H+ {, `
% l/ k2 f4 @9 ]+ k' Z# F+ a- fclose(file);
% P5 T. x1 G+ I9 Z( V) D9 b% S
. @9 ?( T K' U3 l- fontListBase = glGenLists(chineseCharCount); // 为中文字符创建显示列表
1 e! K s6 e/ x8 S$ v
: F& f8 _4 O: J- {# c: O- font = CreateFontA(' x8 @* {* _( D5 ^* P& w
- 48, // 字体高度3 v9 K* r, ~ O& O0 w
- 0, // 字体宽度
3 k: v: K9 V8 D3 A7 c - 0, // 倾斜角度
/ s$ \9 v1 v4 y3 Y% I! n! z - 0, // 倾斜方向
, Z9 E0 _. j: y* G - FW_NORMAL, // 字体粗细3 {4 j" j% Z9 `) o$ I. ^+ j% h0 g2 @1 w& z
- FALSE, // 是否为斜体- s8 M. G% ^+ {9 G1 S+ x, ^
- FALSE, // 是否有下划线
$ T8 @+ m6 o9 v+ G. Q - FALSE, // 是否有删除线, B- M6 x3 T! b: c- K# C$ {5 t
- ANSI_CHARSET, // 字符集6 f6 m7 y$ ^/ m4 _0 s U
- OUT_TT_PRECIS, // 输出精度
+ U; `" z& [0 Y9 `( F& ^$ J - CLIP_DEFAULT_PRECIS, // 剪切精度
! T+ M% w# L6 p, V) M( D2 V3 q - ANTIALIASED_QUALITY, // 抗锯齿质量! v7 u/ x$ Y6 |- S( B* F
- FF_DONTCARE | DEFAULT_PITCH, // 字体族和字体Pitch$ C2 h* O3 J4 j* x6 `$ i
- "Arial" // 字体名称
9 ^& _( z! h/ D3 l1 K) G3 Y: B/ V" T - );
9 j! k7 @4 D* w; y
3 l1 m0 _* c, w- W( b( D- HDC hdc = wglGetCurrentDC(); // 获取当前OpenGL设备上下文的句柄
) {$ W% Q0 a: ~3 ] - HFONT oldFont = (HFONT)SelectObject(hdc, font); // 选择字体
" T4 h+ I1 D" v
7 k2 h* K* G- s ~3 f' r- int currentListIndex = fontListBase;! f4 k. p, {& z& F$ m
$ n5 R+ l- U" k# s8 J, J- // 逐个读取中文字符并创建字形位图存储在显示列表中, k" N- ^. p& u- X+ o( w) [
- file = fopen(filename, "r");' \6 O3 R+ V/ S1 A- p
- while (fgets(chineseChars, sizeof(chineseChars), file)) {
' J: j% W4 G2 U2 l& r - for (int i = 0; chineseChars[i] != '\0'; i++) { {- Q6 g3 ]' D, n6 h, M) j, n
- if (chineseChars[i] >= 0x4E00 && chineseChars[i] <= 0x9FFF) {5 v- g! z/ ]7 k7 \4 S
- wglUseFontBitmapsA(hdc, chineseChars[i], 1, currentListIndex);! w. {( N* A* X5 {2 U; j7 ]
- currentListIndex++;+ S& Y) ? x: n: H; H; i
- }2 d8 b$ z; Y! j1 r$ t9 \
- }. Y2 u5 U4 R+ P+ h
- }
1 Z* U, @8 j1 W) K - fclose(file);8 Q+ z2 \" \2 ?# ~
- |5 C4 E8 w g% D% J
- SelectObject(hdc, oldFont); // 恢复原来的字体* t+ x* J1 Q: Y4 L: }+ \. ^! R; v
- / [1 ^( { g/ E# p# m$ S1 F N; X
- glGenTextures(1, &fontTexture); // 创建纹理用于字形位图" f8 R- |( m/ H, T1 ~# P
- glBindTexture(GL_TEXTURE_2D, fontTexture);- `) l4 I: {: M9 T/ _+ k! i% C
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8 w1 K* R7 `2 p. ~* _) Y8 g - }& t3 |9 K* e' T
- ! `* n; R+ R" R; P4 y# s: Q
- void renderString(const char* text, float x, float y) {
$ X# V9 @/ J y# o, n+ } - glBindTexture(GL_TEXTURE_2D, fontTexture);
1 [+ r4 ^9 |: S3 \
- u! v1 W8 g1 B4 y0 k- glEnable(GL_BLEND);
9 u4 J7 U7 D! M6 v - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
& @5 r( O3 h2 O T' P/ Q8 L- p
' g2 I0 ]' x; L2 `- p) I- glRasterPos2f(x, y);
: w4 S# O$ U. W. i
! Q. { ]6 ~, Y$ q# J: w6 h, E- F9 O- glListBase(fontListBase);
% Y8 |( B7 X5 `* J - ( W$ ?: o! ^$ O: O# d
- glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // 使用显示列表渲染文本; k# `8 r( b% H( f/ S* ^' g
' d; m8 g$ X# `) C- glDisable(GL_BLEND);
, S& v9 T* x+ R% d - }
/ }# N3 y7 y! p/ E( w - 8 N% {% h( d+ U. V2 }$ {' P2 W
- int main() {
0 x( ]/ [8 K0 h/ A5 N$ ` C - if (!glfwInit()) {
& h$ w% \. O* z9 { - fprintf(stderr, "Failed to initialize GLFW\n");7 J( k" j5 {, m! Y# l
- return -1;; g7 n& w; v& [! n1 h+ I( @
- }. l/ j- A7 r" \
- - O- M( Z: t: \9 c
- GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);0 ?; v6 i* y! [
- if (!window) {
8 e7 H! f/ H; {+ J. d0 D - fprintf(stderr, "Failed to create GLFW window\n");
3 I2 r( ]/ \$ Y+ s. ~9 i - glfwTerminate();" Z, n% a. w- v" r; L" u" e
- return -1;
2 k8 Q0 Y+ B0 V5 P+ { - }- h2 a: ^6 p/ v2 M" J% [
3 z, I) k. }- w H* L: v- glfwMakeContextCurrent(window);
( F9 ~, h( Y1 R - glewInit();$ [4 |4 R; B) I6 y4 F4 ]
{9 j- b4 H3 l, g& I( Q- initialize("chinese.txt"); // 传入文件名
8 @- U9 P+ v9 Q0 A
! R6 `+ m+ \% M' \* l6 d- while (!glfwWindowShouldClose(window)) {& v' Z+ |7 t4 i* K
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
" J& y5 H, l6 S6 x/ ] - glClear(GL_COLOR_BUFFER_BIT);
" A& }* v" l V. r - ( t- V, ^1 y$ F% a4 I- n
- glColor3f(1.0f, 1.0f, 1.0f);
& n5 Q# z; a* a' g& d: z/ w - renderString("你好,OpenGL!", 100.0f, 100.0f); // 示例中使用中文文本
L7 y; {5 k, }+ Z7 c - ! v% h# V! v3 r: C
- glfwSwapBuffers(window);
& F& S$ g" m5 ^3 X+ {* B - glfwPollEvents();/ K+ E5 ~0 d+ P, j) H
- }/ b6 d& w: i# o& [
- 7 t+ G2 G2 P; u, s6 X
- glDeleteLists(fontListBase, 128); // 删除显示列表
0 D& r5 U* R$ n! \+ m" T' q - + w9 ^6 [4 Z& v; t1 e
- glDeleteTextures(1, &fontTexture); // 删除纹理
) P0 E3 l& S# V! N
4 v8 A. n7 r; a W, V/ z, v# d- DeleteObject(font); // 删除字体对象% m |! h) C- h% m
- * r% p# p# i/ ~) q6 {' t
- glfwTerminate();
; Y1 R. C* u( Z: i; D* ?
! r1 ~. z% F: Z, W$ X- return 0;! G7 E$ o1 {: @6 S
- }
% r2 I2 G5 {% u5 U
复制代码
- O3 o. j" S, C
' S" w' k+ o. d/ W
1 K. m2 ~6 j0 {* c3 E5 ^) N |