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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑 ( R( i/ {! q; o+ ~
7 c. L  {8 p; A% b' w( G
以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。" e" U) n% m1 u* v
本代码经过分析以及改写之后,将取代游戏原有的显示函数。/ m  n# }0 N) D8 s
. K1 J; j( C3 Q; n5 h+ S
代码详细说明如下$ k2 i. S4 t9 W* D& f: m4 P

3 g; e+ Q: }* L. k
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:4 K" F' c( v% {9 e! A$ F% i
  2. ; x  g) l  C3 K7 n6 o4 [
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。
    0 A) _4 `$ o& S1 Y' w
  4. ) b" H3 N& W& l! E; n) Z- K
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。; h( k: Q0 w) J( K4 n5 z1 O" x% L

  6. 9 Q4 `5 W6 a, Q7 E# j
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。) k6 N4 ]% o, V$ t

  8. % E3 {( ?* S; D2 p0 N5 R5 j
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:
    + [( ?' [; ^, P+ C6 W

  10. - {/ ^0 v$ ^/ C3 v+ D' v* H
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。" d! p( Z  {0 a8 T/ r" v1 @
  12. , o2 h; e. Z5 h0 D
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。
    " H1 m& d  D* r: ~1 o- `

  14. 1 T8 H+ t- M: u& ~$ V. w
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。( y; d1 _0 P# j$ V+ _" _/ E
  16.   C; v; b+ v( T/ B# m' L
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。: c7 |% k1 Y5 \; @
  18. ; S& b+ W0 W7 K: ?
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。* V2 t1 D0 k; V% T& {

  20. ' }0 Y! z7 B+ a8 ^
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。& C, b& B6 D$ B: s: @
复制代码

& j) |: d' s8 H9 ~. A$ j5 `  M9 A# }. D0 B) t, F% j5 Y! a3 ]
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:1 t' M% u3 |" ~+ z# [+ m) O. J, m
  2. ) S; T: O/ e. o9 G! Z8 c1 }. h7 O
  3. 参数:& G% r+ t7 V+ r- h5 ]6 ]
  4. , m5 {4 j  g3 K+ B
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。& u( O/ E8 ~) S: [6 J" P4 o
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。1 H5 }1 {, m- Y6 u' {
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。: u+ Q8 w8 |, a5 m3 q+ u# f( B: |
  8. 功能:6 I9 [: Z$ }. j; Z/ L# c0 H

  9. 7 }% Y, w) e* I
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。
    ( J+ I$ C2 @% W8 ~5 c
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。
    2 @+ x* w1 i: l
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。( x% d- }. ~6 Z7 T  ~: J
  13. 使用示例:
    6 Y6 E0 \$ X/ @5 y" n/ u
  14. 4 }/ P# C# U& ?" D2 G
  15. c/ G1 a4 e1 ~8 Q' o: C- u
  16. Copy code
    5 I' B6 s- e+ r/ }# N' I
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);. D7 y5 E& p: d  Z0 c8 v
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。
    ( I* f) O# L4 l6 S* z# p. Z/ f; X
  19. / |3 q: q* q5 o6 p  n& [
  20. 错误处理:
      _4 x2 Y7 C( u# e/ {$ F2 y

  21. ( u3 W& R0 Q4 L0 A
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。3 d9 E0 ~# N4 \9 B% j; F! q2 [% D
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
: d5 W9 g3 w  G
1 B! j+ u( d7 O" G
代码
. O7 E1 j# `) f, n8 ~  n7 n# H" S

  1. * q" O& \8 e# w7 g0 p. i6 L, I
  2. ' D; ]5 u- h' ^

  3. 1 u4 L) Y- Z5 D. |6 w6 k
  4. #include <stdio.h>
    " a" i6 Z" ?. Q! x5 x# S( A
  5. #include <stdlib.h>
    7 u: j9 P1 W$ d1 U* Q  K) X
  6. #include <GL/glew.h>9 j$ j, _0 v, q% `- \+ W
  7. #include <GLFW/glfw3.h>
    ( d$ w- T$ N1 T* Z- ^5 `$ K5 {0 e
  8. #include <ft2build.h>! m/ p% C# `$ ~
  9. #include FT_FREETYPE_H
    8 m4 @. l# l8 {. W' m% s# k9 Z

  10. * Y+ p) K% v  T& d, R
  11. // 定义字形数据的字节数组
    " J+ D+ e3 l. t0 o& M' g7 f# e
  12. unsigned char fontData[] = {
    1 g* I) u6 M; u+ ?. D5 e0 U! o4 U
  13.     // 字形数据的字节表示
    ) S' W+ E0 ?" `/ C# F
  14.     // 例如,这里可以包含字母、数字和符号的字形数据
    ( ^/ Y- b2 J( Y3 V: b, u+ Q
  15. };0 N1 Y7 F: v7 }' {/ o

  16. $ C$ S) i, ~. K5 `2 \
  17. FT_Library library;8 k/ i+ V" y. ^' X9 N& O/ h. r
  18. FT_Face face;
    , C" m# B0 [6 D* w6 w6 D& `
  19. GLuint fontTexture;
    % o4 g. v: N4 O0 }
  20. & _: o1 E/ t4 {' ?, l% R
  21. // 初始化FreeType库和OpenGL
    5 ^8 b0 z3 _! m* S+ Z
  22. void initialize() {
    , R! d$ g; n' n$ G. ~
  23.     if (FT_Init_FreeType(&library)) {
    ( Q8 e; W9 l6 \2 W3 a5 U0 s. G
  24.         fprintf(stderr, "Failed to initialize FreeType\n");! ]1 k9 }' h+ d- n- B, R
  25.         exit(EXIT_FAILURE);
    $ y' H5 {5 u( |% ?' I. {
  26.     }0 ^4 o6 s, b9 m9 }: c" G+ b# x4 o

  27. 8 E! O8 f# n" R9 t/ C
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {
    $ c7 H! |0 V& s$ P( |
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
    " M( b$ E2 b9 |8 [  {0 X
  30.         exit(EXIT_FAILURE);
    6 z3 R$ [9 S: n# i6 i
  31.     }  j% U: h! n# H

  32. : F4 Q$ h1 v% L0 S6 z( u
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小2 q8 M  l3 N# P
  34.         fprintf(stderr, "Failed to set font size\n");8 p, \( |* `. s& g  F
  35.         exit(EXIT_FAILURE);% D' X* j9 B2 y2 X" |  P
  36.     }, P7 `$ ~7 j( S+ d0 Z  D
  37. ) c8 C; V! a8 O
  38.     glGenTextures(1, &fontTexture);7 P; u; P, r- ]  N5 O2 ^
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);7 c$ j& P" t; p! m5 [) A, f
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);% ^8 m: U( K3 H5 V& N$ y
  41. 8 j3 K6 m2 e4 G/ }/ l) `
  42.     // 将字形数据传递给OpenGL纹理1 E8 o* g( y. D( H) V
  43.     for (int i = 0; i < 128; i++) {
    % V1 k% N5 V& l, n
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {# s7 q- O; S* G+ |" g* \- K
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);+ S) j' S" Q: ^8 d
  46.             continue;
    / m! |2 c- k$ I' r- m
  47.         }
    + d# Y/ S+ W3 t: }" T# ]+ o, k
  48. ( a8 M+ L7 A/ G, Z; W
  49.         glTexImage2D(. B" J! _0 y. ^2 @% N1 ]7 r) Y
  50.             GL_TEXTURE_2D,% H- b& Q* p+ P* ?, T* ^$ i
  51.             0,- L" f) A9 c7 H1 a, E0 k
  52.             GL_RED,7 k% ~+ b4 D  E: I; w" G
  53.             face->glyph->bitmap.width,+ \: {$ D8 @9 I$ A( F5 C( L
  54.             face->glyph->bitmap.rows,
    3 r* N' F. d" X; r: n
  55.             0,0 [& |  G+ y* l1 H. C# P
  56.             GL_RED,
      d8 K" v) A$ X  k' J: X
  57.             GL_UNSIGNED_BYTE,8 p* j0 a" A* k$ B  x0 M0 y, Y
  58.             face->glyph->bitmap.buffer# n; c/ R7 T! t6 Q( D" M8 m9 n
  59.         );
    / R9 f" V' V* t6 Y  Q3 B$ K$ T* t
  60. ( t1 ^6 ^0 d1 E9 d1 c  s
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);, \3 {' k5 N7 E  k0 b* `% F6 F
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    ! }+ w) l0 H  S8 O: p9 B
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);8 T# O- ~( r5 h5 a8 Q1 v
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);) _% @! a, j: H6 n9 T; v' T
  65.     }8 a$ e8 G9 |6 O6 P
  66. }
    * S; l! Y( O& [( [( J; {

  67. ! z$ n2 J( k4 ]
  68. // 渲染字符串) `" N! P4 ?. z2 b
  69. void renderString(const char* text, float x, float y) {
    - }0 S# |, P9 I' [! `0 H( q: R2 K
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);) t2 f5 K% y- Y# d; v) P3 i
  71. - @3 v( }8 A5 J% j* A  N3 ?. N
  72.     glEnable(GL_BLEND);
    5 K+ e, I' k5 q( }, J
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);2 i! g: l/ D; f! Y8 W* |$ t
  74. 1 p8 z* ?3 A$ {1 D* N7 W, A
  75.     glBegin(GL_QUADS);
    : J  V) O& b6 R# F3 r. a0 p! N
  76.     for (const char* p = text; *p; p++) {& A5 K( E4 k- B3 m+ s% @: r% B
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);
    4 T: y& w: a! S4 ~* q8 c. q

  78. " a/ D& w* ^8 Z" \, i: I
  79.         glTexImage2D(8 i+ w4 g& M5 |# w. v( p$ R/ @
  80.             GL_TEXTURE_2D,
    + V: T7 p1 t: c: G/ X- \
  81.             0,
    6 Y( W1 X0 x2 s
  82.             GL_RED,
    ! D& ~  p+ f2 h1 c. g$ H
  83.             face->glyph->bitmap.width,
    ) U0 }7 G) k5 d8 I3 w( w
  84.             face->glyph->bitmap.rows,/ j; @4 y1 q- H; ]' A0 d
  85.             0,% L" W& \" F" l2 C5 v. [1 D
  86.             GL_RED,5 b- z, f: C3 [9 C9 h) S
  87.             GL_UNSIGNED_BYTE,5 l" T. E4 V' B) H
  88.             face->glyph->bitmap.buffer
    ) ^9 q0 o2 [8 X; y
  89.         );& Y5 I: h) t4 ^3 Q) [

  90. ) c; p! e9 `3 r3 k3 v5 M
  91.         float xpos = x + face->glyph->bitmap_left;
    0 N: U! L1 M# I/ f
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);
    & ?7 \* ?' P) v1 ~* u. q+ S

  93. / l! y+ v' w" J% L
  94.         float w = face->glyph->bitmap.width;7 _# U( M1 x4 J, o! ^% f
  95.         float h = face->glyph->bitmap.rows;
    4 f" F3 N5 L# ?- W; v1 F& T

  96. - d2 `/ W/ d" `: ^
  97.         glTexCoord2f(0, 0);
    3 P* ]& k8 J4 T7 ?
  98.         glVertex2f(xpos, ypos);
    % g- z$ P3 ^3 l% }7 j; M' D/ E
  99. + A5 w. x# [7 f& F# C
  100.         glTexCoord2f(0, 1);
      l2 G, ]" A9 j
  101.         glVertex2f(xpos, ypos + h);
    * Z. j, H; B6 v7 p

  102. / f" N4 o* ~6 q* P2 E! E* g
  103.         glTexCoord2f(1, 1);$ D% `, V3 X( g* }; ?* p2 g( R& ?
  104.         glVertex2f(xpos + w, ypos + h);
    ; |9 u, y0 H' ~6 c
  105. ( Z5 E( c! x! r' o$ S* x$ K. x
  106.         glTexCoord2f(1, 0);) w. ?4 ]/ N. B- P- C
  107.         glVertex2f(xpos + w, ypos);6 X9 C4 n( @* ?0 N

  108. $ c' N! m7 [, {. R- D  x
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距: U$ h& ?  r# `' w! c4 i
  110.     }0 V0 @3 ?5 d! M+ j9 W
  111.     glEnd();
    # W4 c) M1 |( }4 E) d$ r! M

  112. 3 u5 c" T8 H" A' H6 `3 d4 S
  113.     glDisable(GL_BLEND);+ Q# |0 t! ~$ O7 R9 e% I/ b6 u
  114. }
    " Y7 e4 [4 E) M7 R$ F& w: ?" s
  115. , ~1 m. q. M% N
  116. int main() {
    & x9 [! @8 C4 q9 |' E
  117.     if (!glfwInit()) {' S; v4 p# l* v
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    $ P6 n, O- ~$ d! y
  119.         return -1;2 g8 P1 u5 C9 {9 E
  120.     }
    - B- C& A4 S' k$ h5 _4 Y

  121. 3 E5 D- _7 s6 w
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);, L) M7 h! w5 \4 `4 e( t1 F& C
  123.     if (!window) {0 e4 {! o+ J! w6 p
  124.         fprintf(stderr, "Failed to create GLFW window\n");
    0 n7 v1 ?; q, I8 Q" M# n
  125.         glfwTerminate();
    " x( W. d0 t( G
  126.         return -1;  h  N4 k! D1 ]- `' \, C
  127.     }
    3 f- f8 k/ g. ?2 {7 m
  128. * P( A; [8 Z1 c9 z  ]
  129.     glfwMakeContextCurrent(window);
    7 |, r1 L4 N. \2 K5 V
  130.     glewInit();
    # N" t6 S4 O" [

  131. 8 y' x1 c. j5 v
  132.     initialize();
    2 h- D8 T( a- y9 |5 Q

  133. ( P: L! p* I3 `  j7 F' H- R
  134.     while (!glfwWindowShouldClose(window)) {
    # T. }$ [2 e4 X/ S2 Q
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    ' _: I2 B0 I/ F) X4 U5 j* A
  136.         glClear(GL_COLOR_BUFFER_BIT);
    6 e4 I+ H8 F; Q& R9 q; W8 z
  137. 6 q4 N% `3 b8 A/ _
  138.         glColor3f(1.0f, 1.0f, 1.0f);* `5 E+ `8 I+ y9 N! g& S$ y
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);4 i2 O7 t& g! t! p/ @/ R

  140. . B. m$ m5 P4 B4 K
  141.         glfwSwapBuffers(window);
    $ e$ d1 F( G! {9 U0 M
  142.         glfwPollEvents();
    / S4 G0 x, j  B0 z
  143.     }
    + ]* v3 [0 C; n: m9 x7 g

  144. 8 N8 ~" T, B9 G
  145.     FT_Done_Face(face);4 U1 q# x3 A# X7 J4 ]+ Z7 x& J
  146.     FT_Done_FreeType(library);
    . R3 ?0 T& M# i/ u) ~5 j  q
  147. % |- b# v" L# n& |: Q
  148.     glfwTerminate();. H) \& u* {/ h; H8 [% }

  149. ' l# g+ l( k1 y* F4 S
  150.     return 0;6 ^$ \! C1 X' E" [5 B
  151. }
    ; }* K; X  J7 x6 ]! N
复制代码

7 J! a' w6 W/ v7 L. H- J8 |) e5 N) Q# x' u4 N
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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