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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑 1 w) }8 O* v! }6 `7 Y7 W
& }# t2 z0 M! Q
以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。
! r, K7 t+ c2 b. y' U3 E2 Y7 Q本代码经过分析以及改写之后,将取代游戏原有的显示函数。
1 v+ n2 W" M0 }6 g# M1 @# a
/ G/ B7 V6 O9 p2 _代码详细说明如下
1 c, j9 V0 F. Z: p0 p3 L! W5 A) b( z7 }' U2 G& A/ a
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:% P' n2 h! K* R

  2. 9 L/ h& |; [, i5 Q4 |7 D
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。; t( q  x6 y2 ]9 n9 ]& I- ]2 Y- {3 A4 ?1 y
  4. % I3 @+ K2 _, ~! R" u0 S
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。7 w  m/ \& l2 T- `+ L- o) Y5 Q

  6. . n) b" V( w% S  W) D1 v! s! C9 y
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。2 _" u1 p. a# L0 \4 s
  8. 6 P1 W: p' r6 C0 T0 j8 k0 P4 {
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:7 {1 k- ^6 l/ O; _8 r

  10. $ ^0 E% M6 v2 `9 c
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。- y, g9 P3 w; Q& N  N8 P, F' \# D
  12. 7 `, o. s3 @) j2 c$ @( }
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。% H- W% ?/ Z. c8 |! I4 j, {' _

  14. # c# v+ J/ Z3 O/ N4 ]3 j
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。
    9 Q) O9 n* T0 b. o6 G- _9 ~! e" ^

  16. 7 e4 m1 C2 H& c" a- N
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。0 N$ ]: G5 F  v

  18. 7 K% p% C: a0 w0 U6 b
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    4 `2 u) t! d7 R& y' l' y
  20. * ?* v6 C8 X7 M( \" Y
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。
    + B; f& O( n$ t8 m% z7 K9 b$ H
复制代码
+ G) y( j, S* |9 c

6 H9 h) \' y4 P! q% ^% C
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:
    ' g, Q/ m" t# p8 y) E
  2. $ x' c2 A9 h) z
  3. 参数:* D! U" {3 S, t5 r7 {- G3 ?1 y+ R8 g

  4. / H& R/ E! r8 w4 I5 [2 d
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    6 ?3 I' ^# L6 }' H+ f' _
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。% K: x9 N2 \' E5 `3 a! Y) H
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。. o3 M1 _7 k- l! _
  8. 功能:5 T. t" I  H' q( }

  9. 6 u+ G3 I% {/ M8 s* x' W
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。8 n. v% y. R1 ~1 i+ X
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。
    ( W$ k" B, ~5 a* p4 B8 g4 m
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。2 _& e$ _! z0 F& C
  13. 使用示例:5 [) F* A7 @% m

  14. % H- t, ]1 |9 W
  15. c' ]& g# A2 }2 @
  16. Copy code
      g; G+ w+ w' k+ W% U$ V
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);: j3 H' p% R- V9 j# h0 y
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。
    * U- E: k" ^2 m8 r4 B
  19. : M- H; Q- @1 M7 x# F- v0 g
  20. 错误处理:
    0 r: V. V1 z' J: d- |' S

  21. 0 `9 K& o" V9 Y9 \  z. N# U
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。
    ' ^# b; p# v, b9 N. Y
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
+ J9 x. D5 ?" e6 G$ b) M5 h
# H% C; I2 @5 b, |& ]0 o! |
代码3 u8 x* A9 v2 ^) ]
! Q- q6 n; a! z

  1. 7 B, d1 b  ]# G; ?

  2. + ^8 F- n4 y5 u, g8 H

  3. 5 Z, J, m! U& S
  4. #include <stdio.h>6 G' b* B* j9 V' ~$ ~
  5. #include <stdlib.h>
      l" a* q2 k7 [' Z
  6. #include <GL/glew.h>- N  N# d) d3 l; t4 d# n
  7. #include <GLFW/glfw3.h>& x" y2 ^% {3 `  v* g- b
  8. #include <ft2build.h>
    & O" @) ?- E4 `/ {2 `
  9. #include FT_FREETYPE_H6 x# D# w% ]6 }: f0 D

  10. 7 C0 E3 N# k2 _/ u( F5 @
  11. // 定义字形数据的字节数组
    , _7 e, ]/ N0 e; X
  12. unsigned char fontData[] = {
    $ i1 k8 A' @4 n) G3 }# z
  13.     // 字形数据的字节表示# K6 L6 v/ E2 x7 H
  14.     // 例如,这里可以包含字母、数字和符号的字形数据
    : w( c% [/ S2 K
  15. };8 @& R( K2 s( W# l  U- H/ b

  16. : Y: H5 ]" z! _* P
  17. FT_Library library;% g  C' o) Q3 K, {
  18. FT_Face face;  C4 W: p' W: K8 O7 f/ O4 ?7 w
  19. GLuint fontTexture;- q) h# a; E, F; S: p6 F7 D
  20. 9 B) b' n! G% Q6 L* x7 i  G
  21. // 初始化FreeType库和OpenGL( {4 D2 ?3 u+ H* E+ M
  22. void initialize() {
    ; U! P& ^: e4 O' N% z
  23.     if (FT_Init_FreeType(&library)) {
    7 h- z8 G: g( s
  24.         fprintf(stderr, "Failed to initialize FreeType\n");0 g% l7 D* M! N/ z: s% N3 p6 U. `5 E. K
  25.         exit(EXIT_FAILURE);
    ; _: V" t& x) u% o% Y" E/ j& n& p
  26.     }
    3 N" c6 l" v( w% e( ]

  27. . I6 I1 D' A/ K  [5 e! K/ C1 ?
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {6 P/ D! N; S9 `% a& c
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
    1 z: F- u7 O$ D; C+ D* n
  30.         exit(EXIT_FAILURE);
    ; `2 X1 B6 [- x  G- `2 B
  31.     }7 G; Y) q$ p4 V! i2 i* l6 |

  32. 6 t/ K. Z# d7 G8 @0 m; P
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小
    3 ~5 G- x' R0 K
  34.         fprintf(stderr, "Failed to set font size\n");# `% {- o+ S3 q9 E0 y
  35.         exit(EXIT_FAILURE);
    0 T% s+ y- S- \: M8 |( _# i4 T
  36.     }
    $ S; y5 x( h1 @6 E
  37. / F) p3 m3 K9 _' y
  38.     glGenTextures(1, &fontTexture);
    1 d, W: A" M0 n% O( O* m( N
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    0 {4 _4 x3 c2 U7 A! k
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    5 K0 U# Z9 z. K- h3 ]) y

  41.   U% ]  k+ F3 X8 K5 ~7 ~
  42.     // 将字形数据传递给OpenGL纹理5 t3 e8 t" q" U$ Q
  43.     for (int i = 0; i < 128; i++) {
    & Z* t: N1 Q( i/ p8 [' o" E
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {. y9 {) q0 r) p
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);
    - z; E* W+ e# L/ h8 w
  46.             continue;
    % u. k" h8 M- B- f$ O5 v( e
  47.         }
    7 a+ [* r. y% \+ D$ H
  48. 1 t# ]5 P* T# w# T+ y2 r/ l
  49.         glTexImage2D(
    / f) z7 f9 A) ?% k" @: S" Y
  50.             GL_TEXTURE_2D,
    & [% C/ s7 D7 n" `
  51.             0,0 [9 L$ ]3 Q1 W, \
  52.             GL_RED,& O/ ]" u8 m0 `! Z0 [
  53.             face->glyph->bitmap.width,
    $ s+ @* G$ `: n+ j- v# E4 x8 `
  54.             face->glyph->bitmap.rows,8 |4 G. n9 q$ z
  55.             0,: f5 X* Q8 |4 E5 y6 }
  56.             GL_RED,
    & J" a( O. U( b
  57.             GL_UNSIGNED_BYTE,; Z# |$ _# Y7 p% a: b2 |+ }8 C
  58.             face->glyph->bitmap.buffer
    - ~# Q  i! u- y& |
  59.         );
    4 ]/ k9 c8 h( ^# T. e/ ^* G7 t+ ~
  60.   O1 U  ~) I3 E5 t. W& [
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    ( W0 O- z; H  m, m6 w6 e4 K/ d
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    8 d0 T' a  v+ |
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    - ^6 S# H+ }6 s1 y$ u
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);: h# C) `& m  j3 M' k/ t" x) u
  65.     }  g+ v7 P% ?: v# R
  66. }
    % r" r* s. \8 w0 s( N

  67. , K8 W, y' T0 F* ]
  68. // 渲染字符串
    ( l) r. @; g) @; |) u0 W
  69. void renderString(const char* text, float x, float y) {  c' G7 t& D) d( A
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    : n5 u, e( C* \. G, d% r( A
  71. & E  ^+ E" |& a) a0 }
  72.     glEnable(GL_BLEND);+ }. I/ G! q( n: S
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    3 c$ N8 n- \& ]% [+ k# Z+ c. E/ K+ s

  74. 0 }5 G9 G& A/ }/ x' ], O( r
  75.     glBegin(GL_QUADS);
    2 Q" s& r$ O' ?% Q$ B- L# f% ]: u
  76.     for (const char* p = text; *p; p++) {
    ; W- P; u( ^9 {+ f0 P; W; {8 B
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);, L' ~& H5 G- Y( Q% n, _; ]4 l

  78. + H  _3 ?+ f* \5 d8 h
  79.         glTexImage2D(! e* r4 _& D3 @" k8 ^$ F
  80.             GL_TEXTURE_2D,* Q: M" c/ _- ^0 b0 J
  81.             0,6 n2 [4 a- d6 @* l+ Y0 X4 W8 c
  82.             GL_RED,
    ( C2 ]( g# q8 f- f( k
  83.             face->glyph->bitmap.width,0 N) L. v3 f# r' V
  84.             face->glyph->bitmap.rows,
    2 o# X, h7 Z! ?
  85.             0,# C+ w: b- \5 p$ l) ^
  86.             GL_RED,
    ! G' e9 C3 ?  m/ W  T2 [8 b# q
  87.             GL_UNSIGNED_BYTE,
    , H) G, g$ ?( J- ]' Q
  88.             face->glyph->bitmap.buffer7 X% ~4 R5 A  v) x0 V
  89.         );
    0 }0 t( Z2 a  i" T+ M2 ^

  90. # d+ N( B) Q7 j. ?. Q
  91.         float xpos = x + face->glyph->bitmap_left;
    . B; M: Y+ C. I; {# j
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);
    0 o1 D) ]  v' a: \

  93. . a1 \3 v/ E; _/ R# I0 ^1 d5 Y
  94.         float w = face->glyph->bitmap.width;; S2 Z. h* y$ r! k' `
  95.         float h = face->glyph->bitmap.rows;
    3 X; a" t$ f/ ^, V. Y' m2 W7 o

  96. " H" H; j( q9 x- p4 ~5 j6 R
  97.         glTexCoord2f(0, 0);
    5 C; \2 g- y. m# `! c! T2 j8 n
  98.         glVertex2f(xpos, ypos);' D8 u6 K* X8 x, a( G; {* G6 y* b$ m; [

  99. , D- B. P+ M& l: ]2 a# U1 v
  100.         glTexCoord2f(0, 1);
    : W8 m4 ^! r! J8 |7 V5 `9 W" T6 i0 f
  101.         glVertex2f(xpos, ypos + h);& X; i: P+ F8 `. V0 p9 Q6 e
  102. 4 i/ ?" W+ p& _$ F4 Z  Q
  103.         glTexCoord2f(1, 1);
    8 L4 G. g4 _0 b- x1 h% u' o2 d
  104.         glVertex2f(xpos + w, ypos + h);$ w6 k4 |2 m. C8 e. K% }4 T' Q
  105. 3 E* r5 {# k1 N
  106.         glTexCoord2f(1, 0);" n: X& F7 c9 D0 f, n
  107.         glVertex2f(xpos + w, ypos);
    3 D/ D4 N* {* N* s1 z) a
  108. + ^6 ~* k) j  P9 ^) X# v  i8 N: {
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距
    9 j( |$ |( T/ v1 i6 O" w
  110.     }: G1 `6 G( @8 F; s" ?, g
  111.     glEnd();
    $ w) X6 l6 A. R# |8 o0 q
  112. ' N2 x( j, p2 ?
  113.     glDisable(GL_BLEND);- v0 ^' o9 W) k" d3 L$ h
  114. }7 e) Q4 Z" }' P' k
  115. % y6 c# F& g- k) G7 m+ }; g4 d
  116. int main() {
    ; P* e4 B$ \3 E3 [4 F0 w
  117.     if (!glfwInit()) {' J$ V, u! y+ ~* i6 y$ \, W
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    7 [7 k3 \! X6 c+ S+ P( L
  119.         return -1;
    5 O* L" q& {' F" r, O
  120.     }
    % q2 S0 M0 h+ P0 ^# }

  121. 2 I( U) m8 i4 O4 k
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);: {+ `. Z0 A0 ]) ^" X
  123.     if (!window) {% H$ S  x: b0 l# l& _! r9 i& a9 a4 p
  124.         fprintf(stderr, "Failed to create GLFW window\n");+ ?. x' w5 k' d/ }# a. b. }
  125.         glfwTerminate();
    7 L3 }* z2 D  r
  126.         return -1;1 t* {! L1 i2 l8 r! i6 a) r
  127.     }
    ( [. P* w8 Y' I( Y+ P* J
  128. 8 d$ i; v' u( K' H/ D
  129.     glfwMakeContextCurrent(window);( A1 |& i& t0 b- [0 {3 X* L
  130.     glewInit();
    6 A8 j) U# F; G+ ]

  131. 1 C# L5 {( X; v4 C2 v5 ]' ?
  132.     initialize();# ?( X# }1 `+ K1 k; e: j/ a
  133. # Z7 _1 M, K3 N( b, r
  134.     while (!glfwWindowShouldClose(window)) {+ H5 k- {4 J$ _- v1 c( U
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);5 h" G1 ^/ M+ r, }8 W
  136.         glClear(GL_COLOR_BUFFER_BIT);
    % C9 N" b2 @2 f/ T, v& {

  137. 2 v8 a% C. E( _& t' }* S
  138.         glColor3f(1.0f, 1.0f, 1.0f);
    + G4 b& ]7 d' y, Q# J/ `
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);! m. `) y6 G) F  b* O8 y

  140. ( j, D9 Y4 N+ e( w" k  B- r
  141.         glfwSwapBuffers(window);
    ' n8 Z; z1 s7 C2 q9 [2 s
  142.         glfwPollEvents();' f& i- T, v# L8 D6 k! ]% ]
  143.     }
    / I1 d+ A$ P  R7 H# E$ g

  144. " {  O( b" {$ e' i
  145.     FT_Done_Face(face);
    0 o6 {1 l* O% m" h8 q
  146.     FT_Done_FreeType(library);& Q  b7 _* O; N1 |  i
  147. 5 b5 T$ w! j) d- E
  148.     glfwTerminate();
    / F5 V' _1 k8 T- {9 p

  149. % f% _: l- U' M2 n. y7 i# _
  150.     return 0;% Y4 s5 H) a$ [4 w- ~- |
  151. }
    # z4 s" C1 H9 K  o/ m+ e& n4 \
复制代码
3 h+ g1 j- }$ F: N% A( s. f1 U8 M
% x8 Q; e( Y. Y+ I/ K' Q1 y
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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