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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑
) t" X& o6 D' U9 [* j0 b. @* q+ a! q5 j7 X! d% f/ H3 `" m
以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。
5 ?  h2 M3 z: U# M' T本代码经过分析以及改写之后,将取代游戏原有的显示函数。. a7 Q- e! e  }. g* g& t

' J( q/ k- I/ s" C8 ]0 m5 B代码详细说明如下/ ]  [& _, I- \; O% L, C

/ P1 \' M: ^7 U+ A( P
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:
    , q; V9 T! L; f8 g" E3 A

  2. , y1 a8 T8 v; R
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。$ M8 y3 W' H" v: y: @+ Q  J$ {

  4. ) d: ~4 ^0 G1 b+ k8 u
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。8 s+ D8 Y! M8 O) e  [% j
  6.   r2 R' A5 A$ R& V3 U2 H& F
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。
    % _2 O' t! P9 D# B, w$ ]# c

  8. : I) k2 r# O. S
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:( I& `6 i# G* ]- c. {

  10. 2 d2 M+ Q2 P) H0 N
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。/ v& w* @6 u# Z" k" B; O

  12. & u; V* X' E/ D( G, a; b+ I
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。: B( T# l/ P* T
  14. 4 F4 C' ?2 `3 _: d. Q( |# g" c
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。0 d! k5 d% \+ [; ^0 @% T
  16. - B$ N/ D7 Q, i- V3 G5 @3 @
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。
    ; U! B0 A" G/ R9 I2 F

  18. ! o: H% r( a4 x- p/ Q- ]7 w
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。! Q  _4 t& Y2 C

  20. ) D/ k+ {9 L- t- B$ j" ^
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。. N" G' |9 v- C9 \$ x$ n& m
复制代码
- m' G, j9 ~, h, w/ q% Q9 D3 B
' L2 r2 L2 ~! w8 D; b
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:$ O- [6 p  i- _8 n: \

  2. 4 E7 z4 a9 d) Q$ M/ O; `
  3. 参数:
    & G' A* v% Y* R  ^  d' n0 A' }

  4. 1 u; W: a! q% y8 d$ R6 P
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    % \0 s5 g9 c) N  d6 z
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
    . E6 I4 w, g  |5 {4 o1 C5 Z
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。' J3 _7 X1 Q% ]. N
  8. 功能:: \) i. ]# q9 t9 o- @! n& D
  9. * Q+ s( I/ l6 Z# B$ n+ h% O, l
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。! i# Z/ W9 r* \7 O$ W+ a
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。
    # Q3 W5 g: T- X$ ~% b
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。8 @- w- y  H% k" G. B
  13. 使用示例:
    ! c  u1 N. b+ c& P$ M
  14. : E. ?3 W) r3 _6 E% C/ w. i( V
  15. c
    9 Y1 ]( Z$ m& l' i1 P
  16. Copy code8 ^& H6 q; t- A% l8 \9 M
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);
    " ]' ]- x' q: r! |
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。* M! {) |% v) d9 a. n( W7 d2 [; l- ?6 B

  19. 9 S% L. V5 ^5 i& `
  20. 错误处理:
    4 a5 C2 @+ q7 X

  21. " ^: T8 T# A& w) b! ]
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。
    7 }" v3 k$ h4 m4 _2 O& Z! W% W
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码

8 M5 R2 B7 j+ a& [5 q
2 h8 W2 @; ?% w6 S" W) W3 }代码
- ?; w, g$ a, U- O, X3 _# |
4 W) U1 [) u* E' r# r6 S- k) B
  1. $ ?+ F6 G% x. j, r/ \+ [# O
  2. 6 n3 r8 I4 B) M7 h! `" ^% p
  3. ( l3 l3 C; Z! [! n5 v
  4. #include <stdio.h>
    - {: H& m/ A" l# J: R) ?& }
  5. #include <stdlib.h>5 i8 }6 g6 `5 e2 e4 G( a
  6. #include <GL/glew.h>
    8 T' _" K/ \4 y1 s
  7. #include <GLFW/glfw3.h>
    - R0 R1 _( S* U4 P% s
  8. #include <ft2build.h>  f5 Y1 R+ b' _9 g
  9. #include FT_FREETYPE_H  h9 `. |  F/ b* x6 Q1 W7 L
  10. : e/ A  h7 \$ D, B/ c5 F
  11. // 定义字形数据的字节数组
    + v! _1 u3 D* N8 l: K
  12. unsigned char fontData[] = {
    ! ]4 }* E+ I( q
  13.     // 字形数据的字节表示& P6 {1 k- N! g. T' |
  14.     // 例如,这里可以包含字母、数字和符号的字形数据0 d) t4 T. M: Q
  15. };2 N, N) D$ f8 n4 z& J

  16. 9 I& ^! c2 K2 X+ s1 e5 m' r* D
  17. FT_Library library;! g+ E6 f2 m3 A! ~/ q5 a
  18. FT_Face face;8 p' F. l# `. @" K$ h0 n7 t2 I
  19. GLuint fontTexture;
    5 F& K2 d+ p- U' n) S* e% j+ B/ L

  20. : \' b. O* }+ E$ \
  21. // 初始化FreeType库和OpenGL- o& K( w+ @! S8 I
  22. void initialize() {( U7 v" z9 ?7 y/ }. ]# Y
  23.     if (FT_Init_FreeType(&library)) {
    4 ~1 B" y' e: Z2 a3 x' T
  24.         fprintf(stderr, "Failed to initialize FreeType\n");
    " G3 S0 w" p3 z6 Q- t+ b- p8 o$ m
  25.         exit(EXIT_FAILURE);
    ' x3 j4 _9 y& E1 i
  26.     }6 @. H' q& e0 S  Z: o
  27. ( C5 F6 F0 c9 g
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {0 J1 k! a9 _) T6 s' g3 T6 [& N
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
    : C' H: P. B+ H
  30.         exit(EXIT_FAILURE);
    3 S# m* {: d' O( k
  31.     }
      i+ h6 i2 I' |/ k0 b. p" i! `
  32. ; _, ^" X. s9 G4 O: S
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小
    $ C1 a# x7 W3 J8 @/ P' s3 P
  34.         fprintf(stderr, "Failed to set font size\n");4 Y, c( Y7 ?# i) r
  35.         exit(EXIT_FAILURE);
    & }* [* }! ~9 M
  36.     }  `+ Q2 M* y6 N
  37. * d4 C3 ?6 F# {4 i6 ]
  38.     glGenTextures(1, &fontTexture);% h! P0 V; C8 z% @4 E" k
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);8 t: _. E7 Z) d* V
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);: z2 |9 a6 A# R. G- W" M4 O. X

  41. # A& [7 q: T9 }$ S& n  h
  42.     // 将字形数据传递给OpenGL纹理4 l) ]% }& k; T! {3 e
  43.     for (int i = 0; i < 128; i++) {' a. f7 t% a) o2 K
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {. r& _/ w1 ~6 O( E) K
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);$ g% A) U' z( |  j& P  X
  46.             continue;
    ( ?' s+ x% T. o7 S1 l
  47.         }
    3 c% w( t4 P8 [& D

  48. 7 T; ~- W2 a( \3 z% M; o! X0 K$ B6 u
  49.         glTexImage2D(9 V( X' ?: Y- D) }) ?) X! t
  50.             GL_TEXTURE_2D,. E5 o6 u; N. U' e1 q0 |# }
  51.             0,
    7 Y7 j0 T# |8 t) A; H
  52.             GL_RED,
    # ]8 |( D" m  e3 r, U
  53.             face->glyph->bitmap.width,' ]5 t, M6 B# S( i  V' `/ [
  54.             face->glyph->bitmap.rows,
    1 j+ |7 _+ {( Y4 V$ j7 E8 d
  55.             0,
    * ~. u4 b6 c( P/ |+ C
  56.             GL_RED,
    " Z. d: Q; h: L4 D8 v. v6 o
  57.             GL_UNSIGNED_BYTE,
    ! }& d6 e/ q: ~( A# ?9 B- _' l
  58.             face->glyph->bitmap.buffer
    % i8 T4 i  w/ J" A9 b
  59.         );- B$ x2 q; V0 J% T, v: q3 j
  60. - q8 {+ ~+ O3 e" q
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);- u- u+ `$ u* @, {' Q$ X/ {
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    ) y4 j; o3 q$ ^8 e  z
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);2 @; o* z( }7 j3 p* L, q
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);# P- Z3 \8 U! A; J; {: ~
  65.     }' R! N1 R3 v) H4 e6 B
  66. }
    / Q# A& `. y& ?3 n3 c7 f7 K( A% b
  67. * |5 u; D* M% J8 c: S! h
  68. // 渲染字符串3 \) a& y" g+ X
  69. void renderString(const char* text, float x, float y) {
    6 R* h* F; E( B% J3 O# f; ~1 g
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    , v% ]' Y" y" z/ X* {" Y$ c1 V6 x

  71. & x, k: ]4 l5 d' h! N7 Q
  72.     glEnable(GL_BLEND);
    5 I" P4 T5 `0 y7 l7 A3 n# L& n( M
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);. i1 Y2 t6 w! z6 {3 S
  74. * w) H" a7 _  k" l7 t5 h! u
  75.     glBegin(GL_QUADS);! x* [/ ]0 Y6 S( n/ H% C' V
  76.     for (const char* p = text; *p; p++) {/ |2 H) E! @) h: M* K' E; J
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);
    5 L# K$ P: D5 U6 {  \( f$ I
  78. ' N) |  }1 j3 M1 m6 _; c
  79.         glTexImage2D(
    . |& G* r/ j/ s" O: j
  80.             GL_TEXTURE_2D,
      f9 @  P: [! U' G% m, K
  81.             0,9 T' X/ H/ h! ~0 ?1 f
  82.             GL_RED,
    & F4 p: v: p  |' ^+ ?- W! E
  83.             face->glyph->bitmap.width,
    7 x  f$ n& V  C9 G( I6 E
  84.             face->glyph->bitmap.rows,
    9 \4 g6 }- T! h& f$ ~
  85.             0,
    0 N: M  F' E( a# _
  86.             GL_RED,
    # H7 A1 L* w9 o) A
  87.             GL_UNSIGNED_BYTE,- M" S1 l# d) N% f! p2 B
  88.             face->glyph->bitmap.buffer) ^  Q! x5 W) o7 L5 Z& v
  89.         );
    ' ]# ]3 @. e1 x. a$ l: r! a2 k
  90.   d8 J& k5 @/ `  g
  91.         float xpos = x + face->glyph->bitmap_left;/ [/ L6 U& X: ^. g
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);
    - ], x5 |- d9 N) Z& H4 ]  i
  93. % ]2 b: t5 @% Z7 M
  94.         float w = face->glyph->bitmap.width;
    / s/ h5 v: b2 j* @' h! [
  95.         float h = face->glyph->bitmap.rows;! \2 q/ P/ O0 D, M. W

  96. $ U2 A4 k$ y% H5 f
  97.         glTexCoord2f(0, 0);
    7 i3 s3 |& x# A" X0 S( X
  98.         glVertex2f(xpos, ypos);
    3 ^- @# c3 O$ H+ }; e: l  }
  99. 5 E( B; D3 ~* A8 d1 c
  100.         glTexCoord2f(0, 1);5 @$ _9 A* `  I6 ~5 V6 x( r
  101.         glVertex2f(xpos, ypos + h);9 B3 j' V0 ~7 L  O
  102. 5 m* A# [) w& k$ A1 d
  103.         glTexCoord2f(1, 1);
    - m- c0 p9 @. f9 O+ C
  104.         glVertex2f(xpos + w, ypos + h);
    ! u' H: O5 C, I7 Y  s2 E
  105. 7 a4 Q+ ~* _' `+ t* p
  106.         glTexCoord2f(1, 0);0 ]9 Y8 m# |& Z
  107.         glVertex2f(xpos + w, ypos);, @7 G9 R# t7 i) [

  108. + s( U9 ?9 Q& b. Q3 ]! q
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距. o1 F3 I" r) \8 O8 a0 R& r
  110.     }
    , [1 I& T6 A) o1 i, {7 U0 W
  111.     glEnd();: c- Z  q" x) X, ^
  112. # r. @0 b! k* o( t# h1 c
  113.     glDisable(GL_BLEND);
    & g) x) @) E, @; F
  114. }
    $ x9 v6 C+ A- S) B+ d1 \2 W5 J
  115. . b! t) B# G; x# W3 n
  116. int main() {
    5 |8 e8 F" r$ {
  117.     if (!glfwInit()) {! x4 @" q( t5 C# T6 _5 U
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    . X  V0 M4 w  |8 p$ |" b2 ~
  119.         return -1;
    ) k) K3 X7 F7 h
  120.     }
    % `3 q( u) Z& k. p

  121. ; N+ @) n# G- c! n7 G
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
    1 k* ^' ^8 y4 a6 Z" I
  123.     if (!window) {
    # G" W% ^4 M9 o1 ]# c/ x9 e3 K' p
  124.         fprintf(stderr, "Failed to create GLFW window\n");( L. V3 b/ b  p) k7 ]9 Z5 U
  125.         glfwTerminate();! l! o9 d/ s8 A: f
  126.         return -1;
    7 g" [8 o2 P5 B% T4 l! M$ Y+ j8 f
  127.     }
    6 v9 ]9 O, }8 J7 r/ n& I9 m

  128. + ^" x" b$ G( h! V2 ^
  129.     glfwMakeContextCurrent(window);
    8 T" @1 r1 _( L3 l+ z; P- g
  130.     glewInit();
    . U8 L8 }+ U$ G, q

  131. 8 V1 W9 e* {; ]6 b
  132.     initialize();" o0 u3 c4 G! D) j* j4 i

  133. + t+ h- T( b3 ]" ?) U
  134.     while (!glfwWindowShouldClose(window)) {
    5 e& N9 D2 u6 ~2 S3 C% |* ]
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    4 q& N, r: Q' J: [  D/ C
  136.         glClear(GL_COLOR_BUFFER_BIT);
    9 Z7 M% s8 j/ {- a3 j2 x0 J

  137. * d9 I5 J6 s8 E0 J: }7 E; l
  138.         glColor3f(1.0f, 1.0f, 1.0f);4 k8 w, F! M2 i" a
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);# F7 s' S. y9 K. W3 h- u

  140. 8 n2 o% f8 ~& ^
  141.         glfwSwapBuffers(window);
    ( V  ~4 |, C2 e! n' P; ]# U( D
  142.         glfwPollEvents();
    6 z, M. d& J: [0 g. ~  @
  143.     }
    0 f$ H& z$ c0 f  w$ O6 q" `8 J

  144. ( r6 i/ ?- E+ c3 L3 t) {3 s
  145.     FT_Done_Face(face);
    . X1 D3 _: V& K/ K7 [3 L
  146.     FT_Done_FreeType(library);6 f0 W7 G$ s9 y, w* B. R5 K
  147. 8 J2 I1 X% j, g/ w
  148.     glfwTerminate();
    ; k' U1 c( w1 I3 {6 W+ c; \
  149. , O2 t3 H, n  G! a
  150.     return 0;
    ! \5 D7 R8 H- F
  151. }
    7 }9 S  ?+ y. {) h6 v. R6 G
复制代码

4 T6 P% o- O! r$ S& M8 w& \5 P" _3 k( G
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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