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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑 0 N8 b, f3 ~( Z2 n& h$ y2 u7 @
5 Z' p# N2 T, k! B! u3 ]
以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。
6 [" R* k3 N7 L  b本代码经过分析以及改写之后,将取代游戏原有的显示函数。
' v% p$ F& G( N# f/ {/ ?; o3 U. l" X# j% @; U
代码详细说明如下
5 f- \& h' k# K! ]! e# ^' D$ T. |% |" O/ p9 [  m8 E& x% q
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:
    5 I* J$ t' X0 N6 F2 m
  2. ; b! s1 b( P8 D% z' e% H
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。% \6 h( h4 J7 d% s' k5 T
  4. . Z7 e6 M3 L; E6 g9 ~. t! m7 {; ]
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。
    : h* O1 z2 v) s- g8 i; k- ^
  6. % t' D' v1 Q/ [* p# H! E/ V
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。
    1 {- A4 F8 V% F. _, e0 m

  8. : u, e/ }: o" e# Z: e, l# F
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:+ a2 A9 t" ?: x$ `6 `

  10. # G" {$ o9 a4 Q$ ^8 l) X! I
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。: K8 v' j  c( w) Y6 z8 U
  12. + B3 P* Z+ d8 i! g  g
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。
    / y" W# F5 \' D  S! @7 n: f$ O

  14. ! b. X! n& w+ t9 T
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。
    4 ?$ H7 K7 E/ H1 P: l- j

  16. 1 o* v( X" x' H% A; ~, Y
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。
    ) F, H. U8 M3 a% _4 E

  18. * v( o# g, R6 a- N3 z
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    , p- C! \  R4 h% o9 b: y" H: V
  20. 7 K* d! Z: [" C0 D4 b, ?  P
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。5 x: ]1 U2 @$ a  C
复制代码

7 J; ~/ a2 X2 a: ?1 k& X
( N5 G( l% T  p4 S  F
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:6 R6 q. Z3 g. L( r% R9 \: F

  2. * j7 `5 g% d- }) u. P1 E  g0 i3 U6 J% ?2 |
  3. 参数:+ A* z6 B( n5 q
  4. ) E7 W9 s4 j( |0 N
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。/ G9 s! A) p# ]: O/ c
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
    . m/ P0 s5 Q* a  h/ {0 E" k
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。6 w6 `; n$ @" h0 }
  8. 功能:
    5 ?+ ], D& k# W% b1 f
  9. & u% e  W+ b7 r% q) F& T4 Y0 |3 Q
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。; v: w, x" a2 {- P. L
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。- }4 k; ~0 j5 N9 u1 x
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。7 k& X' o5 y+ g- x8 ?7 v5 R1 M) A
  13. 使用示例:0 q! p9 [4 G" }

  14. " \+ `7 X# a1 O$ a2 O& j
  15. c
    : C0 |: u- O, H# `
  16. Copy code
    5 Y, Q8 L# {% N- B+ P; R
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);
    * r$ C- _! k- q$ |; U$ e/ z& I8 [
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。" u9 u9 v" }4 }8 u% s6 G: X

  19. , b$ Q) V* f7 B8 Z- f# w1 X. _
  20. 错误处理:
    / C  Y4 D6 H; V- H

  21. ' c1 W+ q+ X9 j* B
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。* [  E0 v6 h4 c9 m  `+ ?
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码

# _4 t1 b3 X" C( e8 D9 K) _: g& d$ [( {7 W9 r
代码
- l- n" Q) U0 {8 y8 A% T$ v2 @  M, ?5 U+ C
  1. 5 O# [4 D$ n6 V2 s

  2. * j6 j( V; ~* P  G$ H
  3. ' Q3 M( g2 V6 T' |9 I
  4. #include <stdio.h>1 G6 N; {  Q5 u2 n$ u
  5. #include <stdlib.h>
    ' O9 N% `( K; _0 f
  6. #include <GL/glew.h>' g  ~4 T' \/ g) P+ O+ L
  7. #include <GLFW/glfw3.h>
    ! L- n; ]! ~; m
  8. #include <ft2build.h>1 J$ _( S* Q- q! `- L9 @6 P: p& C
  9. #include FT_FREETYPE_H' Q) {* {* a: r% C
  10.   F$ ~7 ~: g: S8 n, p# ^3 I2 a
  11. // 定义字形数据的字节数组7 P" H2 h( h# c  d
  12. unsigned char fontData[] = {
    5 c/ E& E( k  X. Y: n
  13.     // 字形数据的字节表示
    ! }' `& W+ A7 O* X2 J1 ]
  14.     // 例如,这里可以包含字母、数字和符号的字形数据
    ' h  T' i* _! Y/ j9 Q3 r. d
  15. };9 w# e$ o2 W/ C! F
  16. / |" s+ x2 b* D0 w' j
  17. FT_Library library;
    ; M6 l, ?$ ^# h
  18. FT_Face face;
    ) Y" a( N6 z( }7 c! l! @
  19. GLuint fontTexture;
    7 V! \, U4 ]6 G
  20. ; b" ^& N: T+ n" o# H+ I3 P
  21. // 初始化FreeType库和OpenGL1 j, @& T7 t$ i$ a* I( H0 O
  22. void initialize() {; r6 f: Z+ r3 S
  23.     if (FT_Init_FreeType(&library)) {1 D3 A5 |# b) @
  24.         fprintf(stderr, "Failed to initialize FreeType\n");
    . x& s9 O' F8 n- F& o. ?) i
  25.         exit(EXIT_FAILURE);
    " F" p8 Y1 v" O$ M! M. E* [  b
  26.     }
    1 I; l/ V4 B( g" b  n9 A0 Z% O
  27. 1 A/ G; }# {4 p2 V7 B+ x
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {# Y; ^; `( j, D0 B
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
    % t# h' F3 R( Y# k4 Y
  30.         exit(EXIT_FAILURE);4 ^# z" E/ z; o* t+ f
  31.     }7 ^# A) e, D3 h# c

  32. # G5 M2 a: T/ o0 A
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小
    ; H# u- {5 \; g+ l0 K. Q: R# u6 N
  34.         fprintf(stderr, "Failed to set font size\n");
    . A' R  W6 _5 e$ R4 w
  35.         exit(EXIT_FAILURE);8 H/ u% v' g( N
  36.     }( `  l8 @( P6 K: F+ t' Q
  37. , [  e, T" F8 D; G
  38.     glGenTextures(1, &fontTexture);' ]4 \. f: b( Y8 P: r
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    # i8 a3 s9 L. w3 Y( ]! W0 p
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    2 a/ O- B0 S" }9 ~: e( z+ G

  41. % ]: R# |, \) ]! m/ o3 V) v
  42.     // 将字形数据传递给OpenGL纹理' [9 N% r( P4 N* M; D6 C% L) W, k; @$ {
  43.     for (int i = 0; i < 128; i++) {
    1 |2 ~: @5 ]. W7 F/ N6 ?
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {8 \8 H  F# G& ~8 k
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);, ^6 _$ r4 P9 R8 ?: t, j+ k5 @
  46.             continue;
    ' s' ?! S' S8 C* e6 r9 o; V8 O
  47.         }
    1 u' F( F# T. [8 V7 `6 z

  48. " R$ r. e) j/ K
  49.         glTexImage2D(
    ( l. O9 t4 _: M( j; C
  50.             GL_TEXTURE_2D,
    : L. s" C! k) a& {' W7 {: Z( M
  51.             0,
    $ L! {4 D! q: w8 f$ h; q
  52.             GL_RED,
    $ F& ?/ A' {7 Q
  53.             face->glyph->bitmap.width,  T6 z* t) s* \* Y% P
  54.             face->glyph->bitmap.rows,1 u  _$ P9 T& c5 l6 |: s8 S6 s
  55.             0,1 W! v6 r1 e4 j2 J% X  a0 i
  56.             GL_RED,
    $ X+ i0 A5 z7 w2 D* U
  57.             GL_UNSIGNED_BYTE,0 B9 t# H% V7 t5 L
  58.             face->glyph->bitmap.buffer
    # F7 e* Q" g- r. s9 ^! _
  59.         );
    # i9 J+ c# S# k! }
  60. : ^- t7 H! G! g1 Q' I2 x& z8 S
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    9 ^1 t9 ~6 i, |$ ^2 J- ?9 m0 G
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);0 J, w8 s+ W) V1 |
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    ! E. @) e' }3 C7 S/ c: D
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);0 m$ ~$ {3 c. W2 R* n: Y( N
  65.     }2 k9 P( B* h0 p% B
  66. }# K! P, d) h3 j* N
  67. 4 V1 s% s* C. s: Q& }) f
  68. // 渲染字符串
    9 }2 |6 v4 _: y# P6 M3 ?9 l
  69. void renderString(const char* text, float x, float y) {3 c1 a3 w+ a' U) x7 I; {2 l
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);2 W& r! N, h+ z$ ?) L
  71. 1 R" i$ f; o. e
  72.     glEnable(GL_BLEND);
    0 t: v: l9 q4 y2 F0 o9 _- F
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);) }0 `( Y- Q0 d! p

  74. 3 E) V; o: P% J# e6 b
  75.     glBegin(GL_QUADS);# m8 M3 [$ q% O6 a6 d! K/ L& M+ D
  76.     for (const char* p = text; *p; p++) {8 F" H3 N4 x6 h  q2 R
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);
    # i* x" X6 D( c
  78. ) d1 @  W3 l! k1 w: x
  79.         glTexImage2D(
    - c6 X( i4 d4 v, {( |( a+ X
  80.             GL_TEXTURE_2D,
    % ?4 v1 @7 G2 ]2 K
  81.             0,2 [( M) X3 p$ @; y; B# x
  82.             GL_RED,& J6 B! d- }! G4 E; I0 M
  83.             face->glyph->bitmap.width,
    % X8 R  i7 \  p" k3 P
  84.             face->glyph->bitmap.rows,* D4 m; o/ a; |  a
  85.             0,+ f! s  G$ y$ }9 h$ U# ?! M6 M
  86.             GL_RED,
    1 V6 X* {0 N. [1 G  u
  87.             GL_UNSIGNED_BYTE,2 T! x2 x; B5 X* x
  88.             face->glyph->bitmap.buffer
    / O# y; ~9 G- I
  89.         );0 {  ~% t& _/ D6 x# {3 \

  90. ) o& V: I; X. ]
  91.         float xpos = x + face->glyph->bitmap_left;
    ) u* j5 j. F% X$ A  ~# n7 B
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);6 {7 P& j3 \0 l9 g

  93. & G2 D6 {) _# U, b
  94.         float w = face->glyph->bitmap.width;. W% a+ n# T3 V- @7 }" L& C8 ?- f
  95.         float h = face->glyph->bitmap.rows;) ~' u+ k! K2 S% ^9 `8 c3 h
  96. * u/ G9 w7 a0 }5 J2 N: j- F0 I
  97.         glTexCoord2f(0, 0);
    ; i2 K  U1 N" ^( y% N3 n
  98.         glVertex2f(xpos, ypos);) \) R  ?! \: I- ]
  99. 1 K: |. {! e5 {! f$ `7 t9 U
  100.         glTexCoord2f(0, 1);* `0 M4 y: Z. _6 \# z2 ~  g
  101.         glVertex2f(xpos, ypos + h);
    & j) f- A& g5 d; k3 \
  102. 5 g4 n2 m) q: V2 n7 w' x3 U
  103.         glTexCoord2f(1, 1);8 B0 W; J: e1 ?" }" p
  104.         glVertex2f(xpos + w, ypos + h);
    ( m/ d6 ?% M0 @& U4 x6 r; b& Q
  105. : N* S! T; p) C$ m. V
  106.         glTexCoord2f(1, 0);
    # A5 M6 N1 U# [0 I
  107.         glVertex2f(xpos + w, ypos);1 ?1 R- C( Y9 f

  108. 7 c3 v5 n4 t  D4 E$ H. @
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距- H7 W9 N1 ]7 O  Q8 r. ~- c
  110.     }; r' }3 W- d7 g# @) M
  111.     glEnd();
    $ W+ Y5 |, A6 a8 r

  112. # }9 `# _9 S( c4 t- |- D; p. e1 U2 g
  113.     glDisable(GL_BLEND);
    / ?' x/ R9 X5 l7 ^* N  f& j% a; Y
  114. }
    0 e2 l4 O. s: g1 H
  115. * @7 T, w7 e* U4 {& I6 g8 a
  116. int main() {: E4 a6 t1 z- G' Y
  117.     if (!glfwInit()) {0 R5 H1 a; l$ S3 k. ?
  118.         fprintf(stderr, "Failed to initialize GLFW\n");- K- @, I% i2 m: k' t1 v# b- A$ ]
  119.         return -1;
    - h  {$ a% k( c8 J6 f9 z
  120.     }$ C+ H! ]  Y, p" }- @# ?. I
  121. 5 `! c  M5 `- q4 d0 z6 p2 {: L3 i
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
    8 `4 X$ I: M/ n0 Y  r0 l- L
  123.     if (!window) {. I* v* K0 I$ R: W
  124.         fprintf(stderr, "Failed to create GLFW window\n");
    4 v, o# @, P: w6 X2 ?& H
  125.         glfwTerminate();  Q' X+ G# J$ A: b+ V* q3 c, J
  126.         return -1;
    3 ~4 J! @9 E, \/ b7 |
  127.     }
    1 d( O: }: C, f( {3 W% H: E

  128. . ]0 j! w6 O& |
  129.     glfwMakeContextCurrent(window);3 _1 u* m& W, a9 j1 v. ?
  130.     glewInit();# |2 }' N. _. f& x7 L- H8 e9 h# \

  131. : w+ w' U" u' \3 {& c$ v* p
  132.     initialize();8 ?! o' `6 E4 w: A! A' [/ m4 p

  133. 7 e& S3 k; G: c
  134.     while (!glfwWindowShouldClose(window)) {
    & D1 q1 n- O) t: ~; T' w2 Q; R
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);) d9 j( E; k( X/ d& a
  136.         glClear(GL_COLOR_BUFFER_BIT);
      ]+ p3 r* [9 n) J/ f8 g

  137. 7 _( f/ I8 U8 N, x  o/ q" H- _6 y
  138.         glColor3f(1.0f, 1.0f, 1.0f);
    ( V. N6 x; l. Q/ v
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);
    ' u4 b- |$ \0 X. m/ Y  D
  140. ' v* L; h4 E- l  s4 x! I
  141.         glfwSwapBuffers(window);
    ( |" S+ K  s3 j3 k
  142.         glfwPollEvents();
    ) ^8 X( ~/ u& ?( N# D% O
  143.     }
    + A- q  G/ d, b% x) Y
  144. ' N7 V4 Z- N* C0 u" O6 ~
  145.     FT_Done_Face(face);7 l7 z7 f) D9 H2 Q( X4 {
  146.     FT_Done_FreeType(library);
    0 d' B/ i* C& _. y

  147. + Q8 ~+ u! g2 L- M/ C" H! ?' y
  148.     glfwTerminate();
    2 \) z" Q8 @+ K9 g1 u' o
  149. + v2 \8 }9 S( q2 R# W
  150.     return 0;; Y$ _0 n* Q6 E! `+ S1 S3 \; C6 O
  151. }
    - J- e2 |4 K$ ~& Y8 U' t' S9 j
复制代码
8 b8 i5 I, `" }( A+ q
$ i2 x: i3 g6 B1 J! N- b
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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