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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑 : X$ m1 o% F8 Q. b- Q1 O7 O
" r6 z% r7 Q( ]
以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。
: u  J! O: D' H0 \! y3 ^- R本代码经过分析以及改写之后,将取代游戏原有的显示函数。
8 h% o8 ~, U* I' Q. q2 N" r% L- G# B$ u( r' @, N* X5 a
代码详细说明如下
! D5 e) \8 K/ C! @1 {
! j9 c% l; w. S: T5 d
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:
    ( F' E# L  X" o) y6 _) a: `

  2. / M# D9 h1 E9 \7 x
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。
    4 L" r' T) x$ I- H
  4.   t* D% M0 `% r
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。, n. v8 M0 v" T2 h! Q, D( T

  6. % A" G# h& P1 t% h1 G
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。2 y5 t& V# m7 A* ]
  8. 2 `+ s" ^8 t( t4 O
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:$ A7 B& i: I0 T  o9 q
  10. 3 C0 a5 ?- h; W3 p% {
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。7 y5 a) F% l. O; g4 k$ W! X, e" l
  12. # s! Y4 l+ s9 m) F
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。
    8 U: h# V3 e$ M0 t! O8 ~9 w5 e8 b5 ?1 s

  14. & U! i; B; ^7 ]! H" E
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。
    * V. e+ s7 D* o; f+ S! f4 [* n

  16. , N, J0 z. [& s$ O' g& ~: Z
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。
    0 Y* {6 ^( @/ @7 c7 N0 c+ I3 K8 ~  K

  18. : W7 G: d$ c+ W
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    ; d! ~8 o. E% G3 L3 C

  20. 8 f! x1 d9 S* b5 r& u
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。* p3 J6 Z' n* N
复制代码
5 }" k& f8 Z; W. O1 X

( g: E& E# F. _, h, k
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:7 D& ], s, j+ @. i- k2 I
  2. - W7 ~) V4 p5 K! T0 K3 p
  3. 参数:: ~) f/ i8 Q- V4 k! P% J

  4. ' r% I8 h; d$ V
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。# I8 _6 ?; Q" U0 N. K- y, h) N2 q
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。/ Q4 p, U3 t3 a) E3 X4 I" A" _
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。. U' h9 V9 h8 D( S0 \# C6 K
  8. 功能:
    + W2 \# e; E1 \; C; [

  9. - E+ c2 k. `) n3 @
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。& a& f9 f# }8 y; s2 P, A; B
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。* v" {) u( l7 z
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。
    . j3 ~4 L$ s, E* Y6 @* z6 I- j5 O5 p% Q
  13. 使用示例:
    1 O5 ^( ?8 W5 c
  14. : t* O: M/ T8 C) ?6 d8 p+ v3 I
  15. c; f* u2 m) B( V) g; J' N' `5 A0 E
  16. Copy code
    3 ~% g9 @9 u! `2 o3 I
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);
    9 H' p; Y0 E7 m- M
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。
    - l9 @; m5 N& t& h/ c6 m5 ]4 ^

  19. , ]  s9 B" k* g% Y; Y# Z
  20. 错误处理:: w3 _5 I, }* `2 ?" F8 F

  21. . y8 }$ n: \% Y3 k. t2 L# W) o% ?
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。
    # i2 `6 A% l/ R# S
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
/ d/ F/ |1 a. _/ T' E+ z& K

