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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑 + A; u+ ^1 p: H( A. B+ V- V, d

2 G% Y# i8 h% w4 G以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。
; b) Y- i! W% R+ r$ C本代码经过分析以及改写之后,将取代游戏原有的显示函数。# H  E6 \4 b+ ]; v$ P6 t( R5 t  x

1 E2 o) i5 d: s- o5 c代码详细说明如下( ~$ A1 h$ O# n! R

; w  \' F7 k/ c+ u' n: T+ Q* m
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:
    ; {3 a! s3 h' j; d" `+ K- c2 m
  2. ( i# y) x- O" a& r2 ~4 h7 I
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。3 C. y, O3 y* K2 M
  4. # b& b! B" h/ |# F. x8 a, Z: i, k& q
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。: Z* u) o% v0 d0 p, t8 N

  6.   c% S, m. U1 H9 w- A& W# j
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。  V  D' Z+ O9 }2 E7 f" q

  8. ; x( f& Y8 A3 r" V
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:
    4 q  y5 f& ?; @$ s% ]4 v$ o8 h
  10.   d& ^# I4 X; D
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。
    ( `0 h8 D& s" ~" B' O5 S9 {

  12. ) {& V' G: o. V
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。, y3 \# t6 p8 y' B/ ^
  14. 8 Y! |5 s* o9 b$ @
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。
    8 d6 p8 q5 n' s' `1 N6 y& }1 f6 K( z

  16. . z# [' ~3 @8 M9 C8 z1 `( w5 n
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。; y4 c$ b1 Z: x  K
  18. / @8 Y, q+ C- U+ H- N/ u5 f: u! G
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    6 b; g' `. U" G6 `# n1 n" b

  20. " C7 c+ F2 i  ~& p; Q# F
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。4 e. t3 s7 K0 X& ^7 g9 O: n( Y1 K
复制代码
2 r2 _! p8 h+ ?8 l
: E! J: m. ^- s; f5 z
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:8 X& B" F( h6 ?7 V* f% ^2 U% f

  2. ; U. B# D7 P* z
  3. 参数:
    ) ]9 z9 E2 z& t" V9 B+ `4 Y
  4. 8 q: }/ b' u% p# T) U2 v
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    % x  P3 i  O0 U7 f8 w
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
    # T/ h# V/ {) K
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。& w. m1 u' q# r8 c
  8. 功能:% J# _9 L; l7 p) w' t
  9. " q6 M& h- ~  t' e: }( e4 V8 Y
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。# I4 h( C# h/ `9 e: e
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。( i: [% Z4 c/ M" b5 z. t4 L
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。  |: k7 h0 U. F
  13. 使用示例:' |3 E4 P5 m2 n! @4 g% L

  14. 7 P- T- r; O  H- k  W" q; [
  15. c- B1 s: o/ f. A2 {
  16. Copy code8 A( i. d+ h  c7 n
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);# i3 q) ?: K# Q0 ~
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。
    $ g7 }2 `' d+ E) \' W/ }, q/ Z# [) `

  19. ' Y+ b. `5 m3 W) M6 J3 ?
  20. 错误处理:
    7 `3 P9 C; t* B# L4 f# I, V5 p

  21. ' y) b, x6 U0 d8 d5 Y5 W
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。. [  T6 w1 [7 \$ ?8 J4 o
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
* C% w# d0 H8 f. c( o8 V0 N9 {+ j
- l4 l. I3 U8 |$ B) _
代码* L4 ^5 S" j' y. \

* U0 V* L5 R) o- F5 d" d6 y4 C
  1. $ O) X. b$ P1 e/ b, _

  2. ( X; |7 L/ r( K
  3. 5 J0 U; i4 Z3 H! R+ g
  4. #include <stdio.h>
    # _; ^; @/ R( H& o
  5. #include <stdlib.h>& U3 B( t3 L8 w  Z
  6. #include <GL/glew.h>
    4 H/ O& m$ d2 E5 y" Z
  7. #include <GLFW/glfw3.h>% j' Y2 b, u' ~! I9 }/ Q
  8. #include <ft2build.h>
    3 V+ l, y& t% ~2 u+ C
  9. #include FT_FREETYPE_H+ }( J  v  r4 ~
  10. 3 c0 I2 Y$ Q9 A: C# s1 w
  11. // 定义字形数据的字节数组+ G4 V1 x3 K+ ~( l' ?$ V' L
  12. unsigned char fontData[] = {
    ( h/ k6 _( Q  T+ P
  13.     // 字形数据的字节表示
    : q7 W) O% J0 R8 }8 t! `. w$ g
  14.     // 例如,这里可以包含字母、数字和符号的字形数据) }$ p; u4 x3 S9 I0 @5 \# ~
  15. };7 f9 W$ _4 s2 @$ w- [
  16. 3 Q. r7 b/ l% k& }3 h6 N; @
  17. FT_Library library;; v: P, a/ Y- @5 V
  18. FT_Face face;
    $ o% x! A! v# s0 v; C* }2 s
  19. GLuint fontTexture;7 U8 P0 E- B+ \8 J" R
  20. ) u+ P) L; ^7 n9 E: X% x
  21. // 初始化FreeType库和OpenGL! l$ `  c* M3 }0 S
  22. void initialize() {3 y9 D# d6 R. _8 k2 G
  23.     if (FT_Init_FreeType(&library)) {5 f- m% y" c2 b' S% v$ K' U3 z
  24.         fprintf(stderr, "Failed to initialize FreeType\n");# Q( u: k, |. F( \! M
  25.         exit(EXIT_FAILURE);
    , M7 e" q) c5 i) c6 i/ |
  26.     }
    : [6 Y2 E% T. X

  27. - i3 ?' i9 }+ z  K* r# A" e$ G
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {
    0 p9 ]5 A* }3 F; j/ Z) [7 r
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
    * r# v; K' h$ p/ v8 Y; ~. ]
  30.         exit(EXIT_FAILURE);. W6 k% K3 i- {! k6 }, H
  31.     }0 h3 p, k: [; N/ O' k$ c0 @

  32. ! J& [# G  \; ^1 K5 M4 J. }
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小2 }5 w5 s. Y' D
  34.         fprintf(stderr, "Failed to set font size\n");
    ' X4 [: |: u3 N# }* Z+ f
  35.         exit(EXIT_FAILURE);
    : l2 M! k1 ?6 Y' ~# D* Q2 r/ Z
  36.     }4 z, q  S/ h9 j) ]0 Q+ {* x8 @2 G
  37. ) A8 o& c; T5 l
  38.     glGenTextures(1, &fontTexture);
    - F; R! d5 T. R- Q+ h' ~) S0 [
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    5 i$ F0 x. s) x# E6 m2 k; e
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);4 m2 ?; A% ^, U$ n- l& ^4 |4 Y

  41. ; H/ \& E6 ?9 i- [& W/ u2 C! j
  42.     // 将字形数据传递给OpenGL纹理
      U6 Z( u4 G7 a0 O% {
  43.     for (int i = 0; i < 128; i++) {
    ' I& s/ [2 ^/ H' J- F/ Z
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {$ p) Q: S# m- H9 ~; }# L
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);
    + q7 f+ k4 O2 S
  46.             continue;
    0 r( k* z: N+ s4 n/ d7 {
  47.         }; A9 ~% C) v. A' Y$ z7 m
  48. - \$ z1 @9 ?6 q: S1 z3 ]
  49.         glTexImage2D(: U  }4 |, b9 h7 n( ^& b
  50.             GL_TEXTURE_2D,2 {& q: Y( [9 Z$ \9 K
  51.             0,
    ) X* t2 i! Y& z, @
  52.             GL_RED,
    ! ^" P' y- }$ S+ u' F6 E5 l
  53.             face->glyph->bitmap.width,. G- x& G4 z5 i+ y5 J0 J$ X
  54.             face->glyph->bitmap.rows,# [/ n# }2 B4 b( P6 K
  55.             0,, B( o0 J4 {/ k& H
  56.             GL_RED,
    ( O* \" K- A0 H) d' n7 l/ d
  57.             GL_UNSIGNED_BYTE,4 \+ r8 x' @3 ]% D, @# T
  58.             face->glyph->bitmap.buffer
    8 j) J+ w4 P1 {2 u4 ?) Y
  59.         );' A$ C9 N3 D7 a6 l0 a

  60. ; b; u6 |" ^$ x- Y% }2 s
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);; Q( V5 D; L, P( Z. _" u, J
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  h: r; S, E, W  L) y; `& ]
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    % L7 @! `# j! Q3 Q/ ^: t8 {
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);' Q7 |! H* O1 u+ O
  65.     }  F! Y- l" P. k, I, l/ q! z2 z
  66. }) C  y5 r5 f' s% ~; Z" K0 o
  67. 7 B, f% d" y) n9 q
  68. // 渲染字符串
    $ W0 M7 N& F0 G% O( V9 Q+ Q
  69. void renderString(const char* text, float x, float y) {
    , V( S; i/ r0 S4 s2 |& c- b6 R- y$ j
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    & T) c; }# |( g) E5 B" `( p
  71. + s  N' C- K8 X% i
  72.     glEnable(GL_BLEND);9 H1 a" t9 I! R* i
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);0 W: N+ u( B8 F

  74. 7 }, |6 @+ a, v+ c
  75.     glBegin(GL_QUADS);
    7 y( t! d! l. e& `! l- v1 D
  76.     for (const char* p = text; *p; p++) {4 W- j+ z( J' f3 ~
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);
    2 Q0 T% Z2 U7 |, \

  78. 4 m' m, W. n6 D
  79.         glTexImage2D(& @# z# h; t) _
  80.             GL_TEXTURE_2D,& H" k7 A. \* w+ Q! t: U' R
  81.             0,' R% [! E( K+ U, j$ H! }4 R  G
  82.             GL_RED,
    % t1 [9 @6 }" |0 w
  83.             face->glyph->bitmap.width,2 {5 Z  @- a% J* [
  84.             face->glyph->bitmap.rows,
    7 i0 A6 g9 p. g  m, _' s
  85.             0,3 l% i  k) ?: l( G: R+ B& B
  86.             GL_RED,- F" J# z% i# N+ {0 X/ D2 F- A( z
  87.             GL_UNSIGNED_BYTE,1 Y- a+ z; z, d  c( Q
  88.             face->glyph->bitmap.buffer
    1 O" j2 s0 c. e) |" _0 c: Z
  89.         );6 d) Z$ Q& K. l& M

  90. 3 }& R9 K5 P# h& O0 d8 @
  91.         float xpos = x + face->glyph->bitmap_left;, ]* _9 S" a2 _* L- Y3 _" X
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);( [. T# e- `9 c$ i5 F

  93. 0 N: e/ e' a* }+ E; p
  94.         float w = face->glyph->bitmap.width;1 y: m) S, C. R, V. i/ U
  95.         float h = face->glyph->bitmap.rows;
    " t  Y6 B4 a% B' R: t- `: v& K

  96. / s2 }& U" [6 J- q$ P, c8 W% E
  97.         glTexCoord2f(0, 0);8 b% O; y  M3 `$ M$ D
  98.         glVertex2f(xpos, ypos);) c6 T& D7 k7 H9 d# v8 w

  99. , O' t' u7 I" \  U0 c. p* g
  100.         glTexCoord2f(0, 1);
    % ^, e' P1 {+ |; X  {( U7 X
  101.         glVertex2f(xpos, ypos + h);
    % L* G2 M' ~/ M$ b: \0 `
  102. / f2 r  D# o7 \* k$ ?2 l/ `
  103.         glTexCoord2f(1, 1);
    ' r& \5 q! L7 @1 l1 G) e+ s
  104.         glVertex2f(xpos + w, ypos + h);
    0 _4 S  b, h; }5 @" z
  105. 0 Z  S. Y! r! g6 [- j* r7 d: {
  106.         glTexCoord2f(1, 0);
    & O8 V4 @6 {& {9 M
  107.         glVertex2f(xpos + w, ypos);! h- |6 F: C* b% m

  108. & [& V; L  j+ M- g" Y+ \0 |
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距
    $ h$ l* S" F0 c
  110.     }. v" {. @5 \! h% f
  111.     glEnd();/ a, o; ?& ]5 O. H9 ~. Q, Z7 w

  112. ) _, M8 `* d. K3 I, [: O( A
  113.     glDisable(GL_BLEND);
    ( @7 s3 \: B% S! u5 ?
  114. }0 B2 s( i4 b8 S3 e
  115. # O8 ~7 b# f8 [/ b2 D( Y; n
  116. int main() {: ]* H1 {! B+ N' D& B
  117.     if (!glfwInit()) {
    ' o9 |( f  {; G. L" g
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    ! }& C' K. v4 u8 ]6 j
  119.         return -1;9 X+ `! d, }3 K4 A5 m3 ^* \
  120.     }
    3 `5 U! B5 h" z* e+ J( W7 R# n. b; |
  121. 0 i& q6 O; j& q+ V2 t
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
    5 X& l; u' v. W" R
  123.     if (!window) {  |1 c; w. Q' r: G! E
  124.         fprintf(stderr, "Failed to create GLFW window\n");; ~% C. R0 _& I$ |* P3 Q( X
  125.         glfwTerminate();% e$ q2 U* X9 J) P0 n
  126.         return -1;
    6 J3 ^  Z0 O3 ?/ a
  127.     }2 m5 A* ^: a+ y6 `6 t) G
  128. . K3 d( q$ M' a' X' p, I
  129.     glfwMakeContextCurrent(window);
    . o' A. ~. I1 A. K, v) t+ L$ {
  130.     glewInit();/ Q# H7 m3 |7 V2 _- _0 `

  131. . R$ K1 m1 W/ j( {% i, A/ S
  132.     initialize();
    , g! {) V* y) T# o

  133. 7 Y% F( z. c) A3 f( T6 p1 t
  134.     while (!glfwWindowShouldClose(window)) {
    2 f( j: v' a' \# c' m- D% I- a
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
      |$ r# y2 ?7 D- l7 Y
  136.         glClear(GL_COLOR_BUFFER_BIT);" T: I4 e' j! `: e$ I7 Q
  137. 4 s+ {/ Y* q$ n% m
  138.         glColor3f(1.0f, 1.0f, 1.0f);
    ! r! n- Q9 m& o3 n# V) L
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);2 F& P1 [2 ~8 {& }
  140. 4 K5 X1 Q0 n* b' C2 ]" y- f
  141.         glfwSwapBuffers(window);
    . J9 e. N( ^" x& A
  142.         glfwPollEvents();" D  z/ g+ O2 H) f
  143.     }
    2 Q/ i' }4 s$ i# ?  h3 Y8 l4 _

  144.   X% t: S/ R6 X
  145.     FT_Done_Face(face);
      H- r& n2 X6 @. r
  146.     FT_Done_FreeType(library);; e' U$ P2 M6 n: e) X

  147. 3 @' Z+ Y2 y5 `+ {: \& ?
  148.     glfwTerminate();
    1 |# e$ d7 n! T* W1 }! Z+ t6 ?
  149. ' i6 g+ O/ G8 |+ O  v* ^# B  M$ C
  150.     return 0;
      B0 Z9 L5 x$ B- a  W
  151. }
    6 n3 ~! H5 _! ~/ C6 n
复制代码

) t' ~& X" e& o8 W7 ~' D8 F6 S$ f4 u
6 R1 T+ L: K8 |+ X$ R7 i% m! Y
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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