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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑 ' m1 ~9 o! j4 C% ~. z1 d
5 t+ y5 }# U' D7 ]) B& ^3 d8 J
以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。
. H: N# s* c. _本代码经过分析以及改写之后,将取代游戏原有的显示函数。( m( J; B! z: t/ ~
: i: B6 ?6 s1 a/ O! T1 V; @+ y8 R
代码详细说明如下- ~% r6 ]% `+ u5 j' Z' j+ j

/ f' U0 v6 o4 d3 U# n8 e6 I
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:
    * \& J3 Z5 j2 `! k' z
  2. $ N3 M2 v7 x3 v% T# b7 ^
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。) Z7 Y  W- D4 d" K3 I3 ]

  4. " }* G9 h( z( e$ r
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。
    3 m  F- d( `, _7 G8 D; V- \
  6. 3 }0 }1 H, P5 `
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。& `+ \0 F8 B5 d% v3 K( f7 L  W

  8.   G, D. `" \& `7 o- `
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:+ r) q# }; N6 {
  10. $ L9 S7 R8 N/ C: X* w6 k
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。
    0 y1 o: o1 W8 ?2 t$ J
  12.   i4 y: n/ U5 A% l: o1 {
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。5 i  ]7 w/ H0 d2 t
  14. ( `) L# k- [9 y) z, {
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。; [2 t* n+ z5 E( s" J0 B

  16. * U3 N6 {6 N" @5 ?% s9 I# Y+ q  }. ^
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。
    2 O. T* U3 z( @' U& ^" Y/ r
  18. % E9 h8 Y( |. |4 A8 S0 s) [4 ?
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。1 r6 m+ I# k! C+ |1 j

  20. 8 D/ c% B1 Q; [. V: T* Z6 F9 [0 A
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。
    3 C$ G& V. t4 p
复制代码
- e. o/ Q8 s# N$ ~- L* f
. N, g! j0 z1 S$ S; o8 @
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:+ m1 x2 Y; k  K8 o

  2. / r5 q- p( n0 w6 a% l
  3. 参数:
    , x* g8 j  K* }) Z" y

  4. ( A# T) d3 b/ Q2 g# e
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    / z$ G' |. ?# {
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。3 e8 h7 L" N" n3 W- A! \
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。
      L  @! ]2 J5 l3 b
  8. 功能:) W+ x) s* r  X) l% Q

  9. % u9 V4 e' h5 \2 t
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。  U  M" I( v0 t% ?' D
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。
    ) g( R' z, ~8 O( }
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。" ~' r  Y7 e" i/ W- o% U5 h$ h
  13. 使用示例:9 a; j  v$ W$ k5 }6 G, y

  14. 6 U0 r/ ^8 V7 d  m  X
  15. c
    5 K( `4 I/ M. F; J' y
  16. Copy code
    5 |& s! S* m- W1 f
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);
    2 Y1 I( l0 f7 V  G" e, `2 e
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。
    # c' v  Q% O& b2 G- V$ A
  19. 1 e- G' g5 [# T1 b
  20. 错误处理:7 u+ T# i0 A4 `( b! |+ m

  21. 9 o' v* e7 s. N4 t
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。" X! y* V4 g; p9 o: `6 \4 {
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
7 S8 ]+ c. `8 W( g% G6 W5 \2 {2 v

8 _5 h2 ?6 s, h! ?" F代码
- B" n% \9 Z6 J" l' Z1 j6 L
7 N" j- d# o- J  M6 V2 C! w+ [
  1. + N/ G4 t7 ]' ?1 n* x
  2. 1 |( n8 ^/ _, n% d0 ~' F

  3. + Y; q/ V1 \) B+ ~% ^
  4. #include <stdio.h>
    , U, X# \8 P& d
  5. #include <stdlib.h>
    7 f7 ^& s" v+ `: G  @" J
  6. #include <GL/glew.h>
    ' N; A* l1 q$ Y8 B* Q
  7. #include <GLFW/glfw3.h>
    : r  ~3 ~; _% i6 R) [
  8. #include <ft2build.h>; F2 ^" e( f3 A$ y6 \& t) q; t& [
  9. #include FT_FREETYPE_H; D3 L7 m0 r* N5 l

  10. " t4 w+ r, @  ~  v. |: @1 O. [& L
  11. // 定义字形数据的字节数组, g1 N& W' C8 w- o4 h
  12. unsigned char fontData[] = {9 B1 ]  e4 a3 w9 K0 \) D! _
  13.     // 字形数据的字节表示8 C# H. f2 B, P$ Z
  14.     // 例如,这里可以包含字母、数字和符号的字形数据
    5 ^# Z. {% z0 F
  15. };
    : m: n4 }) @& r2 @7 ^
  16. / {0 d! a0 W- ~0 a
  17. FT_Library library;+ Z# b4 \. ~! }
  18. FT_Face face;) {" z; g, H4 A1 t0 C
  19. GLuint fontTexture;
    6 u$ k$ M  k0 ~0 ?& [3 {

  20. & Z2 a9 p0 H' q* S* l
  21. // 初始化FreeType库和OpenGL) i3 O$ _) X9 p( ?$ t- S
  22. void initialize() {
    9 K4 q+ D2 V# y$ z( k  B
  23.     if (FT_Init_FreeType(&library)) {# z9 t2 `% o9 s4 z9 s! n
  24.         fprintf(stderr, "Failed to initialize FreeType\n");
    9 v4 I- c' n9 A( z6 [( ^" }
  25.         exit(EXIT_FAILURE);' S/ u2 |+ @- c
  26.     }
    0 B0 d, i" r, F$ h+ ?: L% ^

  27. 8 }+ W- b3 O4 P2 H
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {
    5 z  l0 ]0 c( J: P; b5 L4 K: {
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
    & ]) ]( T8 E" o* V4 A
  30.         exit(EXIT_FAILURE);
    ; V0 Y) I7 P0 I" H
  31.     }0 M& e2 \1 ~) j6 Z2 f" `
  32. 2 ^$ l1 Q9 i; H/ y7 q% Y  G
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小3 G5 A% F( a3 e( C+ T9 |
  34.         fprintf(stderr, "Failed to set font size\n");) s' y/ v3 E- D
  35.         exit(EXIT_FAILURE);# G$ L3 e1 x6 K& X' m: l$ Q  U
  36.     }
    , b; P7 i2 m1 f* ?7 z
  37. 8 I8 D& j) Y0 {$ E( M' j
  38.     glGenTextures(1, &fontTexture);
    # ]; E8 p# m/ T
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);9 ]& F3 B: f8 U3 z; x, D
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);2 H* f7 [3 ?0 I! `
  41. ! s# i) }$ t# f/ M
  42.     // 将字形数据传递给OpenGL纹理% f- b3 q0 X  A4 ~
  43.     for (int i = 0; i < 128; i++) {1 q5 {  r  U$ \; a3 [
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {( G, k- p# `4 O
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);
    3 S* P3 t! v% m' u* i
  46.             continue;8 `4 I* T* w1 c' h; g# T4 J
  47.         }
    8 G9 `. H% z/ J. y0 j8 }

  48. $ x+ C0 L! J& Q2 C* p+ ~" W
  49.         glTexImage2D(! c$ c( l: V( ?; }* J
  50.             GL_TEXTURE_2D,
    1 `1 k# J! N, E% ^! j: a7 E2 F+ ^
  51.             0,- k3 W+ p9 n3 |4 w1 C
  52.             GL_RED,& o) B* C- e7 s5 N  ^5 ?) Z! f
  53.             face->glyph->bitmap.width,
    ) t) e* v. n! a, h. M3 P
  54.             face->glyph->bitmap.rows,
    , H# U% }* G  a9 B. z+ a. l4 Z
  55.             0,
    & {, i" {0 |. Y: R2 t# f5 K- E
  56.             GL_RED,
    6 \+ s  W7 m: h+ i
  57.             GL_UNSIGNED_BYTE,* O3 d& e9 H6 r0 @- ~" K
  58.             face->glyph->bitmap.buffer
    " K7 ~) h8 Z( n. j; k
  59.         );2 k0 j* C6 d/ [
  60. ; K3 S* J3 y6 b6 k7 x0 d( z
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);% W& C( c- z) u/ \
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1 i8 _) U  K7 `  X7 H$ v
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);$ R, x9 Z6 Z  A  s
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);$ F4 s3 }* J; S% d* g
  65.     }* R0 o- [% w6 \2 ^. W
  66. }9 s" g2 i7 q, c; n) r# g

  67. % k3 w/ h0 ]  q# G$ `
  68. // 渲染字符串5 E, C. {; v) b, D
  69. void renderString(const char* text, float x, float y) {# s5 t7 q  z1 H* F6 R
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);( q4 ^/ I4 \# \+ u# `
  71. % o% Z% w2 u# P$ J1 V' S& D* H
  72.     glEnable(GL_BLEND);
    4 o$ }) M4 u7 T
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);, E. I7 h+ B% U( x" k  |8 P

  74. ) j! [. w- m- R* c' N$ x8 K
  75.     glBegin(GL_QUADS);: T( G5 H' `9 |. j9 g! h% T, M
  76.     for (const char* p = text; *p; p++) {
    + S' |- P9 T8 D* y
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);; s: A0 B% ]! Q% g# U

  78. & t% `" x7 T! z: Z% x
  79.         glTexImage2D(
    ( c: o/ @' n! l
  80.             GL_TEXTURE_2D,/ ^2 N* o' U: F
  81.             0,6 A" G" O7 d/ k6 r) _" z" Q
  82.             GL_RED,+ v+ R2 T% M5 \: v& m* @' D
  83.             face->glyph->bitmap.width,
    ) w! F) d+ r4 w0 M3 Z: w
  84.             face->glyph->bitmap.rows,  {3 C1 J. {0 C1 g( Q7 h. j
  85.             0,
    6 u# H0 T, d) v; ^& S
  86.             GL_RED,$ N) D8 X) ]1 x8 E
  87.             GL_UNSIGNED_BYTE,4 `" l; Q" l0 s6 a! L
  88.             face->glyph->bitmap.buffer
    - g2 a, o4 g! `9 H1 Z9 H
  89.         );. K- J, g- q6 _
  90. ) |. m( r. \8 R, Y+ F: J
  91.         float xpos = x + face->glyph->bitmap_left;# U: ?* E$ y) m" o3 m' ~5 R
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);& D/ ~# K  b* P) W# i' R5 z

  93. ) @4 O$ Q# I5 |3 r8 m5 R5 V8 `8 H
  94.         float w = face->glyph->bitmap.width;' E& a, k" @/ J8 p2 [8 U0 x, I
  95.         float h = face->glyph->bitmap.rows;4 }8 r4 z/ _8 v

  96. # o6 t5 _$ Z5 F$ i8 s
  97.         glTexCoord2f(0, 0);
    ) ?8 d/ d8 T% \/ P2 `) u* m
  98.         glVertex2f(xpos, ypos);; N3 a; j0 \. Q1 V- H

  99. 3 T$ s8 p: {/ ^% e) R1 E
  100.         glTexCoord2f(0, 1);
    ! C# z5 M6 @) `$ S
  101.         glVertex2f(xpos, ypos + h);( E* ?; t9 y/ _4 U- |
  102. 1 B/ h' l  }! K+ ~( X
  103.         glTexCoord2f(1, 1);
    8 A9 R( Q% e1 E# O" [# o' ]4 i+ F
  104.         glVertex2f(xpos + w, ypos + h);+ [' y6 b# ~" s9 o' C( x2 y

  105. : v  C& m% b) B1 s  }
  106.         glTexCoord2f(1, 0);
    : v8 r% b) `% s: y8 o
  107.         glVertex2f(xpos + w, ypos);0 [! P) |, Z& V3 e- V
  108. . u6 W/ t* L' Q# Y
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距! E6 R+ I% L' a# j$ u  K
  110.     }# s) E0 P: d7 _
  111.     glEnd();6 D7 C9 L* v$ O

  112. $ O5 C! n+ ~" `9 d# I. r2 ~
  113.     glDisable(GL_BLEND);
    6 q6 G, Q8 E' @! L, n; r! w" J$ F
  114. }, g' _7 B; C6 h3 [3 c9 k
  115. : V: n1 D9 I/ v4 v' e9 Y
  116. int main() {
    / r2 _' B5 ~; [8 _) V# E" t
  117.     if (!glfwInit()) {
    / i0 d. O1 z; p: [! ^' r
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    ! q% l' ~- {$ A! C  X
  119.         return -1;
    , `" n& S1 D/ f7 n" ~. {
  120.     }
    " I' O1 w/ k- S, Y/ Q
  121. ' C# G6 t  `9 h' z: J- n" A
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);
    4 ]& C0 f: m) D% U
  123.     if (!window) {1 Z  I4 x* `0 z3 b" c
  124.         fprintf(stderr, "Failed to create GLFW window\n");
    " z/ }% }  |) [4 _* y
  125.         glfwTerminate();: \9 {, H' ?5 z& O7 `9 B5 K2 y
  126.         return -1;$ b2 f& h  E8 J
  127.     }( x  i' n6 P7 l6 A& D9 i8 m

  128. 4 O0 a2 E( n; f
  129.     glfwMakeContextCurrent(window);
    + d) V5 ^* I9 w" |! E" o. T
  130.     glewInit();
    . `8 I! d- i) r5 g
  131. : g5 o8 ?1 r% A' x' s# I
  132.     initialize();
    ( Q3 c, {0 H/ J1 `8 ]! E
  133. 8 q: s; u% @0 D4 u. Q7 M: |1 c- `
  134.     while (!glfwWindowShouldClose(window)) {9 B2 f8 p9 u# k( g* Z" L
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    ' t7 {# [7 {: a9 t2 l% ?; C
  136.         glClear(GL_COLOR_BUFFER_BIT);
    " E  k& H8 t, I8 G

  137. 0 r* J5 r) Z& i
  138.         glColor3f(1.0f, 1.0f, 1.0f);
    - ]. d1 v1 T. i; C
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);
    ( g5 [' z6 L4 v1 l. p) v$ O
  140. : P6 g& G+ Z2 A. y  {
  141.         glfwSwapBuffers(window);" X8 g4 E/ Q  y7 y
  142.         glfwPollEvents();6 P2 N; U# F5 E2 T/ O  B
  143.     }
    - s4 V9 [. }! R# [  [/ S. S: V
  144. % x% b/ x9 o5 |. \
  145.     FT_Done_Face(face);' s1 J* M1 ?/ _' ]% K" n$ q" b
  146.     FT_Done_FreeType(library);
    , r+ O/ D+ N4 L) p# j, B6 F

  147. 6 V8 I  @: Y- F% T( J0 B
  148.     glfwTerminate();
    9 w! h2 x+ H& U3 G7 S

  149. 2 l" z- Y( g- \; I) y
  150.     return 0;3 `- a( v% K  K# F
  151. }& d0 `2 o8 ?' l: I$ ^
复制代码

7 l# {: ]6 y4 O1 a( }1 j3 u( P$ R' `- [
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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