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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑 5 A9 z9 B/ b! j9 l! M0 S

& ]2 d6 _) U9 @$ S: D以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。+ p* L( o9 i5 }
本代码经过分析以及改写之后,将取代游戏原有的显示函数。
1 N& n- f6 Z+ N
) s" i! @% _* u: B8 p: i代码详细说明如下
- b; p8 B. i9 h8 ^0 M/ J
$ D, ?/ P2 H; u2 a6 p( |. ]
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:- n# V0 w) D: @

  2. 0 K  J$ L. j$ b$ s' m/ s- `
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。
    9 _: G1 Y! ~/ |. {1 o
  4. * q1 V8 ]% }( F9 v. y. C
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。( N9 |/ w$ M3 Z2 F& I

  6. 4 l4 ?: a+ J; A" G1 @1 T% ^
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。
    , W. d  C; g0 R- G

  8. & B4 T6 j# U6 ^* a
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:& U# x" s! \7 Q% N/ @  Y  {

  10. . w% v; T1 q  v. e8 z5 B
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。
    9 \+ Q* h( Z* h6 U+ d

  12. 0 G/ |' F% k% P9 h4 H+ }2 A$ U, n
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。
    ' ]7 y$ D) }; D1 u& A) }2 Y4 g* P
  14. 5 F% ]! b! h' y+ i. l% J" M0 L
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。6 f; t" B- b0 g; Y
  16. & \8 c* O* i3 O4 J# o
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。# l0 ?) ^+ k8 L+ `! r
  18. # g, a$ Z* L) a! Z7 q& w
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    - A/ [$ U$ L8 ~" A
  20. $ x, D! ^8 ^! g$ t% J
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。
    ( i( g1 I/ Y* o/ U4 K
复制代码

7 ?4 x6 b# O8 Z7 K- |8 x# J! l: Y7 R/ O2 [; ^
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:0 ~) A+ t2 p# K8 v, r
  2. ( I8 _9 c' r' `
  3. 参数:5 u' m& o- n# S: D4 F7 m, B
  4. 2 |4 X6 ]! t2 q! M( P
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。3 z, m; G$ ^7 ?& b8 L
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
    . G" U, _- J" Z( y" ]: ?0 d
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。
    : d3 o2 x5 Q4 i8 _! t2 l- W6 r. ^
  8. 功能:) b1 b+ i4 g4 H3 g

  9. % U# Z, X) R$ l3 W* G4 Z
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。) ~; s% J" H+ D8 t6 Q6 f% m
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。3 n9 F5 ?. R5 |* M% S
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。
    % y0 J2 I/ i$ r! u5 D
  13. 使用示例:1 j/ z; ?: Z0 d0 E+ P

  14. ; a7 V6 H. {$ G4 h) q2 q! [% _. m
  15. c6 h, f. {2 M% X# W; K
  16. Copy code
    9 \" x) w" B, y1 Q  X$ ^: x/ x* [/ R
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);
    + X& \* o/ s. N
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。7 Y* {' ?# e! g9 H" C$ v

  19. % a0 `4 J4 v- S5 L( ?; ^5 r
  20. 错误处理:# e5 s( q, a8 Y8 _
  21. 5 h2 f' H! D' H" W
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。, k" P+ T' j8 ^6 j# y# w, i
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
" e2 w3 \% D; n5 Z1 o
+ Z* i; z4 B: T& V( C
代码
" s- j0 I0 h. N  B6 {
5 o  b2 u9 K3 }* z# R

  1. 9 V( Q$ e2 H& Z: T9 z2 z

  2. ) M% u* ?3 R" ^/ h

  3. + m' G: M1 Z% P& f1 y
  4. #include <stdio.h>5 u' v' J; ~0 Z! u# r4 d
  5. #include <stdlib.h>+ S! R: j& n4 z( u5 n/ }) n1 W
  6. #include <GL/glew.h>
    * Q! q% `' z6 C, V% l) \- Y
  7. #include <GLFW/glfw3.h>4 @+ n7 u& e* O0 j7 ^$ j
  8. #include <ft2build.h>
    ) M8 ]3 o% I5 z5 k' W2 l+ l
  9. #include FT_FREETYPE_H% C9 J8 A! E+ z5 a
  10. 8 _8 m, M! `3 G( R
  11. // 定义字形数据的字节数组
    % V9 i+ N, S+ d( [
  12. unsigned char fontData[] = {
    + ^& y1 Q! z* K7 \) y
  13.     // 字形数据的字节表示
    2 x6 A) R( R- u$ ]3 r# `5 [
  14.     // 例如,这里可以包含字母、数字和符号的字形数据
    ' Y0 A7 N: r. T) |( B
  15. };  ?2 b/ r; ?! N* V0 r2 x1 s

  16. 9 _7 s2 P; `! V8 I) [& j
  17. FT_Library library;
    & ~2 y6 C, p0 z9 G  S( z) ^+ o' b
  18. FT_Face face;! k* ^; ~0 `! `8 z8 T1 G* v
  19. GLuint fontTexture;
    7 y% y6 `# T% `- w; \7 Q
  20. ) C) a2 R) A2 E; n
  21. // 初始化FreeType库和OpenGL& l' H" w/ `/ d% K9 I
  22. void initialize() {) @7 d- d: f  E  ?
  23.     if (FT_Init_FreeType(&library)) {! O+ P0 p4 c6 ?, [& N
  24.         fprintf(stderr, "Failed to initialize FreeType\n");* J5 ?- P4 }6 _
  25.         exit(EXIT_FAILURE);4 a- [4 K+ S5 ~, a
  26.     }
    6 v5 Y# q9 ~* v2 b- l
  27. & T  [( K& k7 z! C4 Z  |
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {
    ; V9 k0 ?( U4 s, c$ p% d
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
      {+ Z" B5 T$ D
  30.         exit(EXIT_FAILURE);
    - W$ B' [8 _+ Q- {! V5 }  {( q
  31.     }. z6 o+ e  H( g: s

  32. 9 n2 ]# R* t: p% E8 N/ w
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小+ h. O( |9 ~6 w2 h4 L2 o
  34.         fprintf(stderr, "Failed to set font size\n");. f" O: w1 j% F( Z9 ~
  35.         exit(EXIT_FAILURE);
    0 D; [9 P6 g& ~" y: U6 O7 U+ s
  36.     }- z: J: D: w* j; p% T8 e6 E
  37. 9 g4 t: c7 E- i' @
  38.     glGenTextures(1, &fontTexture);) o* w8 u1 L* f
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    + q. F- j& X! u- M) y' W
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    / H, n; J: ]  s/ c; X' b# ~# A
  41. 7 A8 l; m$ Z' Y9 o% V
  42.     // 将字形数据传递给OpenGL纹理2 @( e( `' O2 X$ Q# F1 I. `
  43.     for (int i = 0; i < 128; i++) {1 s3 O* e- w" m- n' c
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
    : _% |7 r$ H/ `6 G
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);1 u& I* n: t8 `0 N, s
  46.             continue;- n6 U6 Y! T" `- w
  47.         }
    / u7 S& A$ d8 }( ~* I  o9 \
  48. $ Z+ r1 F0 N. n6 _5 Q$ Q/ @
  49.         glTexImage2D(
    ( M7 x2 l1 d- p1 b4 S
  50.             GL_TEXTURE_2D,
    0 H7 v2 r7 d6 s
  51.             0,* a9 W' M  m2 p
  52.             GL_RED,
    " `  ]# ]2 i( Q5 ^: a
  53.             face->glyph->bitmap.width,( O! y' b6 h' y0 }0 C8 g
  54.             face->glyph->bitmap.rows,
    8 ^- [) N, l* h* J* n" z
  55.             0,
    4 u7 ^, {( E8 b0 T
  56.             GL_RED,
    ; D3 B: ?5 N% G0 O+ `$ u
  57.             GL_UNSIGNED_BYTE,
    - d* L& l! _! V, Z. n
  58.             face->glyph->bitmap.buffer2 B  n7 p  x3 @$ ]9 f4 N' ^
  59.         );
    : F$ [( d: j$ X* W  [1 w" W
  60. / `* ?8 s# o, f4 n! W8 J
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
      j, j# E8 e6 X" b+ w: d3 O
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    3 r$ {& R0 C. {4 I8 E% M
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);) P2 g/ E  `# F  m* y8 Z
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  j: V* M) M8 Z. A. c5 N
  65.     }
    # N: Q0 b0 H. S, f
  66. }# c) |! V' U" I- N

  67. 4 r/ U  Y2 T) i. u, T9 W
  68. // 渲染字符串
    + H9 N9 c' y7 L% I. z
  69. void renderString(const char* text, float x, float y) {- s* Q- i; S- f$ `2 |; T+ i
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);, ^. ]: {1 X( |  w
  71. ( `$ P# s9 C: `  v
  72.     glEnable(GL_BLEND);
    # ?! f$ X9 N- y) R/ a0 b: L! K
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);6 ~' A+ N/ S9 _( q" n0 p

  74. ' R  P2 q; }, f  B3 r1 x$ H
  75.     glBegin(GL_QUADS);* K1 R  j0 q9 E: }5 V
  76.     for (const char* p = text; *p; p++) {- M0 |# ^! m; w& c+ C
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);, A* s: V  M8 g: g) F
  78. 5 Q: ^) _! S# m3 |+ p
  79.         glTexImage2D(
    2 I& V1 r/ F- a& p( N
  80.             GL_TEXTURE_2D,. w5 I* k0 P! }( C
  81.             0,
    9 a4 g: N- O1 b$ R  y$ q
  82.             GL_RED,
    ' {- E4 v/ R. ?8 r! D4 {5 \9 E8 L
  83.             face->glyph->bitmap.width,% w7 s& w4 h) h% {% s
  84.             face->glyph->bitmap.rows,' U: W& `! z$ L; S, z; ?4 B
  85.             0,$ Q: S, Z) p# x" [
  86.             GL_RED,
    ; _) T; u/ m' s: i* v
  87.             GL_UNSIGNED_BYTE,
    0 v* p. ~1 o$ y" g$ f5 n0 u* k
  88.             face->glyph->bitmap.buffer
    + M( n( a& X# m0 l
  89.         );
    5 m2 I2 u$ x' Q7 G, J
  90. % j% Z! U: S5 V* k3 D' p4 @) V
  91.         float xpos = x + face->glyph->bitmap_left;
    & J* ?9 V. n0 v* z8 o. L
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);3 ^* [( w& b% A, O$ s

  93. + h8 y0 b- D4 D7 I7 K
  94.         float w = face->glyph->bitmap.width;' N+ K. X, t0 W- Q
  95.         float h = face->glyph->bitmap.rows;  x  p- c, _4 C1 e& x

  96. $ R: W5 S  T7 V% v- B" y
  97.         glTexCoord2f(0, 0);
    # j2 M5 B7 t2 z) i
  98.         glVertex2f(xpos, ypos);; _. Q; E4 b' `% C2 G/ N; x$ F
  99. ' l; q! @1 f3 B' C( f/ C& W
  100.         glTexCoord2f(0, 1);
    " Q3 m( P& F9 ^- w: M6 `1 f' K" V+ e; [
  101.         glVertex2f(xpos, ypos + h);
    9 V" u4 I' w% p; N) ]

  102. ; ?% \; J9 d  q, }6 S
  103.         glTexCoord2f(1, 1);% S+ N/ q, W$ V, f0 e" k8 k
  104.         glVertex2f(xpos + w, ypos + h);: Q8 @# J7 u  ]$ ^# Z
  105. 0 T8 D/ N3 I! q1 T/ f5 }& L
  106.         glTexCoord2f(1, 0);& q5 z. H5 u- ?9 o+ K4 K
  107.         glVertex2f(xpos + w, ypos);
    0 I4 A+ E' D$ M

  108. " j$ K" F9 Q5 D3 e& L8 }
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距" j  a' O- i+ A( ?8 u
  110.     }
    0 L4 d0 {% n  }& p0 E1 }( L  i2 O
  111.     glEnd();
    3 V  e3 I( z* R* }- a5 H. C
  112. + f6 H8 W2 \3 m. [) |* J, k
  113.     glDisable(GL_BLEND);
    7 g( b/ N8 P! U( ^+ y* L: j4 \
  114. }; y# b1 C* Z: `
  115. 2 ?. Z7 \2 n. d) k) Q  j5 J
  116. int main() {  u3 T, p5 t2 ~1 ~  c& w4 C
  117.     if (!glfwInit()) {
    & o6 l( v/ Q+ \) W/ t
  118.         fprintf(stderr, "Failed to initialize GLFW\n");: E1 h! u8 r2 ~" Z( h( p
  119.         return -1;/ M' M' V% k1 x+ f0 H1 x/ K
  120.     }
    8 s" B  t3 A( A' [6 g

  121. 9 S7 A2 f3 g% j. f) {. o# N% U
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);. e8 B) g% m6 z/ J8 W- W4 ?# H" p
  123.     if (!window) {
    0 y" \+ d# @; b+ p9 F, h6 ^
  124.         fprintf(stderr, "Failed to create GLFW window\n");
      a5 _) J0 u7 H
  125.         glfwTerminate();
    0 @% L" l* z* N" [
  126.         return -1;9 s* U) U" e) f( R  M8 u
  127.     }
    # @+ H+ K" p2 y

  128. 0 z7 u0 n: }- n3 {$ n9 K3 c
  129.     glfwMakeContextCurrent(window);4 q% |. a% B% p, z
  130.     glewInit();$ U9 }, o5 d1 z  y
  131. 4 j7 [9 g; X) X( x4 ~7 O
  132.     initialize();- k8 R% T/ @" B2 I

  133. 0 B) ]* E7 c" F/ \" E0 h1 M, o' K
  134.     while (!glfwWindowShouldClose(window)) {' T5 c2 L5 w  r; @! R
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    ' a+ M( e/ R  I7 Y$ `9 J
  136.         glClear(GL_COLOR_BUFFER_BIT);  m% C4 K3 |+ d, Z% L
  137. 5 f/ [- W- E# {& j
  138.         glColor3f(1.0f, 1.0f, 1.0f);
    / G( `* I/ ~$ R6 d% t6 O  y
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);% d0 p+ n3 W% u, W) f

  140. ; P8 W1 E3 w& f% I+ T
  141.         glfwSwapBuffers(window);$ b" n3 x7 t8 G7 Q, E, l3 H- Z1 d
  142.         glfwPollEvents();" X7 U7 S+ s# D' |/ I( @9 k
  143.     }! [2 }$ Y9 _2 R
  144. ! e. b; [: f& H1 C- X0 ?. W
  145.     FT_Done_Face(face);
    $ s# v7 j9 E4 N
  146.     FT_Done_FreeType(library);
    5 }) H; @* x  f1 q: [5 Q/ F
  147. ) n2 O. R9 I8 E) o; q2 S. D& G
  148.     glfwTerminate();
    1 f& f( w2 D0 X3 v
  149. 9 c# m& B) t+ Z; d
  150.     return 0;
    2 b+ C& ^1 |& ?: T9 H! a8 }
  151. }
    + U% w) _: x( c" g
复制代码

+ E! t2 Q1 X2 \! N% c' J* d" @; Q# Z0 ?" |) o
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 很美好很美好1 很差劲很差劲
回复

使用道具 举报

沙发
发表于 2025-4-12 16:41 | 只看该作者
学习学习一下
回复 支持 反对

使用道具 举报

高级模式
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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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