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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑
- w6 _) d9 M2 S2 p" G  A; r$ b7 o' M, ~- l4 i
以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。! R; I4 @3 A3 h' g% I
本代码经过分析以及改写之后,将取代游戏原有的显示函数。
4 ?/ [% |( z6 B; F/ f
, F6 M- ]7 f. s% Y! d代码详细说明如下! x/ \5 W/ P% |' m
  |# v4 C# t5 Q' N& @' H
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:0 X4 Y8 l+ G! ~
  2. 4 r) \2 c! ~" A( l
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。2 q" G' h, ~: @: \- l$ \

  4. + e8 V- o8 W5 O
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。
    ) `- R8 S% _, ?9 h8 y

  6. * f  |! c' r/ x6 t5 j! c
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。5 d5 i) G! ^* V7 p5 H3 X
  8. ; k* u6 D" h, T- }, H
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:
    : q9 r/ |+ o, q, B& l' D

  10. ! i  Y0 i4 I7 t, M
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。( Y( ^: `/ F& L
  12. 9 n* J- ~. f: `5 T& a6 |
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。
    - j# c: B* h+ r7 q) z# q
  14. - x* {9 Q: F3 k3 H/ B: `
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。% D+ b4 ]7 ^; A9 @+ D7 B2 ~

  16. 0 j' o4 `6 q2 {1 C
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。2 S0 R( B: Y3 c! r. o
  18. 7 H( V- G5 }/ u
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    * N: _3 ~# @5 C+ C( K& T

  20. % v- b0 N# I% j7 w! j, m
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。3 Z. A/ O0 @4 X0 ?0 Q# b3 E
复制代码
0 O6 d. Z* ]. ~  S2 v( ?# e: E" X9 I

" h6 A$ ]& U2 a' e
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:
    ) T) w& z8 u$ O( ^. ]8 u
  2.   F, }% m9 u' P- l& R8 i) s
  3. 参数:3 t: q& W# c4 w8 Y
  4. ( l& U% W+ }& O2 e& Z" W7 l& {2 j% w
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    " V; X. N+ H$ K8 l
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
      ?# [9 v) N) L2 \0 H; Q% R
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。* I6 D: g) r" a/ _
  8. 功能:
    . i1 p/ l3 `" G, V& y  Q
  9. ! g) H3 l+ n. @9 }
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。
    / w/ P% C: X% {: e: n
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。
    : o8 D& E6 e" f) q8 |
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。3 }0 u, O2 K- r7 w5 b( h  U
  13. 使用示例:2 c' @$ ^% C: q( Y: g$ w( p

  14. : ]; d% ^8 p3 L# ?9 \
  15. c
    - \& \  ?7 V+ D
  16. Copy code
    0 S6 |+ a! ^# M+ V9 p( `5 X
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);0 v; g' ^1 m* y0 s2 ]. r
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。
    # A% T0 z5 d8 r$ x$ T) }; ^
  19. ) F: a& ]7 S+ p$ y3 w! Z. _
  20. 错误处理:  X/ U/ u" q: V7 S, \5 g: Z. ]' f
  21. ; S0 }$ U- k1 d2 c
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。' @9 B/ n8 k7 a, o( d1 R
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码

% I8 F/ y: Z" K/ \1 R# G6 k6 s" H& T- Q. e6 w2 b6 A+ A
代码2 K0 P, h8 i- g1 M' a

