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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑 $ l7 ^, s. z% R9 H( A/ A( L

  ]" v  U2 b4 {: R# T5 z以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。0 y  b$ @9 h/ O/ z) f
本代码经过分析以及改写之后,将取代游戏原有的显示函数。
0 T% [7 `8 E5 h8 N  w
* ~0 h- U; r3 m8 A代码详细说明如下
9 Z% ~  {' K8 |* d: _5 _" ^& k$ Y) f5 k
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:
    5 n9 @+ C* N3 I2 l5 Z

  2. ! t2 q1 f( p- s4 ^4 g
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。* x& \+ g9 T. |1 L9 A
  4. " L2 f) {6 k* d( e8 E3 X: [
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。
    , y6 Z& i  o9 l  k

  6. ( E. p# `- r/ b8 U- W: r% R
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。
    ; f: K# h) O- ~4 Q' U, A% [
  8. - S0 R/ t# u, P' a' N
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:* V/ ~  W/ X; N- G
  10. * H3 m- K1 h8 P- r
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。5 S* G3 Y" ^% p( S( x

  12. 2 [7 u# j8 g8 J" w9 e% u
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。) f0 D& a3 c1 Y
  14. 7 O; M, Q4 U% N3 @6 t
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。
    * C: I" G% S( ]7 @3 D
  16. - i7 u% c% m; U( u& L2 v
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。
    9 b* `2 v6 z4 B
  18. ) o3 \* B  Q, r9 y
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    3 H; b) ~* o' \, Z3 a5 y
  20. , Q8 e' P9 k' E0 I
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。
    . G" y7 u1 T; Q: q+ W8 {+ n$ N
复制代码

0 k4 X' [" j  |
* X* E: p8 D7 f
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:
    : u5 R7 E# v; Y
  2. 4 c9 w" ~* u6 E, u6 a! b: R
  3. 参数:
    2 ~7 K  |" q! b' e" F' y' P% i8 g, G

  4. $ q& ^- E. N) X5 ~
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    3 p! H- j. t0 [. W& E* d
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
    6 N0 b6 K9 Q+ h" [9 y, `
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。/ P0 s6 G" b8 O# o( y/ k
  8. 功能:
    1 L5 m: H7 N5 d/ ~0 M7 |6 Y$ y
  9. 4 S: D$ g! V& L0 r) ?8 x
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。: M, i  x  s$ c! a
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。" E; _/ t+ Q! E6 K& R
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。
    6 m! \* r$ G$ i2 `8 P2 Q; m3 j
  13. 使用示例:, O; `" ?" r6 m: M: u' N
  14. * Z6 k3 O* O& q4 B7 b
  15. c& d9 l% [$ j) ?: u4 Z% `
  16. Copy code
    * h' P1 Y/ ~5 U4 ^% k
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);' P+ K8 L9 w  b: ~9 s; g" n
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。
    7 F3 a' s9 _" D/ y4 a
  19. 5 E& `& H2 u9 ~, s5 r
  20. 错误处理:
    9 u, v+ k4 ^+ A) @2 l

  21. ; v/ _, t" K: \1 ~% a4 u
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。
    1 z$ M3 ?' i& C1 L
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
5 E& C7 C6 m( c9 v% Q# M- V6 ]# L7 {
# [; ^: f4 H4 _: z5 F3 J3 _! F8 }' U
代码
4 t( z$ n+ o& ]2 x' R
. {" {2 g7 x( _, E+ Z
  1. 2 _2 n# ^2 M. b: ?& p8 [
  2. 1 V4 T- c+ e# Y7 K
  3. ) L" {' H. R  V3 z# [
  4. #include <stdio.h>$ ^- H0 _- A- M3 k
  5. #include <stdlib.h>5 C$ L' S+ @- g' c6 ?
  6. #include <GL/glew.h>
    $ \+ M, `9 z) R+ K/ l% b% o6 J# I  q
  7. #include <GLFW/glfw3.h>: a4 u9 E; `2 N' \$ y7 S/ G
  8. #include <ft2build.h>' e8 d: S+ C6 \8 [/ V
  9. #include FT_FREETYPE_H2 w  n3 R: y! K9 }2 g$ x
  10. 8 K# Z1 T, |$ ]0 s
  11. // 定义字形数据的字节数组6 u5 M' J' W' N3 g$ `
  12. unsigned char fontData[] = {
    ! \. B+ T6 _9 V7 P% c- L
  13.     // 字形数据的字节表示6 L+ f5 q. D6 i! w) L, @7 P( J
  14.     // 例如,这里可以包含字母、数字和符号的字形数据7 J4 I- s, ]9 r7 T, I
  15. };
    ! L% V, ^  C6 O; D( h
  16. / e! c- j# z: ]/ M$ d
  17. FT_Library library;
    / \) W  c; {2 u5 x5 b3 L& Y- }
  18. FT_Face face;
    ; {& ]/ }$ p1 y" D1 K
  19. GLuint fontTexture;
    # {  k& y( x' ^) C

  20. . m- H+ {: u& x; Z3 |+ e
  21. // 初始化FreeType库和OpenGL
    1 I0 S, r- n4 a% h. u' j
  22. void initialize() {) a9 ]  T0 g5 X! R3 {. G
  23.     if (FT_Init_FreeType(&library)) {# j! \5 t9 Q' V; \
  24.         fprintf(stderr, "Failed to initialize FreeType\n");* x- e: X+ X% M+ W9 s
  25.         exit(EXIT_FAILURE);
    $ b& _- \8 |2 W6 U  T
  26.     }& h( ]2 @; j4 F- p& r3 c9 G
  27. - ~0 \0 m) q1 X6 U% F- d; j! n
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {, ]6 e; L9 r8 |' _1 _. D5 i0 V
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
    / y/ C/ f6 N7 j% d" ?0 n8 H
  30.         exit(EXIT_FAILURE);
    4 m, i. ^, S, L' W. }8 Y# d2 A
  31.     }
    ! ?2 ^1 M) f" y# C* Y1 w6 f
  32. 9 \7 j' Z4 B6 S. e
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小+ D8 _/ Q( ^; G' j
  34.         fprintf(stderr, "Failed to set font size\n");. L( ?- ~( K# Q9 Y& A
  35.         exit(EXIT_FAILURE);
    + _' B( d/ j, B& N3 O1 C; @' v
  36.     }/ b6 Q( {" {% Z' l9 e
  37. $ m- E7 `' h7 W
  38.     glGenTextures(1, &fontTexture);6 M8 W: @& Z" _- H. ]! T3 K
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    + C1 K- I$ S& q2 U
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);, h, b+ X% E* J" n. ]7 v7 i& ]# S6 h; z) y

  41. 5 ~, T" [# v4 S! D
  42.     // 将字形数据传递给OpenGL纹理
    9 x- ~' m' F" ^+ d1 |! L' ?
  43.     for (int i = 0; i < 128; i++) {+ r/ [: x% v8 |- y  T; A" d$ V
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {# R6 `$ ]: @: Z/ O( N5 ?* i" h
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);1 t* h4 M' A- @$ }# W
  46.             continue;
    5 K5 Z" S( u+ {+ @- e3 c" D
  47.         }; b* Y+ K8 K. D* k

  48. ) v5 E9 t+ H; i' J% z* h
  49.         glTexImage2D(
    % j  U8 l" D& F& Q3 e
  50.             GL_TEXTURE_2D,9 {1 M$ ]  t8 N5 R# t/ Q# Y7 ]7 |
  51.             0,$ D, c" e  k5 U2 S1 {! v
  52.             GL_RED,
    7 ]3 \  k. k+ ]+ e0 c6 V
  53.             face->glyph->bitmap.width,/ K% z5 `: d+ _% R7 Q9 ]
  54.             face->glyph->bitmap.rows,
    6 L% F+ `6 }% \2 k
  55.             0,
    4 V3 @  ?) |) F2 x" O! O
  56.             GL_RED,+ W9 L! U8 z! S% h% K- {% I( m
  57.             GL_UNSIGNED_BYTE,# g2 B4 y( o3 Y1 a
  58.             face->glyph->bitmap.buffer6 u+ `7 ^5 B8 @
  59.         );
    / q& S; m. e' V# e: [& Q

  60. ) G0 B; I) w. l4 O) U+ w
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    0 n/ b9 r8 B9 i. I1 x! M
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    9 ^& z/ L: \* _  _
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);+ ^; @' x: M7 p% y# x
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    1 ?1 G' X. i. g5 o/ Y
  65.     }( D3 \2 e& \. E; \4 r' c/ q
  66. }
    ; r+ R7 v5 j+ Z  `" L( Z0 I
  67. # a( x' N& p, e. c; A$ F
  68. // 渲染字符串/ a7 v' K4 K( ?2 O. Q  h
  69. void renderString(const char* text, float x, float y) {! A( T& I- K3 ~$ v
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);4 v' d- W+ [* U2 C) N  L9 `
  71. 9 T1 }9 P8 ]3 j7 |: n3 T
  72.     glEnable(GL_BLEND);+ ~9 D/ \! S, @
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);( v. |$ i! l1 g9 r2 r

  74. ) N2 A" _5 F+ L' ]4 H  L
  75.     glBegin(GL_QUADS);
    3 Y2 Y2 B8 Q( B0 ?. Y! `
  76.     for (const char* p = text; *p; p++) {3 {7 c" L7 }& i$ B
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);
    & {3 x9 a  O) A! P! u5 x2 s
  78. " M& F  f1 G/ C6 P! r
  79.         glTexImage2D(
    ! s/ B" P, m- j* r3 A; M
  80.             GL_TEXTURE_2D,
    # H& Y; p- K& @0 E3 v' o
  81.             0,
    7 L# a# R2 r% p
  82.             GL_RED,
      p: b4 U' ]0 d. v* g: @) z) Z
  83.             face->glyph->bitmap.width,+ s& X. \# n" p) e
  84.             face->glyph->bitmap.rows,6 M, _/ h! ]# N: P
  85.             0,0 o" B1 g+ \& D9 {  E4 y% ^. U4 _
  86.             GL_RED,
    ; \; \2 v! v# y! C. C
  87.             GL_UNSIGNED_BYTE,. K1 z  t+ a) `
  88.             face->glyph->bitmap.buffer
    ; ]1 [) r  |6 J% G1 Q% v4 o
  89.         );- w5 D5 X1 |1 B/ d  {
  90. / c+ U' l/ F* J/ B4 V4 b
  91.         float xpos = x + face->glyph->bitmap_left;3 \1 B5 B2 n# ]6 V3 e9 ]
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);
    . k. T+ Q, ?0 d) u. S! m! u- u
  93. 3 R2 d5 i/ x! s- n1 H( }6 Y) f
  94.         float w = face->glyph->bitmap.width;5 M" U- T0 \! o. j8 W; _' P7 I8 {
  95.         float h = face->glyph->bitmap.rows;9 b7 ?5 i. R3 f9 N/ [7 L% H

  96. & j. `1 b  L2 g: y$ l# T
  97.         glTexCoord2f(0, 0);8 a+ D- g3 _. t) Q
  98.         glVertex2f(xpos, ypos);: _; Z" q% A+ E

  99. . H) c( r6 u; t1 j* _3 D0 E
  100.         glTexCoord2f(0, 1);% K, b' d1 ?0 f2 K3 m# G  l; ~
  101.         glVertex2f(xpos, ypos + h);
    & S1 X# a  W0 T0 G- L4 U& I
  102. - |6 z' H, ~3 p( T( ^( O
  103.         glTexCoord2f(1, 1);
    9 {: v- f8 R3 h+ ~
  104.         glVertex2f(xpos + w, ypos + h);$ C. @* z# i5 F

  105. 7 y% Y* {/ j* K7 z( m, U, y/ J
  106.         glTexCoord2f(1, 0);
    ( f9 Y1 R. O" T. I1 v" S" x; }
  107.         glVertex2f(xpos + w, ypos);+ q; [4 H; l1 H, J& a

  108. $ ]8 e' O) W' ?
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距4 H' w" X, v- ]$ z
  110.     }
    , p! L! D7 c% f/ [
  111.     glEnd();/ o% d' Y7 |0 r9 o& L
  112. : o8 O1 N7 [3 U& N4 [0 F
  113.     glDisable(GL_BLEND);
    8 T- U9 H6 m) K; C
  114. }
      ^& U2 K7 y& u& I  L& _  b" G
  115. ' O* j. ?5 m' ]5 A6 m3 B9 a
  116. int main() {
    % Z, R4 Q/ X# s) G5 [, E- s0 O2 r
  117.     if (!glfwInit()) {# S5 ?/ p& a$ r+ Q. D
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    : B# Z4 a  d" f( j
  119.         return -1;
    6 u+ a: T) i# _# u
  120.     }
    * z5 V9 n8 ?9 x  M9 x
  121. 8 G% J& G* T8 x: r
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);3 M+ h& Q  B) }" q. Y# o9 X1 [
  123.     if (!window) {( i: P+ b2 S" j/ x1 f9 x$ E' |/ C
  124.         fprintf(stderr, "Failed to create GLFW window\n");; r, Q8 R! S, {' C
  125.         glfwTerminate();9 Z  P# r3 L, w3 h/ p; }& l
  126.         return -1;
    " T- C0 k1 w$ p
  127.     }
    $ q, h/ l% }6 A5 U2 W; @+ m

  128. 7 V6 E7 Z' M8 j  Z% b2 U4 a. ]
  129.     glfwMakeContextCurrent(window);
    6 _3 X) `4 }" Q. ]. x& g3 l2 I3 c
  130.     glewInit();6 X+ p# X* J! N
  131. . i; P: H( n. S9 l, E
  132.     initialize();9 z& O5 B$ Y/ [8 R) C' w5 s# Q

  133. ) D% ^+ i2 i  D& u
  134.     while (!glfwWindowShouldClose(window)) {
    " w% Y0 R8 w4 {! Q
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);# C$ M+ D, n6 f! @  ^5 K( w
  136.         glClear(GL_COLOR_BUFFER_BIT);- V, n. E3 b) ~% c
  137. ' w9 p$ K+ w9 p. \4 H3 R* F4 b
  138.         glColor3f(1.0f, 1.0f, 1.0f);8 H$ s: l. s, P8 r
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);& W- f' X. o8 o  e/ n/ Z7 o0 n$ Z

  140. 6 k% M0 V( _6 _/ p+ X" y3 z9 s0 e
  141.         glfwSwapBuffers(window);
    $ ~& P# V) B. X( W
  142.         glfwPollEvents();
    % z( p& X* w' n) V2 |8 t" p  h6 g
  143.     }
    , j5 _& Z8 J+ `, G3 A) [5 g4 d
  144. # G  h0 |4 N8 F
  145.     FT_Done_Face(face);
    : ]; [$ {' U7 I" h- w4 o; G
  146.     FT_Done_FreeType(library);
    . O5 K; q" p; S, B$ ^

  147. ( l# ?( R; f4 L$ H" f
  148.     glfwTerminate();/ v, g4 i4 c4 e6 N
  149. 1 ^) B$ w6 I* X: `8 o% L
  150.     return 0;' |, |( r  V8 G5 y
  151. }
    4 {# m& u8 G3 N* ?; [  l9 F0 T; m4 u. F
复制代码
9 v; L* Y& |/ l) ~. u$ `

# u+ n# X: S/ Z# K8 C" S+ q7 D
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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