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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑
6 d5 U& P% W% \0 v5 q; Z! M, a8 r5 \  j* V. n+ Y
以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。
! [' X# \) R) \5 t% C1 A& o  F& }本代码经过分析以及改写之后,将取代游戏原有的显示函数。
& ~  E7 ^, e3 z$ e- ~
5 y& o( _: }* ?8 Q/ s代码详细说明如下
" M% |- v; {# T( p) v* ?% [2 ~! U8 `# r/ ]
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:1 j* u* S% V  q& w5 z; O

  2.   W7 a- M3 x! _1 V' k
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。2 F1 f# e- \" a3 y5 o! Y! b0 f5 H
  4. : h& B! S- \  q1 f* Y
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。0 r0 m+ G( _% R8 e- o
  6. " e# N6 K3 c3 N4 J1 g# X
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。
    + P3 p1 B/ K, \

  8. - A3 v; x9 D9 ^& Q0 Q! J
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:1 o' o* t* H, O' }2 b. i# f; J
  10. 3 Q7 q' h& s$ R4 `) _  k+ u9 l9 I
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。: u+ |  W6 f' x" l9 f: C% u

  12. + f# ~' {" f) _
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。
    - D! w+ I. a' H6 ~% I5 J) ^

  14. , z' \* V" J7 w. E7 W/ a' B
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。
    ( @7 H( v- N0 u9 Z
  16. 3 S0 C/ k& z( f! T+ J/ f
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。. n$ j# `6 y1 k: i7 H

  18. 2 ?, [. b) k7 q1 o: F( N
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    ; @% E& }0 f9 f$ J

  20. # P9 J* s8 Y: M# s
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。
    3 g! y# Y7 O9 l% F6 E* X0 z# R
复制代码

1 x6 \2 v! |) m7 ?: E4 {$ ~0 p) q8 i' f+ \  x
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:  l( s# K+ o$ u) ^; a2 m
  2. 9 u4 }% V8 M5 z# Y- G+ f4 e0 A3 ^
  3. 参数:
    * h: }) n9 g$ [& n$ B* |

  4. 2 G! I$ C3 w( N
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    1 U' C  {& x2 p: j+ f8 D
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。, z1 u' x1 H5 r' V& B3 O8 o
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。8 b7 A/ G' I& P2 C, j+ ]
  8. 功能:
    0 {& h7 S8 N0 q8 b+ ?$ i4 E
  9. 3 @9 ~3 N9 B8 Z, x2 _
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。
    " x% H. x( M! d3 q. k, t9 w7 Y
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。
    / H6 ^4 H* ?- W1 _
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。, @3 F+ f9 Y9 T
  13. 使用示例:
    2 ~% b$ {0 f2 z+ ^3 t" v: d
  14. 0 q( N( r8 p6 h0 T
  15. c' U4 Y2 a" v0 ^& B
  16. Copy code
      w3 J' g' n7 ^) X
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);
    4 q2 h8 o3 G# k
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。/ `  p4 q) h& l7 n

  19. - w* i6 a0 ~( B
  20. 错误处理:
    $ i- b+ v9 B4 h0 ^& |

  21. 9 H& `# w' @* X
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。
    & ~! P  q7 }* [( ~& p% B7 b7 f( f
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
2 C& `2 _. _' n4 z* ?4 J6 l4 f

* U- o6 n5 f+ t* w# V* x( X代码
8 z6 _: u9 B4 {' S7 J. p7 \/ k: R& o+ A) ^4 I( c

  1. % h) i* f4 M8 [6 H
  2. 6 a! }1 ~5 d  ^8 ?- {5 r& S$ ^' x

  3. . y$ j6 y+ @% v+ \$ p7 z
  4. #include <stdio.h>
    : j" n2 j9 S) p5 a
  5. #include <stdlib.h>. _: m0 t7 _6 F- Z
  6. #include <GL/glew.h>
    * x) \3 r2 Y/ ]" d/ X
  7. #include <GLFW/glfw3.h>
    - Y2 }+ u# ]  K4 B& L+ N$ r
  8. #include <ft2build.h>
    , V/ Y* p8 M$ \. H1 S% Q4 C, n' d6 w
  9. #include FT_FREETYPE_H2 z$ ]* w, f0 E
  10. ' k! k+ E! D3 ^7 Z
  11. // 定义字形数据的字节数组
    6 G* k5 n% \0 w) p- x1 v9 x% |. D% q
  12. unsigned char fontData[] = {) R& ^7 ]  n1 t1 f0 a" Y' _4 F+ c
  13.     // 字形数据的字节表示
    . R* O$ o% V2 [+ }1 u
  14.     // 例如,这里可以包含字母、数字和符号的字形数据3 ]- y' R, r4 v8 L8 z3 C* H; N
  15. };6 T$ d( S" s" H

  16. ' G) b5 X' r: A8 r. l6 j! w
  17. FT_Library library;
    6 ^3 E( U/ A% r/ R, z9 [/ Y: h6 A! z4 i
  18. FT_Face face;2 U5 E! k3 o5 E7 L+ E% M
  19. GLuint fontTexture;
    0 w( d( h# _  x/ U* i

  20. ' o: v. k! H1 ]9 j% D
  21. // 初始化FreeType库和OpenGL
    : O" n$ x8 K* t5 h
  22. void initialize() {
    ' e$ G' C& G8 q* v5 G9 J
  23.     if (FT_Init_FreeType(&library)) {: `+ h7 a& C7 ?% w: j. x
  24.         fprintf(stderr, "Failed to initialize FreeType\n");
    . W' g+ R( [2 `0 }9 l1 t
  25.         exit(EXIT_FAILURE);
    & h! I3 b8 ^, W- X
  26.     }/ R( f) ^" h# W
  27. % X# L( O% i6 n
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {
    ! ?* e2 i5 x9 ~; x4 |9 R7 }9 {0 {3 ?2 r
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");) _! Q( ?6 [& F+ M: H% o
  30.         exit(EXIT_FAILURE);
    ; [0 D+ m4 V6 b8 m1 A
  31.     }7 N2 U( g5 L: F) o  @# ~2 U5 X( Z
  32. 6 I+ a% R+ }4 |% b5 p0 L+ @
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小( K; w# _. J% M1 n7 ~# z
  34.         fprintf(stderr, "Failed to set font size\n");( H3 o! n6 Z6 K
  35.         exit(EXIT_FAILURE);
    $ l4 G+ n; ], N" D3 u# v1 Y4 G
  36.     }
    # Y) s: S. ^; c4 x

  37. ) Y9 B# k9 L- f
  38.     glGenTextures(1, &fontTexture);
    + F. g. o! h0 y2 p/ G* c
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);4 F5 @, g5 v& q* W- K# M" a
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);9 [) L, S2 G' Q2 s/ r3 f& ~

  41. 2 t$ Y0 ]# R% ^$ W5 V
  42.     // 将字形数据传递给OpenGL纹理6 l' C4 Y8 N6 D5 L" Y
  43.     for (int i = 0; i < 128; i++) {. k. V6 Y2 s+ G
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {: N/ h7 o5 t) r  \
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);
    * H8 N* W  [: T% r# L( T. V
  46.             continue;0 Z+ i! {& |- R6 O
  47.         }0 l. `4 d5 G7 e0 U( i3 l

  48. + o0 C$ K: ?) i; m; q, v1 ]9 R; k6 a# z
  49.         glTexImage2D(+ P7 ^. A; p6 b  h/ B! `! @) N
  50.             GL_TEXTURE_2D,* ~1 L) W/ Q8 i
  51.             0,+ ^  M: H+ k1 @9 r& r) q4 C
  52.             GL_RED,
    4 T! }  o2 K5 {$ r4 M1 J8 T
  53.             face->glyph->bitmap.width,
    4 f. J* j5 ^$ K; z( i% }
  54.             face->glyph->bitmap.rows,. c, U& j% w) v. h2 M/ V- r
  55.             0,
    + e, Q0 P5 y7 Q3 O) r
  56.             GL_RED," S6 O* e6 p! k9 T; c6 R; O
  57.             GL_UNSIGNED_BYTE,; s, r* I8 b- g0 ~4 `; W  L  P
  58.             face->glyph->bitmap.buffer
    3 @+ ]1 L7 s: Z4 F% x( ]
  59.         );9 ^; ^3 R: H( S5 b/ R8 Z

  60. * Z3 Q5 I( T; c# F1 u. q
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    : w- u6 q/ g+ g  o  n0 n
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    / y! {: `7 h* H; g- Z3 ^
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    : Z4 ?) C( o9 k9 e
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    2 y4 p$ b: T) K2 [# G+ V- c# \
  65.     }
    * p# q  K* m% x! F
  66. }5 Z% e4 m, w" t4 m/ Z
  67. 3 X- D; n' m1 i+ c( X/ H0 G$ V
  68. // 渲染字符串7 H+ e+ d. y" N, I, z
  69. void renderString(const char* text, float x, float y) {* ^0 F3 y" v) R% M$ Q
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);& T5 e) D4 |0 Q9 ]0 b! u

  71. , z/ |" n, Q9 K9 S/ T
  72.     glEnable(GL_BLEND);
    3 `8 C  c( Z& O* J, A- T7 R( x
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    4 @( x/ @. \. X9 ?
  74. 7 C+ {  C/ v: a1 I2 \( |
  75.     glBegin(GL_QUADS);
    ( |, _$ ?9 M+ s6 C$ ?2 O' p
  76.     for (const char* p = text; *p; p++) {2 u$ N  H% m+ u  ?6 j& H0 J% I
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);
    2 r, `# G0 H' `% y7 p3 F

  78. 1 u* A3 G1 c; L9 _# S
  79.         glTexImage2D(0 Z8 `, ^: B) u0 |6 ?2 d  N  r0 Y  u- ]
  80.             GL_TEXTURE_2D,
    5 W# Z+ Q: Q' O% B* Z, L* Q' ^& ^2 `
  81.             0,/ Z0 N' n/ W6 C# s! @, e& |
  82.             GL_RED,
    & H% _  ]  \. J
  83.             face->glyph->bitmap.width,( u  J4 ^% i1 P0 ]* O& A! y4 }
  84.             face->glyph->bitmap.rows,! J8 c& [/ r2 Q9 D, M% @6 Z+ t$ g
  85.             0,+ N1 P$ Q) e1 T5 R
  86.             GL_RED,
    9 I2 ?$ y7 Q% @4 N
  87.             GL_UNSIGNED_BYTE,
    # L: m! M8 s% X; u! H
  88.             face->glyph->bitmap.buffer% a% R+ e, N+ o: P* v* r1 Q2 Z, H
  89.         );5 s" u  I- f7 e" _. F4 e! z$ a* T
  90. & ~8 W' u8 ^. m3 u
  91.         float xpos = x + face->glyph->bitmap_left;
    ( k- \+ e2 c# s0 A* O
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);( V; i9 i0 q5 V7 l

  93. 9 o, d; Z9 Z+ W/ ?$ }/ B) O$ a
  94.         float w = face->glyph->bitmap.width;( T4 r2 P! y  @7 p
  95.         float h = face->glyph->bitmap.rows;% v/ O/ ^  V- v1 O3 L
  96. ; {# P2 d# [# z
  97.         glTexCoord2f(0, 0);5 ?0 y5 Q/ R8 F& U
  98.         glVertex2f(xpos, ypos);! F- J, o  v' c
  99. & t" d. b! E" c, G, ]% x, L
  100.         glTexCoord2f(0, 1);
      o( q3 |" i" L$ U& Q
  101.         glVertex2f(xpos, ypos + h);
    0 p3 E* [& t# z7 F
  102.   t: [; ~% U; m1 {4 b1 H8 T3 O! z
  103.         glTexCoord2f(1, 1);, v9 |1 \; b% u: c3 ]; F
  104.         glVertex2f(xpos + w, ypos + h);
    + h6 M$ [( M3 \8 p6 `
  105. ) A# [" q. p/ h9 w) w. O2 |& k
  106.         glTexCoord2f(1, 0);- X5 U0 X+ v8 h; t6 s" w. R
  107.         glVertex2f(xpos + w, ypos);
    " c+ v, ^: X7 n9 G

  108. - ^0 }, Q5 ?% g+ C1 G* z: K% ]
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距, a+ e3 t1 z' C! j6 h
  110.     }. k) x+ G/ p& h* M$ }* O3 J! v' p
  111.     glEnd();# X5 B% y( [5 A# L( X
  112.   S" b& S/ E! j
  113.     glDisable(GL_BLEND);( C/ f5 s# a5 J
  114. }
    - s; C& m6 R0 ], H" L

  115. * k: @" p2 n9 B# H4 c
  116. int main() {: c8 F, i0 \$ _1 |
  117.     if (!glfwInit()) {2 Y  c" d3 i/ B+ f/ y
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    : q: ?- \- Q7 i* m" P% @
  119.         return -1;
    0 w; F2 K8 x, P5 W! f. D( }
  120.     }
    4 E" C2 }/ x9 H3 H8 v
  121. ) M& `9 _  _8 y; J+ O
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
    2 ^8 R- {% K0 T1 ~; B$ j: S
  123.     if (!window) {
    ( m/ n1 `$ H! w5 O, n3 {: m
  124.         fprintf(stderr, "Failed to create GLFW window\n");9 R! Z" Y: x5 f. N/ H
  125.         glfwTerminate();' f, {( F. y; E% l/ w! W- B0 g
  126.         return -1;5 T7 Q' [% b% I' d) ^( Z2 R
  127.     }# P# e0 D' ~2 m  l

  128. % g- d1 u4 e" p* h) s- i
  129.     glfwMakeContextCurrent(window);3 O. V$ V" J( G! Z" c) y
  130.     glewInit();
    ' Z) b$ }" h+ K' V# a8 `
  131. 6 R$ V; f. |$ j% ?* H3 Q
  132.     initialize();+ ~) [8 [; x! b3 H6 Z

  133. ; q3 {0 {5 N- y" d& S
  134.     while (!glfwWindowShouldClose(window)) {
    ; A) F, p5 ?3 t& e/ s
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    ; F/ J6 a9 G2 a' ], H; p
  136.         glClear(GL_COLOR_BUFFER_BIT);
    # O# c# D" o1 |! R! z" k3 w8 x

  137. 2 \; J7 E+ a$ t
  138.         glColor3f(1.0f, 1.0f, 1.0f);1 k9 O3 [( J# k& g$ M0 x& A/ S3 N: a
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);: _3 x- E  |8 l* W; @. E

  140. 4 Y+ [8 B0 A4 t5 r
  141.         glfwSwapBuffers(window);5 |( @5 k% R3 u7 }/ v
  142.         glfwPollEvents();
    + n3 ^6 {& y1 Q" @  t
  143.     }5 {' {0 L" I* w. _/ q& b
  144. 8 s. T! V# ]8 H6 Z
  145.     FT_Done_Face(face);( X9 U) Q, u! J( W4 x* W7 ?
  146.     FT_Done_FreeType(library);
    9 p5 C# N7 T$ ]* r! y9 i. Q
  147. + f5 K& B; |6 D* H+ p
  148.     glfwTerminate();
    3 H( H; S6 c, `' @# X( A5 r

  149. 8 B; V% r6 M5 W# ~; R% e2 @. |: M
  150.     return 0;# {% T) i# L: q6 I
  151. }. _8 U% n, q! ^9 s; y
复制代码

8 a* X, i+ Y! P# d, g$ c
5 O4 |* J: R- {/ W8 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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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