# p8 V* i8 ~! }+ l3 `. O0 S3 s
  1. 3 |0 |# j- O. n) \% M2 R

  2.   V* G4 D: m+ l1 d
  3. & o9 d) E! R* F1 e# F
  4. #include <stdio.h>2 p+ Z( h# D3 c  K4 }0 x
  5. #include <stdlib.h>
    6 U! k( P, y/ r
  6. #include <GL/glew.h>
    + h  o) v8 V! H3 Q. o0 \  J' q
  7. #include <GLFW/glfw3.h>
    3 M1 G1 U& [% G! r, v' V% w2 ]' ~
  8. #include <ft2build.h>
    2 B% H; r1 f0 X; I, H' z3 w
  9. #include FT_FREETYPE_H7 ~- _$ M, A2 q+ ~
  10. 4 m. K4 {+ J7 \, A% L
  11. // 定义字形数据的字节数组2 G6 P- B. q/ Z7 Y$ J
  12. unsigned char fontData[] = {
    / w* d' t& }. s0 T7 b/ L
  13.     // 字形数据的字节表示" t$ d, C) r% o0 s0 D$ }
  14.     // 例如,这里可以包含字母、数字和符号的字形数据
    0 M% A; c/ M2 F; o- d$ v3 ?- q
  15. };
    ) ]+ y$ l) u( R5 Q" d3 V

  16. 1 j7 ~0 v2 Y& R2 m
  17. FT_Library library;
      Q0 c/ V8 s, ]( N+ m' p
  18. FT_Face face;
    . u! l# L* C; I5 h) e+ u2 O4 ?' s6 u
  19. GLuint fontTexture;
    . S, A& ?  \; b/ T# O. R
  20. ; \9 l: W1 \7 R$ g& `7 S
  21. // 初始化FreeType库和OpenGL. }* @- t$ w2 k5 l$ @( h
  22. void initialize() {
    7 N; }8 S2 j  n
  23.     if (FT_Init_FreeType(&library)) {; S' p8 q/ ?. y
  24.         fprintf(stderr, "Failed to initialize FreeType\n");
    % U) B# s7 ]3 {
  25.         exit(EXIT_FAILURE);
    8 @2 F# b$ [% m' t6 A
  26.     }
    ; k4 T0 U8 Q- `- O9 O

  27.   _2 W* g& p# O
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {
    8 K" P2 }! U7 V$ Q( @
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");9 J. r: v8 o; Q6 D
  30.         exit(EXIT_FAILURE);. W+ l' W7 F: e2 X
  31.     }
    ! A, x6 ?# O7 T! ]1 A2 c
  32. + w3 E$ }- C' d
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小3 [+ a/ P/ D) l" \
  34.         fprintf(stderr, "Failed to set font size\n");
    " j* e9 I: Z' _3 ^8 ]6 p
  35.         exit(EXIT_FAILURE);; F8 t- Z2 g6 d  T- `/ j
  36.     }& [; G! j" A) c  O

  37.   q2 E, _. N# t: ]! f3 l
  38.     glGenTextures(1, &fontTexture);7 M5 e! R6 F; b, E/ u! e# T
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);4 s9 H4 k" [( J0 e2 {- n
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);! A! c3 ^' S4 J( Z! ?( Z

  41. - L6 }- h( W+ y$ q3 t) P
  42.     // 将字形数据传递给OpenGL纹理0 m: @" N$ I& f6 D: j
  43.     for (int i = 0; i < 128; i++) {9 E& I9 X2 M$ H& c( f2 J
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {: U' b5 v8 @2 ^+ I! s. ?
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);: ^* a# d" e  A0 a
  46.             continue;
    0 g( H' J- C! U$ f) K& Y; ?
  47.         }
    * S6 \7 l" U( j0 D! w, x
  48. 3 n& J# Z) ?  q$ @" b
  49.         glTexImage2D(
    ) u. S0 Y" b: `  y$ z# n
  50.             GL_TEXTURE_2D,
    0 ]+ G6 c/ ^" G; B4 X7 m4 `! N
  51.             0,2 c! x$ t- @- j' v8 W; }
  52.             GL_RED,. K' e( ?" _$ l5 F5 s$ u+ J* g3 T
  53.             face->glyph->bitmap.width," u3 w$ J1 n9 |" `. l7 C$ F
  54.             face->glyph->bitmap.rows,
    2 i6 i) V$ L* Q
  55.             0,/ W8 x" K+ [' E4 A
  56.             GL_RED,
    . Z/ p7 p6 H! e1 q
  57.             GL_UNSIGNED_BYTE,. P, `( m/ M' n4 r: C
  58.             face->glyph->bitmap.buffer
    " n/ l, l7 Q9 {
  59.         );* L: t7 R  v/ l7 z- L1 ]

  60. ) j5 U5 D3 \& X9 A
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    ) h- V! M6 ]0 V% a) T9 I1 e' M
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    4 |  p& g- T2 e8 W9 i( b( Z0 E- A. H
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  x0 C' n5 H1 w& r
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    + F6 d  L2 E  x* M2 R4 L
  65.     }
    4 A8 U$ ?# l  L4 u' F
  66. }
    + G! @1 R" m+ [/ E9 z* j0 a- W

  67. ; O2 @  s0 I+ q4 N
  68. // 渲染字符串
    3 L+ P- ]: e5 P/ w. Q& q2 N
  69. void renderString(const char* text, float x, float y) {6 m& s7 e0 p2 y% k# U
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    6 w5 M  v- g  a

  71. ( b  u6 s" T0 t  i2 P/ G1 ~
  72.     glEnable(GL_BLEND);, i4 e4 z6 d9 F! T* X5 G, T
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    7 i" U. l5 b+ p/ r' J
  74. & {5 C; J: j* I4 @& m' @- x
  75.     glBegin(GL_QUADS);
    * {# T; t8 i) C) _2 }
  76.     for (const char* p = text; *p; p++) {$ O% j( A2 o1 x
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);
    7 A( f/ d' E3 \, z% E5 P$ i

  78. 0 m0 Z! A. z5 y) s% V
  79.         glTexImage2D(
      b6 p. v" u* s9 G6 a; z8 Q9 G
  80.             GL_TEXTURE_2D,
    1 N5 L3 K# C2 N( o' K3 d$ X
  81.             0,
    2 J; \* L3 Q7 f: `9 L- @6 }* c
  82.             GL_RED,! c: g, Y5 {2 r
  83.             face->glyph->bitmap.width,
    : b4 O* g$ I  m8 K7 r- a+ S
  84.             face->glyph->bitmap.rows,: o* u4 W: i1 i# L+ M
  85.             0,3 F1 g8 p  W8 b3 C! ~" T
  86.             GL_RED,
    4 z/ w2 w+ p/ B! s* o) X
  87.             GL_UNSIGNED_BYTE,
    : i% H6 U2 k# ~5 ~! r$ k# D
  88.             face->glyph->bitmap.buffer, X4 b0 P, `2 G' b' f& z0 Y% _
  89.         );
    7 p; U2 p) ?9 N$ k& J
  90. ; e! Q3 Q6 `& C
  91.         float xpos = x + face->glyph->bitmap_left;
    : J5 G5 u7 m4 Y  F4 T- X. ?' }. N
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);
    : ^! R( w( z5 r0 u  N; t8 d
  93. ! S( Y0 X1 w# d+ K( w$ b" A
  94.         float w = face->glyph->bitmap.width;
    6 A8 ]9 i2 n9 X2 j* f2 \. \
  95.         float h = face->glyph->bitmap.rows;
    2 R; L, o2 A4 _8 L3 J+ W# ^0 l' {
  96. ! z6 q- w- y; Y3 w( V( _- c+ j
  97.         glTexCoord2f(0, 0);) T' Z0 j* z8 p4 Q. P0 u8 r
  98.         glVertex2f(xpos, ypos);
    4 m/ m1 w3 j) i& m; P& {# M& z
  99. " X& v5 _  A/ c1 A0 v  x
  100.         glTexCoord2f(0, 1);5 d; X9 b  i$ u+ g$ o: H
  101.         glVertex2f(xpos, ypos + h);- U+ w2 x4 G3 g
  102. 2 x3 ]$ A! H, j. ?; L* [
  103.         glTexCoord2f(1, 1);5 e3 t0 `- f7 _5 X
  104.         glVertex2f(xpos + w, ypos + h);
    ; _; \" p  i$ A3 |  ?! X& L0 _0 \

  105. / N1 ]0 \4 t! d5 J; |) F
  106.         glTexCoord2f(1, 0);
    $ |1 F  o8 u9 ?! o$ X
  107.         glVertex2f(xpos + w, ypos);9 i' a: x4 n0 t& w

  108. - K# l$ t" X5 E& n3 q, e
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距
    ( y. c1 ?- j) T- d- G: n7 L0 [* h
  110.     }
    5 {5 R5 p, S8 {$ e
  111.     glEnd();6 t. k3 J9 z: b0 l; O
  112. 5 G1 y' s$ Z3 a4 }
  113.     glDisable(GL_BLEND);) @# P- ^+ K# r
  114. }% C+ [" i+ e1 @* h" t# w* e$ S

  115. 0 K% ~& X  H9 c, m
  116. int main() {9 T$ T+ t1 W0 Q) a- G, M: l
  117.     if (!glfwInit()) {
    . e- R& C' g/ M; Z8 q6 m
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
      @; y; X( Y" N$ p
  119.         return -1;
    7 X1 C( p& _: r7 y
  120.     }
    6 e( M5 t" p5 p2 j  s, w+ w

  121. " }* \  V1 Z- Q
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
    ) z" R1 L- O7 |
  123.     if (!window) {9 E5 g4 J  z+ X+ D! N6 ]6 R! f& V
  124.         fprintf(stderr, "Failed to create GLFW window\n");
    $ i5 O, ]% H5 m5 F
  125.         glfwTerminate();6 M, {- C  A" d- I% d
  126.         return -1;: N# C5 }# f" V
  127.     }
    / n, P$ M& d' q, [. z) u8 H

  128. % k0 I4 X) ]# R6 r8 r
  129.     glfwMakeContextCurrent(window);
    # C( A- p) z& h) s! F) w
  130.     glewInit();
    + j6 i# w" A# O- m8 t: n

  131. & l3 I8 y- I  H* y- U+ y
  132.     initialize();
    7 M1 ?3 |# \' l

  133. / C+ f! g5 k0 v* l1 C8 W, c
  134.     while (!glfwWindowShouldClose(window)) {
    6 ^8 A. a8 P' G6 `3 b5 y
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);7 t/ Q- @7 A8 C' C% P% o
  136.         glClear(GL_COLOR_BUFFER_BIT);
    " m0 Y* @4 y4 m0 n
  137.   s: i* n7 J4 _
  138.         glColor3f(1.0f, 1.0f, 1.0f);
    6 J: A* K5 h* l+ f
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);' W: y2 h8 H+ ^4 V
  140. 6 X1 B  \* D' ~# {
  141.         glfwSwapBuffers(window);
    ! }: I% c% S2 w4 [& t* D4 E% k
  142.         glfwPollEvents();
    ; O! j( _2 z3 [0 L
  143.     }5 }2 ~/ u* B3 Q1 O: m
  144. 6 e$ Q$ c+ c; y. i: R
  145.     FT_Done_Face(face);/ P- ]7 L, i9 k% ~4 r2 [  g5 B2 W
  146.     FT_Done_FreeType(library);
    $ V! E* _, i  Z! k  }
  147. ( `0 M) _$ A0 ^) \( k
  148.     glfwTerminate();8 Z  A; A: r/ R
  149. : t, m1 A: u1 A
  150.     return 0;
      C  O2 `: [. e; v( |! O5 g
  151. }
    9 N2 l1 p6 Q- }# \8 e8 M/ O
复制代码

! F* Z1 S9 E4 Q- r" K
; }, [7 h* g; Z
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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