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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑 ; r3 k% q3 @: t2 z; s7 L6 M( T
7 }8 q$ |3 X* c1 J1 ~
以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。
+ _% u1 F$ u* Y' q, x本代码经过分析以及改写之后,将取代游戏原有的显示函数。
  }  b; ]& E# |4 G  \1 L5 l0 b" y0 H# d3 M* x0 n% P
代码详细说明如下
5 P/ o; r4 q; R2 O9 j4 W% `5 `. a1 g* A5 i" O9 P, B
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:3 [" H3 S/ X) ~
  2. - d1 |9 W6 y% Y, e. C. ^  ^
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。# r( X6 K: q- m. V
  4. ) W) z  [; r- R, Y6 N# Z6 ]& d
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。
    , ]2 V0 o1 ?% m3 h/ c6 I

  6. * B8 P$ Q* e3 n
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。) _& A# g; f- o$ f
  8. - n' Q  x. [2 P. L" \4 y$ ]
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:. `# e6 Q8 D( [* X$ F2 B2 S- ~

  10. ' n: t% `3 i: V; P! i# J- T! |% J
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。' o0 X8 ?* |1 p9 x

  12.   S, h0 j/ D9 W6 y6 P
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。
    5 T& ^3 x2 V9 Z9 N
  14. . f8 e1 R7 X+ v/ B4 G5 U
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。5 e2 ^5 G8 U& q4 D

  16. ) O; S# ?" d/ h' P
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。
    + I6 O' E& m3 O+ l8 }7 T

  18. ) w+ P# ^1 H. Q& J  Y6 }
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    $ q* Z8 B. x& N% ]- i2 C* x

  20. , s% q7 T  _, `. v/ r- o
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。# m: E2 |7 e- }# C  n
复制代码

: C  D0 Z8 n( g' V) F6 I1 u; }& f9 G1 p$ J- E  X* }, [* _; @
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:/ f) N0 h. {3 i3 a

  2. $ |+ U0 |+ |3 p8 R
  3. 参数:
    8 m  Q9 O2 L$ s2 B5 {
  4. 7 X4 H' \9 W5 o
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    & U' i: ]! x; p6 o& ^/ j6 A
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
    . r+ F6 z; N4 |# r$ c+ k4 d
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。
    ) b0 E) _- t8 j* F
  8. 功能:
    * i$ D/ k9 |& T* r

  9. - k: X- g: P- c5 R8 Q1 u
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。
    3 m6 a+ [: e9 _
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。
    / M6 @: K8 _# K
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。
    4 h0 W  U# h1 V" T7 u# Z
  13. 使用示例:
    ' o" P% S2 S0 Q0 Z. Q6 d4 p: L

  14. / n# t! N) C, N
  15. c
    * J+ r7 q8 E9 v5 P, `, f# |
  16. Copy code# m7 [# p5 p. T4 ^' H8 P% P
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);
    8 r, Z2 |5 `% ~) c0 o7 R
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。% a) X8 f3 G' j) o, E  ^
  19. " ^8 u, ?9 N9 [" l5 Z9 R
  20. 错误处理:
    " O# j  }% a6 R. j3 d

  21. # I: x8 d/ f- h; t$ ^6 U: G' j8 c
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。& U9 \  k- ?3 N4 T2 h0 j! c
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码

  x. ~9 E- O1 f3 G; K2 P6 J0 C- ^; ]% z! x% f) s' V% {7 X/ C; F6 B+ Y! X
代码7 W8 D5 A6 `% G# S