! G6 I- Q& w  R  _5 R" y' L代码
2 p* J8 ]3 B) E3 K* B* d
* X  E/ M3 C$ `
  1. & w' o# l! D, F/ M

  2. . y& C$ S# y2 ]0 @3 ]6 ]' L  ^

  3. 2 k1 V; |+ F3 T  h" O# B6 V5 B
  4. #include <stdio.h>* M- {% z% u' C: i( k# z9 [
  5. #include <stdlib.h>+ j9 x3 G4 o/ m% P1 n7 g: i. U. s: _
  6. #include <GL/glew.h>3 u0 ^7 F3 p" O1 |& K; Q
  7. #include <GLFW/glfw3.h>
    & c$ M* N8 l+ V1 p9 e6 m
  8. #include <ft2build.h>7 S: b$ c1 \9 C+ l* Y5 D( R! s% K
  9. #include FT_FREETYPE_H
    - H& V, F* |9 j

  10. # [3 G% ?5 O  X" ~: y
  11. // 定义字形数据的字节数组, H" G0 D' d& t6 B% ^# T
  12. unsigned char fontData[] = {0 p% C; |" p* B) Z' z; u4 l
  13.     // 字形数据的字节表示
    9 k6 S9 M" i! K; L+ B
  14.     // 例如,这里可以包含字母、数字和符号的字形数据
    # o8 `1 F$ u$ C% Q" G% e2 p1 F
  15. };- o- P! M- ?7 C/ e% `/ j; r
  16. - b/ j, I, q# K. b1 D
  17. FT_Library library;
    & Z" C, x, V/ a$ F3 D3 \0 t  P% M
  18. FT_Face face;9 D8 X8 E1 W4 i' Z( }
  19. GLuint fontTexture;
    0 `3 g- e4 D0 D, d
  20. - B4 h) \; X: o
  21. // 初始化FreeType库和OpenGL8 C" _6 F4 T: W
  22. void initialize() {
    ! X' R+ r* F3 G7 q  ~6 m" Y
  23.     if (FT_Init_FreeType(&library)) {
    6 E5 r0 _. Z7 ?, P- H) X( _
  24.         fprintf(stderr, "Failed to initialize FreeType\n");
    ' l8 J8 y( N: _$ c. [! h4 S
  25.         exit(EXIT_FAILURE);
    0 V6 L9 a+ L( a: G& G
  26.     }- p: O" v4 u8 [0 W) |

  27. 1 S6 `/ h- v& j( J
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {& H. Q: h1 y" v: k3 H/ A! g* v
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");3 z; w; S) a& T0 G5 U: u! s
  30.         exit(EXIT_FAILURE);
    6 s' _+ \6 B4 M0 h
  31.     }
    ( ]& v) ^4 M+ {. _. `! R: m: x
  32. 6 [2 [7 ~3 d1 N7 A% c: g
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小* h& m: [" p1 x- ]( L  ~; L
  34.         fprintf(stderr, "Failed to set font size\n");" D0 Y) `0 x3 v* I! Z6 K  ^
  35.         exit(EXIT_FAILURE);, a& Q" |( b/ ]
  36.     }
    2 g7 C& I, X. W( G2 c* O  k& M
  37. $ t& O& |) I& p) f
  38.     glGenTextures(1, &fontTexture);) M  m, i- D4 r' [
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);7 C; U* B  q, b2 W/ f7 z
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);7 x5 k7 o) d4 u% H" F0 X& Y

  41. / j/ a4 \9 e+ x+ U1 f0 F
  42.     // 将字形数据传递给OpenGL纹理
    % K! ?) X. ]9 X5 L% {
  43.     for (int i = 0; i < 128; i++) {  O% n3 t) F! N
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {/ M  o+ O( z/ G' j
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);6 z1 z7 z3 |# V- U: W/ s& @1 F
  46.             continue;
    3 v# K+ B; }2 a5 B
  47.         }# x. c; Z# W& ?8 f7 N9 `

  48. 0 U( x% R. e8 b# B  U
  49.         glTexImage2D(/ \  x1 W0 p7 q1 Q) h' O$ l$ M: P
  50.             GL_TEXTURE_2D,
    6 k5 `) d9 y+ @. I7 X9 t
  51.             0,& p( T; Z; i  Z) y$ J, N
  52.             GL_RED,3 v  H) {% _3 c
  53.             face->glyph->bitmap.width,
    9 P# B7 u1 K  d( @
  54.             face->glyph->bitmap.rows,
    / N- N0 x7 B" M6 l
  55.             0,- H* x# ?* o3 D1 a# n# W5 p
  56.             GL_RED,
    + c) M5 `- [, |! v
  57.             GL_UNSIGNED_BYTE,
    7 D* C% a$ k0 c8 ^% u# l5 @, [  N1 y
  58.             face->glyph->bitmap.buffer3 d. [9 w* r% I
  59.         );
    9 B: W5 U0 Y9 ]: V* B7 l
  60. " z: t2 }0 k5 I1 N* Z+ [
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);. v( R3 E; \4 ?0 m( Z
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);' v7 Y5 y& p7 `  t
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    , |* x1 g3 ?# d; h" R6 I8 K. E
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);+ w0 s$ _9 O. o5 M4 p
  65.     }
    * ?+ v; O# A/ O" `; l
  66. }$ t9 ^+ ~" @7 G, Y/ Y
  67. ) `, H: k8 w- ]
  68. // 渲染字符串
    7 y: O/ |% b1 P" Z
  69. void renderString(const char* text, float x, float y) {
    1 }* j0 H0 Y  }3 O& Z- r0 V$ ~
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);" t8 [8 _. G# M8 D/ k9 l

  71. : b! {9 ^" h* f0 C/ x( N& |8 M
  72.     glEnable(GL_BLEND);8 \! J& Z& o) F6 S3 }; z) k5 L
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);6 E* d" E5 w8 K7 x
  74. , w6 E# P9 @! O# e- U$ P* L% ?) F) k
  75.     glBegin(GL_QUADS);6 O1 ^# H8 D2 }! l8 t( N) |1 W
  76.     for (const char* p = text; *p; p++) {% U$ d5 i( u, l0 v
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);- |* x) D1 \* J* T  G
  78. & r, s7 U: |* H1 Y% p9 J
  79.         glTexImage2D(
    7 s( m; C6 a6 s. i8 W
  80.             GL_TEXTURE_2D,
    & Z% g# K* {: g- {
  81.             0,) F$ b* y+ g' J" Y8 v
  82.             GL_RED,
      b3 P" z  ^  t$ o1 L9 E3 R
  83.             face->glyph->bitmap.width,
    ; l4 t3 V1 Z0 o+ C
  84.             face->glyph->bitmap.rows,
    * p* v9 @5 h% d9 J0 a
  85.             0,
    ; i3 I; y! L8 O- p2 I  B- w
  86.             GL_RED,
    9 C  A- O7 X; S0 b% Q- S2 }+ @
  87.             GL_UNSIGNED_BYTE,
    . M/ Y% q6 l6 d0 T3 |" N
  88.             face->glyph->bitmap.buffer2 G; u! b* K$ P; `
  89.         );( Q" W6 U, g) f( o& Y

  90. 4 y! M7 P2 m9 j& I2 P
  91.         float xpos = x + face->glyph->bitmap_left;
    # a/ {2 ~) j3 ]. [  U
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);- d2 K0 o. K2 M5 d4 ]/ ?
  93. : J. t" ?5 R/ I/ a' Z+ [4 ]& i/ Q
  94.         float w = face->glyph->bitmap.width;
    6 X2 e9 y0 v9 w4 C# r$ S( [% N
  95.         float h = face->glyph->bitmap.rows;( m) Y7 x# x8 ~: K) G  `

  96. $ V0 a7 ]" y3 }
  97.         glTexCoord2f(0, 0);
    7 H$ I' S6 O) u/ `7 R' M
  98.         glVertex2f(xpos, ypos);
    5 x. k: Z* i0 n" L" Y7 l
  99. ; v* \& G! V2 j* a% f% @" L
  100.         glTexCoord2f(0, 1);
    , ?9 _) ?3 p, u4 A
  101.         glVertex2f(xpos, ypos + h);7 _. \( z  ^( C- H- z

  102.   G% w' l. S$ `# d% _1 ?5 E' |9 V
  103.         glTexCoord2f(1, 1);" |& Z2 d0 L  x' c; J1 P1 x: ~
  104.         glVertex2f(xpos + w, ypos + h);: f) Q4 R$ J9 m1 }

  105. 2 }/ G/ ]0 U5 C- V# X% A! l, {
  106.         glTexCoord2f(1, 0);3 O: H8 _$ R6 k* o
  107.         glVertex2f(xpos + w, ypos);3 g* z- M. ~$ ~  m8 {+ K

  108. + W5 x' H7 Z, O- t
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距) o' ]: }$ s2 w: g
  110.     }
    # u# |" l9 o. j" x) }
  111.     glEnd();! T% v8 J% G7 A7 c. N: |( z
  112. , S, ]  U6 v+ @9 w. T$ X6 C* P
  113.     glDisable(GL_BLEND);/ @! _' w# k: j( |" O; {" b
  114. }
    " N# m" k/ R7 F% k# Z- v' K
  115. 6 T: g+ \9 |! w) ~2 f( p
  116. int main() {/ S' @  ]- T  o" ?3 s* ]1 r0 K. S$ |4 t" a
  117.     if (!glfwInit()) {
    , K1 ]% ]' a6 f5 L- w" f
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    ! [0 i5 i/ Y# H+ T2 w. V
  119.         return -1;
    & P1 ~2 p) s1 q! y0 A* f+ m
  120.     }. a0 W) Z; W' B: Y1 n9 e

  121. + @, _0 Y6 d; q
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);: s& Y# S7 z8 Q
  123.     if (!window) {
    ' K$ O4 }7 n0 D+ ]( v8 S4 W2 f
  124.         fprintf(stderr, "Failed to create GLFW window\n");# I/ a) t- V0 q6 j; f2 Y
  125.         glfwTerminate();$ j. E) E5 s0 v0 ~
  126.         return -1;1 K1 i" i9 {  u8 K
  127.     }) W7 F: n, A5 C
  128. 0 [3 z$ b8 t: {3 n
  129.     glfwMakeContextCurrent(window);
    6 c6 Q4 ~; p" ?2 @  F  {& u9 a/ a
  130.     glewInit();
      p3 G9 i) f+ Y2 n5 _
  131. 9 v/ x6 W* {4 P8 s9 W+ \& D3 M! O
  132.     initialize();; u% i0 L$ `) N" t

  133. 1 w; T1 B1 }+ S3 A6 i
  134.     while (!glfwWindowShouldClose(window)) {
    " {  C+ s/ N; W! x$ B4 ?  f
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);3 K- l3 K% C5 h6 r% c6 Q" z
  136.         glClear(GL_COLOR_BUFFER_BIT);
    " n5 {% S% F: H* X4 W# A2 L6 R

  137. 7 @  X9 s) }+ y2 q' P2 Y3 X
  138.         glColor3f(1.0f, 1.0f, 1.0f);
    - _1 B6 T) N% b# |. p8 |4 M( N
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);. w5 Z9 ?) J  U2 U* |; y
  140. % S. m$ C; D1 L2 A
  141.         glfwSwapBuffers(window);, w- X, |* h4 G9 C# h
  142.         glfwPollEvents();3 ]$ Q/ n* O+ j" o7 `# T% t
  143.     }
    3 g) d$ d2 Y" C: j
  144. 4 {# N' a3 p0 [4 P
  145.     FT_Done_Face(face);+ P' }; `' J, [& o! _$ Y; t/ w7 K
  146.     FT_Done_FreeType(library);
    2 i% [% \2 F# V
  147. 8 u& U& y5 y" C' i% N6 E9 z
  148.     glfwTerminate();
    ; ~3 Q9 m1 H" c% }1 z0 H
  149. * v7 Z- T6 \/ b! R
  150.     return 0;& C/ B% ^, B' d1 J& x& j( R
  151. }. E$ m; Q3 x7 {5 N! ]' F
复制代码
( x& h2 i5 J. m( B

4 j& E4 u' H1 \9 I1 k" W
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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