设为首页收藏本站官方微博

建议 【Opengl游戏汉化 #5】 尼比鲁:秘密年代 (NiBiRu)字幕显示函数修改2

[复制链接]
查看: 355|回复: 0
打印 上一主题 下一主题

[建议] 【Opengl游戏汉化 #5】 尼比鲁:秘密年代 (NiBiRu)字幕显示函数修改2

跳转到指定楼层
楼主
发表于 2023-9-6 15:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

【Opengl游戏汉化 #5】 尼比鲁:秘密年代 (NiBiRu)字幕显示函数修改2

本帖最后由 shane007 于 2023-9-6 15:32 编辑 " ~4 Y3 }, J6 l& P7 v

# ~2 M+ Q& U( L以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。
) z6 M5 j2 t2 r, {本代码经过分析以及改写之后,将取代游戏原有的显示函数。
1 m# N# _% w5 j6 R1 Z2 m* _
( V& u( A( J0 x! ~! T* x9 C9 N5 x5 ~代码详细说明如下
6 Z0 S. ?4 p8 @7 f% |+ D# [5 j- @# h" O
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:
    3 W/ r5 s+ A2 K" k+ I" `

  2. 7 \% t6 N- P2 S" `3 _
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。0 B$ M$ q& K0 j; l$ a

  4. $ v6 f; U! x/ E# @
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。
    2 |% s( h  X8 [5 s$ B

  6. 2 G& d* [/ B9 R  v5 d
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。9 ?4 ~9 i5 y6 E
  8. % G. y. z# W& @, b& T
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:) K8 ^! ?0 X3 x0 @! a

  10. ( }; {' b, O. ^$ G
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。
    0 i  y/ X7 F& v. X' D8 h

  12. * E5 w) I! p' q$ H" i* k/ E
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。* X2 P3 ~+ X; B; N9 Z# Y7 _7 n
  14. * j$ W$ F! z# r: u# P) y
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。
    ! u7 M0 s8 L# w7 X& i2 p
  16. 1 ]1 p; @6 B+ u' \9 B7 ?, J0 z
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。7 F8 x* `# ]/ a1 G! V- D
  18. - E9 \1 Q) {9 K2 @' c
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    ( d4 W2 Z; S4 h' p) V2 B
  20.   z6 A" c8 x8 m, J; E
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。
      g. D3 R/ {; G5 O
复制代码

- M) M& m: O  J  E- {; Y& U; u( W& }
' @! S0 b/ g  X$ x4 q6 `
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:
    2 E8 c* N. d! A- J4 s* Y

  2. 4 s5 E( }2 g# L- s0 C* j5 ?
  3. 参数:4 T% N! W  _0 u' u- R4 D: Y
  4. 4 ]0 H$ l" i: v4 ^
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    - ^& Q5 D3 j6 |. ^
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
    $ G" x) A: c6 L1 A& n9 H# E& r
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。
    $ L) G- v  E) N" |
  8. 功能:3 q9 l' H. x4 Z0 T

  9.   k/ _2 E5 G) q6 a
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。3 j2 F/ T, t  `% g: [0 T
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。
      D0 C) Y: t0 z; v+ u$ E3 x
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。
    / M4 y0 e1 ^5 J4 E  K
  13. 使用示例:1 U. W! R3 w4 |! \; t& R0 w( ~( a, a
  14. 3 ?4 X7 {8 n) v
  15. c
      F, ^, z; N; \, ?
  16. Copy code6 h+ Z% [- h6 b2 [' q$ L
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);
    ) q$ G( x+ O0 V8 E
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。4 X% ?. J; L0 Q8 V
  19. 2 u( _6 ~! B" I4 S) I! a  p
  20. 错误处理:8 i1 E5 j( I! c! B% S: a
  21. : Q' @6 E, [, X
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。
    2 w) @, [7 B" v4 z% J1 u1 n
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
6 h  b/ e1 P& U5 z

$ m" e: M# |. o8 B代码( Z& _0 x" `5 e  ^7 _0 z" g6 a

1 X1 U- \7 s  U

  1. ! j! f9 l' V, j
  2. ' S) k* [1 w7 g+ l: K
  3. 3 n, S/ e$ a7 E7 _0 c8 b' k" e
  4. #include <stdio.h>
    8 J( r+ R' ?0 V/ B! x7 w
  5. #include <stdlib.h>: E% X, p" h0 ]2 U2 [7 S% c; A
  6. #include <GL/glew.h>
    ' P/ L- O# q+ l& a, P
  7. #include <GLFW/glfw3.h>
    ( A& \! D2 K' f7 e7 N! g
  8. #include <ft2build.h>
    1 D4 v4 E$ `, ^" O- w
  9. #include FT_FREETYPE_H
    : }" I( I8 A. ^

  10. ; N, n- |4 V. `9 i
  11. // 定义字形数据的字节数组3 z& T- L- y* M% Z7 c0 W: D
  12. unsigned char fontData[] = {  s/ E4 I1 j/ y+ o
  13.     // 字形数据的字节表示4 |3 U- D" y9 I$ e  V
  14.     // 例如,这里可以包含字母、数字和符号的字形数据- i) D: k" `% T3 l- u4 s7 Z& U
  15. };7 W8 P; f# k9 v  w. B6 O6 L
  16. $ P- e( [4 {- _+ i
  17. FT_Library library;0 o/ }0 ^, W5 L
  18. FT_Face face;
    & M% O# Z7 Q2 k7 P$ G
  19. GLuint fontTexture;
    % Z1 ]* W7 L9 c7 C0 w# V

  20. 2 q4 U7 \7 T$ \# O# p. ~% c' @
  21. // 初始化FreeType库和OpenGL
    # K( e5 k! E( v1 n1 |+ @" t
  22. void initialize() {# F3 N9 W  y, J4 Y8 B
  23.     if (FT_Init_FreeType(&library)) {9 v( x! R+ @$ `; j; \) W
  24.         fprintf(stderr, "Failed to initialize FreeType\n");7 s- l$ a) F& L
  25.         exit(EXIT_FAILURE);
    0 O( D2 A" u/ M% Y2 d
  26.     }
    7 g4 d. g- ~" |, C

  27. 6 ]& A$ n2 V) b* \/ h$ h+ v- P! k
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {
    1 V) B9 R; ?' a( I, O" W
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
    3 N( e. L6 ?( r# i* J% I; _0 O
  30.         exit(EXIT_FAILURE);
    8 D2 |3 w' j: E) D
  31.     }
    ' r; P  U/ }, }; }4 y1 d
  32. . @$ E& N) u+ o
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小
    3 |  q8 X- g, p3 Z: j
  34.         fprintf(stderr, "Failed to set font size\n");
    : r' ^4 [2 B* B" x7 e4 b' g; E( i8 _
  35.         exit(EXIT_FAILURE);8 ~- U, i. n* a1 C+ O
  36.     }
    3 y  e. Y$ @2 N+ j! A
  37. . ?' I5 m3 Z( E( F% f
  38.     glGenTextures(1, &fontTexture);) m4 O7 R+ e# \6 `1 E
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);) U* F! F6 U+ o3 Q# \9 I( L4 {- L
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);# W/ z, `" Y9 h

  41. 7 ~+ h# R+ [6 r, `8 H
  42.     // 将字形数据传递给OpenGL纹理
    " X% j' X8 h4 e, y* ^( c5 s3 n
  43.     for (int i = 0; i < 128; i++) {
    1 |# C1 ^$ c8 b. P
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {6 j- @$ ?3 O3 D' m
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);; J" f6 G  {8 E
  46.             continue;3 \* G# y& _; Y% H0 Z; }* D4 u
  47.         }, a. S7 d3 C, u! I6 o) |: r

  48. 0 w# Y2 C  P6 s$ c- S8 @
  49.         glTexImage2D(
    , L8 l8 C3 B9 J4 b
  50.             GL_TEXTURE_2D,
    % Q! g  V# l( w) U
  51.             0,* Y+ Q! S6 a! j& P( ]. w
  52.             GL_RED,) M: R0 l& [- f, e' t: i* ^7 l
  53.             face->glyph->bitmap.width,* V  X5 z# |* I, }
  54.             face->glyph->bitmap.rows,
    9 ]8 ?' y; N6 G6 c6 z
  55.             0,
    - j& E% B& m# w
  56.             GL_RED,' |# Q6 E9 m- f# \4 k5 O
  57.             GL_UNSIGNED_BYTE,- j0 r: ^. u3 {8 X6 e5 y
  58.             face->glyph->bitmap.buffer. k$ c3 J( B, x2 u8 q
  59.         );. q# c! c+ K; J0 g4 u! Z: D

  60.   J$ P: C; B! S- N% M
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);) J! k* y  E# r: u6 A
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);- o9 _8 U/ ?+ P5 v4 P! m6 I
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);6 ^$ J- b7 @. k' }
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    0 H# n8 ?  u4 }
  65.     }
    # j& W+ ^" \8 {$ l/ `  z& C
  66. }* s+ D; d# l, U* M
  67. : }8 P$ Y8 n- B0 A
  68. // 渲染字符串' G, G+ v0 n/ v+ G1 v
  69. void renderString(const char* text, float x, float y) {
    ' s+ f7 Q" V, j
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);, N: a: Z$ J# G3 v

  71. , Q. t6 l: m' D$ P
  72.     glEnable(GL_BLEND);9 ?, b# j2 h+ L% Z1 ^
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    9 F% k. M7 \5 t& ~; a9 q

  74. % A$ Q8 @' C: o1 m' X
  75.     glBegin(GL_QUADS);
    & b) R# t5 T# A9 C- \4 F" G, H$ |
  76.     for (const char* p = text; *p; p++) {
    8 Y& c' o# ]7 p- y1 ]# Y
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);
    , @4 x" n! d$ b7 S2 G: A

  78.   I% ]- j* i; m
  79.         glTexImage2D(
    1 w2 i, \; i2 M, g0 o+ _
  80.             GL_TEXTURE_2D,
    0 q: Z9 n: P4 f' T; ]6 U# ^" `$ k3 j
  81.             0,
    . {* T, J& k- n2 @4 u- S! Y1 {
  82.             GL_RED,7 `0 A0 B4 O# F! x# t6 t: [* L% P
  83.             face->glyph->bitmap.width,
    * m$ O2 V7 D/ t" Z: x7 ^) ^% \
  84.             face->glyph->bitmap.rows," Q2 F! G. m9 F* A7 r
  85.             0,% H: B/ u+ p# D2 N& j4 X% T
  86.             GL_RED,* _% B  o" F9 g) O; p
  87.             GL_UNSIGNED_BYTE,
    0 X7 }" l" E3 h1 P& ~" ~
  88.             face->glyph->bitmap.buffer
    5 _$ Q8 _6 S5 c8 W& v( c
  89.         );: I( t9 b" x" h

  90. & x# A- e& r8 a! p. |1 K  J6 ^
  91.         float xpos = x + face->glyph->bitmap_left;
    0 N; @4 R3 t6 g7 T  @
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);* D$ A: x1 \& o% K: f1 |
  93. ; p. S( z* c: ]! \, l1 T+ @7 ^
  94.         float w = face->glyph->bitmap.width;
    4 A& h: I6 w' _6 N
  95.         float h = face->glyph->bitmap.rows;" T: L8 T* |3 [" N

  96. 4 b# u- s6 U  ^) E2 Y1 y
  97.         glTexCoord2f(0, 0);
    7 D+ D: A+ B0 J# `: R3 ^
  98.         glVertex2f(xpos, ypos);' F3 G7 y# A5 d/ U  ^

  99. " b7 Q2 O8 x0 R+ ^, I* K# P8 A. L1 f
  100.         glTexCoord2f(0, 1);
    , Q% x* C% L% i5 V0 m. F& w4 I8 t
  101.         glVertex2f(xpos, ypos + h);
    2 B" B! ~3 _) I) @1 d  n! _

  102. 5 p5 {8 {! Q* Z5 C
  103.         glTexCoord2f(1, 1);
    / a% {8 k7 W# G  D
  104.         glVertex2f(xpos + w, ypos + h);
    3 a( G5 K* c/ q. u

  105. % Y0 n# b* D7 ]6 k
  106.         glTexCoord2f(1, 0);
    % y8 u& A$ Z2 L. z& p
  107.         glVertex2f(xpos + w, ypos);
    7 P  D- M; V' E0 D, H. ^/ g
  108. 9 ]0 F! E1 U2 E3 e. K5 F; N
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距
    & d/ P/ V4 \2 G* g5 A. o4 f
  110.     }
    + x% c+ v/ v5 |" ?2 H0 |' `6 i/ D' A$ m0 I
  111.     glEnd();: t( U2 X4 \; B# O! _) ?" I

  112. 8 l% x- G6 W4 n; o, w4 {: i9 w
  113.     glDisable(GL_BLEND);1 r- C# }4 Z9 t: P. L
  114. }5 X* l' \' ^& H( P1 V
  115. 0 u2 C! o. R; J0 `: k
  116. int main() {
    % D( \+ G, u$ S8 N/ s) [
  117.     if (!glfwInit()) {
    $ v7 n+ X( t7 o$ F- `
  118.         fprintf(stderr, "Failed to initialize GLFW\n");' W  V7 e  `& ^3 }; n7 U# W
  119.         return -1;6 d1 C& X  G, W/ f. W+ L* c9 Z
  120.     }! z0 Y: V1 U/ B

  121.   h, s  B2 u8 T1 b/ @- M
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);7 A8 @- E, v0 Y
  123.     if (!window) {4 z9 \/ Y' K! B' ?% F& H9 [; M
  124.         fprintf(stderr, "Failed to create GLFW window\n");8 e2 T) i" R9 M
  125.         glfwTerminate();
    4 l3 z& E+ t) S6 p
  126.         return -1;
    ; h) y6 |- I6 K9 v: E
  127.     }& c; a! K# D8 v4 ]
  128. 0 q0 J( A+ b0 s. m
  129.     glfwMakeContextCurrent(window);1 t: S5 Y9 O$ \8 _  A7 p3 l. `$ |0 N
  130.     glewInit();5 ^# Q" ]$ q$ ^' |  B
  131. 3 o( Z( v! _8 u' K" V
  132.     initialize();* o2 R7 t' e5 M; f' G
  133. ) _) I; f  U( r/ R$ |: D4 z' b
  134.     while (!glfwWindowShouldClose(window)) {1 e6 L( _- d6 v
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    / V/ f: N9 I- ]  B1 c
  136.         glClear(GL_COLOR_BUFFER_BIT);+ m$ J% S& d( f9 L: U

  137. 9 J; q1 ^6 V- d
  138.         glColor3f(1.0f, 1.0f, 1.0f);0 x# H2 o  \( s1 \' }
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);7 B1 _1 O5 r( K8 `: g) s( T
  140. : \$ `! Z* y# ?! O
  141.         glfwSwapBuffers(window);0 s( n8 T; f" h$ L8 i
  142.         glfwPollEvents();* }+ U7 V  A  i, w
  143.     }
    # F; D; i, K5 o% H% p/ O

  144.   @5 N0 l7 [6 e) g+ N* s; ^
  145.     FT_Done_Face(face);) S6 e+ w. z6 S- F; k6 ]1 t1 ]
  146.     FT_Done_FreeType(library);
    ; i! b: w! x) F

  147. ( ]! ]" n( |6 a% y
  148.     glfwTerminate();
    9 ]2 N% W% C+ K$ [; y6 X

  149. 2 b+ u, l* U% u/ Z2 T- J' l1 K
  150.     return 0;
    , k5 \4 z' R" C( B4 V
  151. }
      |# N( a/ I; I+ t  m
复制代码
# r6 S2 u" M, |4 s! ^& _
1 V8 @) X" C& I( ^
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 很美好很美好 很差劲很差劲
回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

冒险解谜游戏中文网 ChinaAVG

官方微博官方微信号小黑屋 微信玩家群  

(C) ChinaAVG 2004 - 2019 All Right Reserved. Powered by Discuz! X3.2
辽ICP备11008827号 | 桂公网安备 45010702000051号

冒险,与你同在。 冒险解谜游戏中文网ChinaAVG诞生于2004年9月9日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

快速回复 返回顶部 返回列表