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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑 # @) C2 W  i+ c( ?- m  _' {, N

2 Q, ]" M' K' E! @& ^1 x$ [以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。1 ^$ c" k% |. }
本代码经过分析以及改写之后,将取代游戏原有的显示函数。
9 q; ~3 r+ D0 S6 U, J
+ D( ~' `' i" v1 p3 e& F代码详细说明如下
/ t- e6 Q6 `1 R1 ^2 D) p9 }, D5 j& B+ A$ j; \
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:
    " P( f9 v3 w5 u: }4 n
  2. * @0 A; C; N) k  l3 X- t! _' X' W/ @
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。3 p2 s6 G# z4 _1 t
  4. / g6 m/ Z0 Z5 F- V% I5 w
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。' k) t& ~1 @$ j6 _6 E

  6. 9 i4 v8 p  f9 z/ T0 c$ K3 y
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。
    1 a# R( N( ?3 d. _4 s" d& a

  8. 9 g  p7 p4 c0 I, z) p
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:& f8 r. A, f7 n  I: P" X! O2 ~
  10. 1 y; P) [# f$ y4 k
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。( i5 ^, U8 h1 C- _1 o- w

  12. - I, X, y" F6 ?2 B- k
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。1 C' S. _0 C8 U) b, V- ]% O, B0 k

  14. , x9 d9 a. v# U' p% N
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。
    9 p, Z2 z7 {  s! P

  16. 3 h  D( M$ f' N+ s: ~$ T  m
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。1 }/ G; ?) V9 Q, ?* t4 G3 l8 f

  18. ) u2 S. p1 S; L/ e
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。' U0 s4 }, ]4 z! ?
  20. - k. J9 O6 U5 \9 @
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。
      u, y0 Y) S5 G, E& {
复制代码
7 j: w4 B! z9 n$ u

1 h2 T/ K, B- ]7 g' W
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:2 Y( E3 Z1 l) o7 f, u' `
  2. " y2 C& [& z* K4 y( N
  3. 参数:
      }8 i  r6 K/ g( E( ~2 \
  4.   I( ]8 ?2 s5 I$ w* o+ T
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    * v, m" ]" L0 T4 q' P4 r+ s
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
    & I7 g7 \( U) L3 r0 {
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。
    & D3 Y7 I6 \% Y; Y: g- I
  8. 功能:
    * u; i- a1 J6 `, Y# T3 y7 j' O
  9. 6 Q0 X5 f2 V( Y. h) O9 ]  ?' M4 M: u
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。3 x- G3 @% d% t) [$ i
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。' w3 W  F8 u2 N! j
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。* \0 x7 W+ H5 `7 m: ^" E
  13. 使用示例:
    9 J0 ?- D, G. M+ r

  14. * M  U$ R& k: c3 ^- B
  15. c7 }+ J* }4 P: h6 |% q
  16. Copy code3 U" f9 C1 T% h/ R5 X- D0 R  q! \
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);
    . H5 H- s/ i3 O' N9 V
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。
    ( H8 c; V! X6 W0 f& f+ U2 U8 K
  19. " a6 P* Z9 F6 o; W. {6 X% H
  20. 错误处理:0 n& F* L+ c: `" E1 l
  21. # M9 ^3 M+ T4 V  U4 d4 I
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。! r) e3 s; [8 L2 Y: j/ t
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
3 D' k# M. x# U% n4 g/ `
! x# A% ^# E3 r  c8 [% k$ D0 [" C* Y
代码
, j, K9 ~9 ^0 l$ v6 e, ]
7 r7 a1 V' V9 a/ T$ k$ G

  1. 2 O; @. e9 ^, I

  2. 8 b4 N8 c& K" y7 g( N

  3.   |4 C! }( F6 c& b1 b
  4. #include <stdio.h>3 W& O/ {/ `/ Y8 h% i5 E
  5. #include <stdlib.h>4 ]- t. U" R; [+ }* L& J1 `
  6. #include <GL/glew.h>
    % S6 A; I) h- V/ ~. U
  7. #include <GLFW/glfw3.h>
    , ]: ?4 H) t) @3 L, E3 p
  8. #include <ft2build.h>
    3 K6 C6 b& {5 ?4 T* n8 e
  9. #include FT_FREETYPE_H
      n0 M+ T& \' v: A
  10. % D! k" X/ d% G( s& _
  11. // 定义字形数据的字节数组
    & a6 \3 b! e! q8 k! S
  12. unsigned char fontData[] = {
    ! s! @: c, ?" D' E8 d
  13.     // 字形数据的字节表示
    1 H. s9 g7 Q+ n, p
  14.     // 例如,这里可以包含字母、数字和符号的字形数据5 j" p5 ^. V* G4 H8 _
  15. };9 Q; e, K' W" e- a* z

  16. 9 g+ z7 d* j/ P2 b# Y
  17. FT_Library library;
    " b1 h: ]: K0 I5 _- j9 N' Z- j
  18. FT_Face face;
    $ `% N- }$ w/ F$ Z
  19. GLuint fontTexture;
    ( o" D; G+ L% D/ v# k2 N( u
  20. + R, r4 z+ `) J. o, g5 U, A5 }
  21. // 初始化FreeType库和OpenGL2 j7 k9 g4 P3 Q7 @5 s
  22. void initialize() {
    3 \) v% Y1 d& \
  23.     if (FT_Init_FreeType(&library)) {+ U! f0 c. i6 I/ U* H; e* s
  24.         fprintf(stderr, "Failed to initialize FreeType\n");
    * M1 k# }, D& b, w
  25.         exit(EXIT_FAILURE);2 J9 \4 y: |' |
  26.     }
    ; V9 J- W! U/ [0 s; g
  27. & t9 }2 V3 Y: k4 p
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {, u% O/ [% a* Q" c, H% _1 M3 J
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");2 l3 ?. Y4 b' Z( i1 C# @
  30.         exit(EXIT_FAILURE);8 U5 D1 J4 S0 f: N. h- b$ F
  31.     }1 D. e# }9 D' F

  32. 2 O4 P. |" X  y8 L$ ?+ c
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小( t% g  T/ w( ^: {& P
  34.         fprintf(stderr, "Failed to set font size\n");
    2 O9 `% O* g5 E$ k! b0 ^+ c* _
  35.         exit(EXIT_FAILURE);" c: O% C) u: z( @  b# h! \9 F# m
  36.     }
    2 ?* B; b3 a+ Z% e. D
  37. % n/ Y4 r% h. H+ {6 |/ R* @3 u) g
  38.     glGenTextures(1, &fontTexture);' S) i' W( F* t
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);7 O2 f6 K- _9 y7 n  z
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);! I5 B: [7 W' O8 s
  41. 4 E; N6 Y: K+ ?( R; a2 C6 j4 G* u; _
  42.     // 将字形数据传递给OpenGL纹理' ]& i' v( E# ~  P+ {1 m4 }2 u$ W
  43.     for (int i = 0; i < 128; i++) {4 y3 i# B7 C! D
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {4 d* e: V9 x5 W- m" F, h
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);
    * r3 o/ m/ L& Z( E; C1 C
  46.             continue;: O  V6 F2 h8 t# @2 w3 i5 Y# ], Y3 G" x
  47.         }1 @# q1 \  g" T5 E% K( s

  48. 8 J' l7 [4 r! F; a# [
  49.         glTexImage2D(8 O$ |& ^3 Y( ^0 I2 `1 H
  50.             GL_TEXTURE_2D," |9 d' Y! q  ^1 b5 g* w$ W
  51.             0,3 F4 v! _& a, D$ R
  52.             GL_RED,
    - o" s( u% F5 A! s3 W
  53.             face->glyph->bitmap.width,3 S2 c" l( {8 T5 `
  54.             face->glyph->bitmap.rows,+ H9 e3 ?4 Q2 u. Y# d
  55.             0,
    : g; i/ N( F6 }0 c! o5 i* \9 u
  56.             GL_RED,7 d6 U$ \( C, Y6 O/ b9 }9 r; N- ]
  57.             GL_UNSIGNED_BYTE,
    ( C* N# \- x) i
  58.             face->glyph->bitmap.buffer1 h5 C' L# Q5 V& G/ R: t
  59.         );
    2 s3 T3 Y6 r# x/ A  o. k
  60. 5 E8 p! l0 j& H4 g" |( y+ A5 Y
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    , Y; X. j. M! C7 A. R9 U0 R5 F
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    + z. U; j2 {: Y
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    & ]& K/ I9 ]0 q2 Y& N$ Q
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    / o& e* u5 b7 O& o% V: T- d
  65.     }4 A. P# \; l( p4 W6 d  j* {4 w
  66. }
    & v) |/ k  H$ ^4 x
  67. 2 f* E4 E! @2 I- Z' T
  68. // 渲染字符串
    . @: W; J4 i& X. [
  69. void renderString(const char* text, float x, float y) {$ S" @: t, [+ C
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    ! p' W  l* z- X7 `) J7 \9 J

  71. 7 V- I" T1 t# ?9 J% l1 u
  72.     glEnable(GL_BLEND);* w; i4 W! Y& j( d2 {  [
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    - P8 {+ |+ I. ?6 R
  74. 8 h& f3 X3 _) ?1 j0 R4 A/ ~7 [
  75.     glBegin(GL_QUADS);
    2 b+ D& W/ s3 S$ W0 p. J, W# n
  76.     for (const char* p = text; *p; p++) {" T" [4 h; g, ~5 r
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);3 h8 }; Y2 S/ A6 F5 s
  78. " j) f: v9 @; z7 X
  79.         glTexImage2D(- l# i0 X* Y- z1 W& E
  80.             GL_TEXTURE_2D,
    " p5 X  A1 H# p
  81.             0,
    - \/ }# [* c/ A
  82.             GL_RED,# `$ a4 ^) D2 ^  g, \, ]  C2 g2 K
  83.             face->glyph->bitmap.width,& B5 ~% @7 R# x4 n) M
  84.             face->glyph->bitmap.rows,
    ) a5 c3 m$ Y1 T- _+ m8 }
  85.             0,
    4 @( ^4 L. E& Z6 s- X
  86.             GL_RED,6 r, X3 N$ ?( D! h! m$ ]" c2 g- [! o
  87.             GL_UNSIGNED_BYTE,; }5 e9 Y, Y' B; A0 T) c/ d
  88.             face->glyph->bitmap.buffer2 u+ u; J6 A* Q: F2 X: S
  89.         );
    2 \7 T2 {, w+ `. z4 r& D5 u4 ?; ], _. l
  90. ! a4 f: v' l: c' F0 G' p9 x
  91.         float xpos = x + face->glyph->bitmap_left;# V; Q/ C( t  Q" ]! t  }
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);
    $ v8 F5 k  X+ ]

  93. ; O* A. r2 ~' ~( k2 c* M, |4 K
  94.         float w = face->glyph->bitmap.width;
    % P5 d& L/ O- Q) U* B
  95.         float h = face->glyph->bitmap.rows;
    / ?' d4 b  c7 x7 k0 L" o# [

  96. : K) P7 Z1 q1 U* l3 r- U
  97.         glTexCoord2f(0, 0);, {: U: {+ u' g9 j3 I( ]1 \( u
  98.         glVertex2f(xpos, ypos);
    ! ]2 E0 Q  Q0 b' |8 u

  99. , j4 ]! t& O2 j! G
  100.         glTexCoord2f(0, 1);' ?! b5 v5 o4 G( N/ ^
  101.         glVertex2f(xpos, ypos + h);+ _9 J8 ?7 h; y0 a- P7 M1 c3 l2 X$ L

  102. - h$ D  h5 A% P( }
  103.         glTexCoord2f(1, 1);) x5 C2 B5 ~" r; z; r( P
  104.         glVertex2f(xpos + w, ypos + h);
    ' |8 m8 m* `+ ]7 I

  105. / {" F! f1 M* U' J; V! \
  106.         glTexCoord2f(1, 0);
    ) C; X# ~! A( Y1 w# B
  107.         glVertex2f(xpos + w, ypos);
    7 q3 |2 x+ n6 S

  108. 7 `2 z+ S- W; F2 {2 e( w' _
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距
    * T& a& W( y, S. I& D
  110.     }
    : s5 @9 n. d( G# q. D
  111.     glEnd();# `: [4 {1 A5 |5 r
  112. 2 ~+ x  y. I. b
  113.     glDisable(GL_BLEND);. @( v+ K. j- @# }2 s$ Q0 G( d
  114. }
    + D) u0 y" _5 o' l5 `2 c# c
  115. / {; C/ u/ J& `0 y2 t
  116. int main() {
    9 R/ x6 V) e& X. X+ g% _6 @
  117.     if (!glfwInit()) {8 z* }( {' l5 c7 \' m
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    % Y" V# [+ b; B3 V/ i% m
  119.         return -1;
    + f6 o5 r- E* ]+ x& p
  120.     }
    9 r# k. b: H7 M) N
  121. ! z5 u3 ^+ F+ X1 ~
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);- G3 l+ J2 ]  q% f
  123.     if (!window) {
    - Z& H, s, d: ~8 Z; M
  124.         fprintf(stderr, "Failed to create GLFW window\n");* a, m+ p! \, r! j
  125.         glfwTerminate();; A# [# a' b4 i$ R* O+ e; N! d2 H
  126.         return -1;
    . ^( [  x# ]7 |& m5 Y% ?" P- ~
  127.     }
    , u7 x! v- s, o& c# N! R& @
  128. 9 e9 l; C, A1 x! ?! p3 b& ?% X
  129.     glfwMakeContextCurrent(window);
    3 u5 e3 t1 v2 ^7 r9 z
  130.     glewInit();" Z5 d2 ]' H7 f+ ^% [2 R; u. ?

  131. , A+ _$ O( X! n  e" ^6 E2 `9 x
  132.     initialize();8 P# P7 S3 V) ]5 N1 x% i% q! F

  133. , N& W3 j+ Q& [& m0 S
  134.     while (!glfwWindowShouldClose(window)) {
    , j* p! ^% k) r  d( L
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
      J6 ^$ ]. j# z1 @4 z) F
  136.         glClear(GL_COLOR_BUFFER_BIT);) _0 G; m/ [- ?, G4 m
  137. , M- G/ `* V$ U" @3 N4 E
  138.         glColor3f(1.0f, 1.0f, 1.0f);$ z/ w$ \5 J" |  \& k
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);
    ! X2 T; B2 e# t
  140. 4 N8 A* m0 L' W( p
  141.         glfwSwapBuffers(window);2 o& N. R. T- n
  142.         glfwPollEvents();* x1 h( h4 @+ M) j
  143.     }
    . ^. _, Z" s/ C! w

  144. - D1 ]  V- X( L/ Q. `
  145.     FT_Done_Face(face);+ l, i! h. O' K2 y: M' l
  146.     FT_Done_FreeType(library);) ~% n; _  u3 K! u
  147. 6 A! D$ B' [$ I7 x4 @
  148.     glfwTerminate();% J, A) E5 A; O0 U3 I" a

  149. 0 B. Y& Q- [+ Z6 M0 J! v
  150.     return 0;
    4 n, a/ }  Q3 O
  151. }
    + C1 G5 w8 u5 y4 ?
复制代码

) \% y% ^- @9 C5 {) p/ p+ i" n
9 t3 `& `+ F: g( }4 |5 X  ]
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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