. s3 ~& n; y% M5 l

  1. 4 `% ?0 Z0 @2 L9 f6 W1 W. h
  2. . y5 c1 |4 _6 ?" ?; i

  3. ! @2 r( p1 `' T5 }  Q
  4. #include <stdio.h>
    4 ~; q, d) q, |$ n' D6 P
  5. #include <stdlib.h>
    & G+ f' q2 D# l, C9 s( J
  6. #include <GL/glew.h>
    1 ?! B( J/ A+ J) G% ~3 |$ ~* L
  7. #include <GLFW/glfw3.h>3 B! E' q; B& s
  8. #include <ft2build.h>
    " _) r6 u0 e$ h
  9. #include FT_FREETYPE_H
    ; k  |& b9 d7 j
  10. 1 z9 Z, J4 G- J: L
  11. // 定义字形数据的字节数组1 D* X& x8 b. Y. ~+ u* M
  12. unsigned char fontData[] = {
    8 ~) x: D9 X# T8 ~1 w! d
  13.     // 字形数据的字节表示
    / S* f! l( f0 n: b5 }
  14.     // 例如,这里可以包含字母、数字和符号的字形数据
    3 X( c  M4 B0 x7 q" z
  15. };
    + G: T8 m5 b' X; d( q: h1 R
  16. 9 f4 u. u5 \8 v
  17. FT_Library library;
    / H: P. a  r. j. f$ Q9 Y4 l, @
  18. FT_Face face;6 T- t  n5 E: ]. m( C
  19. GLuint fontTexture;
    ' I$ Z$ c0 i/ H* e+ F* N
  20. , y6 S+ _( u1 M" h, I( U
  21. // 初始化FreeType库和OpenGL
    + w: }8 {# ~6 t" {& S& m! o5 A
  22. void initialize() {
    0 t& l, m5 b- g4 e
  23.     if (FT_Init_FreeType(&library)) {
    9 [- A% \+ v( z' I5 |* X; F, l( `9 S3 {
  24.         fprintf(stderr, "Failed to initialize FreeType\n");0 C; A! G- U6 }$ l  B( m( M. S# `
  25.         exit(EXIT_FAILURE);! x# g8 i' w( ]/ l6 I; v  n
  26.     }2 _& E4 Y" |$ L6 v5 O0 ]

  27. ' M0 m, z) i" t$ L/ F
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {
    ' b1 h$ P, l2 \7 q6 G
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
    " Q7 J1 Y* b) p  Z% S- B( C
  30.         exit(EXIT_FAILURE);" r4 `9 G% ^" ^# w0 P
  31.     }/ q" Y2 s% ]0 [. ]

  32. % z3 K$ O/ K2 c
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小
    - U/ f3 p# ?; L3 c+ \. ]
  34.         fprintf(stderr, "Failed to set font size\n");( }8 U, y  y6 q3 D, j% w
  35.         exit(EXIT_FAILURE);/ G% J- g# J# T6 l7 M# n9 g
  36.     }% ~" q+ L0 |' W0 T# ?4 i$ n' x

  37.   p- S: b" |& D6 q0 I
  38.     glGenTextures(1, &fontTexture);* |* G$ S) w( H( K2 @1 t
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    ' g- m8 R0 D/ L6 P+ u
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    7 S& H3 S1 x/ j7 I

  41. # H, Q5 _' |$ o' \4 ?. N
  42.     // 将字形数据传递给OpenGL纹理
    3 s' c2 p" C: K" |, n
  43.     for (int i = 0; i < 128; i++) {5 ^$ o- Z* \+ \7 d* e7 m
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {3 W' N" O" @+ I( P+ X, M
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);
    * `/ O. N8 f5 [. I  p4 T
  46.             continue;: p- ]9 |+ ?' J3 C' i% G9 O
  47.         }
    * x4 h+ V, l3 y1 _- m) a. W' E
  48. - `- c, B: Y: f$ Y& P
  49.         glTexImage2D(
    : y( A; V8 p, n$ N* w2 T
  50.             GL_TEXTURE_2D,) |& T* {; |9 x4 Z1 s; t% G! E9 {
  51.             0,
    1 R% ?4 J7 D, v9 a  D- O4 c( ]  Y
  52.             GL_RED,
    * ~3 p8 m- @& w, y
  53.             face->glyph->bitmap.width,5 n) n2 q/ l. |+ n2 X8 ]8 y% ?6 h! `
  54.             face->glyph->bitmap.rows,
    7 i8 W0 f* H2 x6 S! d) Q2 B
  55.             0,
    . V* ]4 s' A6 p0 O5 K' i9 o
  56.             GL_RED,0 o) o$ O( A' @0 g4 P
  57.             GL_UNSIGNED_BYTE,9 z* Q  m$ Z* ]6 x5 L2 S. U* S
  58.             face->glyph->bitmap.buffer
    7 a1 i7 c, z: I, |  Z. M4 W/ `
  59.         );1 P: [6 t1 E6 Q

  60. 5 y, M0 M$ C- C2 |7 B
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    ! N" G) |4 S" @
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);+ ~: c( k& |) M$ ]* @
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    # T# k( O, R  F* _) w$ k: N
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      O7 B- x# R  e5 J
  65.     }/ \6 F# b/ M1 }/ c2 @  {8 z
  66. }( V* o. l- ?/ x' L1 {
  67. $ i6 i7 E; O( ?1 D6 j7 v/ F- M
  68. // 渲染字符串
    $ }: r7 S3 r% O1 V
  69. void renderString(const char* text, float x, float y) {
    " f4 u4 h( t; P
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);" U7 T' s& ?  F0 `; Y2 X
  71. # ^6 s1 R- k. ^# X/ J, n1 ]* b: R
  72.     glEnable(GL_BLEND);
    ' M  ~, Y, K3 @- S  N
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    1 Y" Z. @7 f( a9 e) H& z
  74. : D+ a( C3 F, a( `0 _! V
  75.     glBegin(GL_QUADS);
    3 U8 ]% q: K9 g! c
  76.     for (const char* p = text; *p; p++) {; }  v7 U4 v6 K, F$ K' g/ k. \
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);
    7 {- o, z. a8 L6 {9 ?. w, Y
  78. $ P& R2 h1 n& l9 d( W7 y
  79.         glTexImage2D(
    ' b' |4 L8 Q3 ~  H/ Z
  80.             GL_TEXTURE_2D,0 V8 ?' Z# y9 ?
  81.             0,
    " z& M" y4 v# q& m8 w( r
  82.             GL_RED,0 i; [) e$ U1 a; t$ i$ Y2 j5 H
  83.             face->glyph->bitmap.width,
    8 i0 z+ A8 S$ M1 S# ^( {( w8 h
  84.             face->glyph->bitmap.rows," }: o) O( u! h9 y
  85.             0,' {; X4 c+ }$ |/ l
  86.             GL_RED,. k( ~3 i# @" e* _. H
  87.             GL_UNSIGNED_BYTE,
    & [6 @1 W1 G% P# \+ g8 `8 ]5 D4 K' H
  88.             face->glyph->bitmap.buffer0 l8 v+ c( K  e; d3 M7 {' ]
  89.         );
    0 \; h, t# x6 H4 W6 V
  90. 8 H+ P9 R3 E- a7 A
  91.         float xpos = x + face->glyph->bitmap_left;0 S' H. P) j5 H  A2 y8 ?
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);+ P9 }9 i3 K( N5 `4 w6 |) Q
  93. " G. ?5 m5 x; R' Q- o
  94.         float w = face->glyph->bitmap.width;
    ! G, _3 @8 T, [( z
  95.         float h = face->glyph->bitmap.rows;
    6 Q  F% g6 i. l1 F
  96. 6 }, a7 ~1 ^& R3 g8 P
  97.         glTexCoord2f(0, 0);* t- @7 X; H" B
  98.         glVertex2f(xpos, ypos);$ W, ]3 x6 t. x# G3 Z4 j
  99. 7 k0 c2 l5 s# Z' k8 U) l0 a
  100.         glTexCoord2f(0, 1);$ s9 {) g- i: H. {' a6 R$ W! h  i
  101.         glVertex2f(xpos, ypos + h);
    & s4 @7 g; W: U$ F5 I1 i" y1 A! W3 v
  102.   i2 a( b7 S! k  h. Y6 `/ q& ?
  103.         glTexCoord2f(1, 1);8 |. K4 A3 {0 @8 Q, q
  104.         glVertex2f(xpos + w, ypos + h);! E# L0 e1 p5 I5 Q2 f4 f, ?: J
  105. 8 }  `7 ~3 _  p. }
  106.         glTexCoord2f(1, 0);
    + r5 F/ x% n% Q: v
  107.         glVertex2f(xpos + w, ypos);. r4 N1 ?8 \6 ^9 H" Z/ u

  108. * S$ l0 J- u% v
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距
    0 S( S( ?9 s% N) u4 _( w
  110.     }" K# Q0 x, U" C$ z# l% c; C& |- t- @6 i8 Z
  111.     glEnd();/ P4 j) z% {4 N9 N+ S, q

  112. 2 ^' F$ [: j6 Q, P9 W# \
  113.     glDisable(GL_BLEND);
    1 q; h$ V/ m& w5 c7 i. T1 L5 W1 S
  114. }/ B& k/ r, ^0 n
  115. 7 t4 ?7 A$ L; }5 m* n
  116. int main() {
    ; d- _  f; o1 P% W* W! D
  117.     if (!glfwInit()) {* A. }5 {: K" n. l: c
  118.         fprintf(stderr, "Failed to initialize GLFW\n");0 ]8 [& k. W# s- a, c8 n3 x
  119.         return -1;( n8 d' Q- b# b, e9 |+ E' K
  120.     }
    ' H( u# X, X3 t" k$ a

  121. . l0 G: Z1 P4 r0 B
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
    & r3 M* _6 {: {
  123.     if (!window) {
    " m* O  q3 S: h) m  U
  124.         fprintf(stderr, "Failed to create GLFW window\n");" X5 I4 X5 E$ U; r+ ]
  125.         glfwTerminate();5 {8 e- z2 {) F, L
  126.         return -1;3 |; f- F% H/ j
  127.     }! C+ ~* K1 X( Y5 x* b1 f$ z

  128.   m7 H& e! J" A" n7 j* Z
  129.     glfwMakeContextCurrent(window);
    ! J" ^% F8 y: O0 {0 H2 \+ _4 p5 k
  130.     glewInit();$ B$ E. g; K7 f( V  _7 L+ n2 D6 N' B+ n
  131. - }" q) y7 w3 \0 g5 i
  132.     initialize();* G7 e) |; [6 i; `2 Q; _. M3 i2 ?

  133. , r; O& n" Q( t. C1 `6 ?8 W
  134.     while (!glfwWindowShouldClose(window)) {
    1 Z9 e+ C. z% ?8 `) C+ r3 h1 L
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);. o. t! ^" Z" }
  136.         glClear(GL_COLOR_BUFFER_BIT);9 t5 y" v  V$ Z: V$ \! o2 k' E7 B
  137. 6 W: ^. y) Z% B  z
  138.         glColor3f(1.0f, 1.0f, 1.0f);
    " j7 o7 G" i' B: p5 t- W
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);
    + l& [+ U' `" e& r

  140. : V& `1 U5 D( y3 L0 l! f1 h1 i; ^
  141.         glfwSwapBuffers(window);
    . V! i5 j+ V7 Y) ~9 b: ?3 l" Z
  142.         glfwPollEvents();
    8 d3 O0 D$ K6 J8 ~
  143.     }4 @( j9 a- ]( {6 ?/ R

  144. # e6 Q/ u4 Y* E' u& J7 u% Q
  145.     FT_Done_Face(face);. G6 J" a# A  e* x' t
  146.     FT_Done_FreeType(library);
      X( u) N+ z. ?3 p( \

  147. 3 r. v+ m) |$ o3 s, z; f: Q
  148.     glfwTerminate();) A4 V: E+ U; d0 F% n% F$ R

  149. ; \) F* i) U* t* x$ z5 z
  150.     return 0;
    $ C$ Y" [& \# q, R2 J% E1 \9 x3 T
  151. }7 S2 o0 K! t9 \3 H# c& R: V
复制代码
/ D% K) E4 Z4 o+ v- W: _

& R5 y6 S, W$ V, V
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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