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

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

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

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

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

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

本帖最后由 shane007 于 2023-9-6 15:32 编辑
/ C4 H' z9 u' a$ E2 ~6 P0 {- o
  O* F3 S2 U% f以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。6 ]' q) I7 d7 `, }& ?" b# Y
本代码经过分析以及改写之后,将取代游戏原有的显示函数。7 ^# b; H+ \3 N

$ o, ?5 z3 ]9 Q代码详细说明如下& I% C0 E/ \2 y$ V0 }* O

. E3 ?1 ]& w' U# A
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:
      q5 d2 v5 K. @4 M$ o) M: @
  2. - Q" L  q: {7 x8 ^- j
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。
    6 S$ X% p! o7 J4 W8 a" f5 a5 X
  4. 3 T$ e- _. x! R. F8 E
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。$ T5 {& e4 o% t6 t

  6. 4 u2 B/ W( F/ C" B6 ^, I- X4 |3 J
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。( g6 a" G! x7 x  N

  8. . O/ c" p) C  {
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:3 W- T/ n! m$ Y2 K; E/ q) z7 \& a
  10. + _5 r. e! [3 h8 ~4 v
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。0 B5 E7 {2 d1 b' J: O

  12. ! G. W# o0 u1 d8 K! d0 o
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。
    ; {+ d: X6 e' A: ]: @3 I
  14. , @3 e5 j6 U+ i, b2 S
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。! N/ o# x- T/ H  U; u
  16. : f! [# ?7 H" ~9 t
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。. {5 k1 D2 e! ^- t  h/ j

  18. ' r; |# w  n' T' e7 G* h9 y
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。/ \; }* M% x- e: ~( t# R: H* X" \

  20. $ u+ J- ]3 }% B5 ~7 x
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。
    ; K" G3 X. i0 Z2 b7 V' Y5 y, S/ R
复制代码

& k- ~- U3 u& M# q
9 P8 f9 o# v$ T# _+ `, j1 M* l
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:
    & j: R/ c1 q4 _3 M
  2. % \% L" E) [8 y
  3. 参数:
    + C( \1 s  O" h9 Z3 Q( d
  4. 2 W' t8 I# \5 m. |1 o# S
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。2 I% K" b1 X% v! \) f
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
    ( U9 V/ e( \8 W' @, P
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。2 k# V" h) b% A( b( }7 E8 a+ T, r
  8. 功能:
    % f- R2 l: m3 _: x5 L6 `

  9. * T( N" E. t0 r3 m/ c
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。9 k. f# i, M2 L% O! X; k" {. O4 `
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。7 ?: H2 z5 c# D4 x9 [+ F: n
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。# `1 w. [! x6 j% {( x& t, j1 D
  13. 使用示例:6 D, x' x& t2 t6 S9 s) I- s
  14. ' z  ^) q$ N+ k& v
  15. c4 a! V3 ~$ r* h+ U' _9 n
  16. Copy code
    % [" Z9 i+ A- N
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);- H& [5 P" `' R" Y$ k! o" ^
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。
    # y; T; d7 ^0 z! j

  19. . G; k8 i& T3 s& D3 c2 z6 v& c
  20. 错误处理:
    + O$ g% j, [  j2 ]' u- o

  21. 7 s+ N% ]& m6 z& i# b! [
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。8 e# Z/ C0 t8 N7 [  q- T% F( ~
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码

0 d& s! M% J+ v! L+ `( o4 L3 |* q0 t9 ^; v& B6 o6 U
代码7 k" h8 z! }" Q
& B- }% f. K7 l& b$ F" N6 V

  1. 2 {+ p  X; @1 X, F9 w
  2. : V% w: X  p1 l+ V+ M- j" h# h" k' A

  3. " g# B) _  Z$ L; y& m
  4. #include <stdio.h>
    4 R+ o: H  T8 C9 y/ F. Z
  5. #include <stdlib.h>
    - y& ]$ g3 V. V! {1 n
  6. #include <GL/glew.h>
    8 v$ Q8 f! [1 X" q" \3 a9 q
  7. #include <GLFW/glfw3.h>
    7 L6 x5 M8 W# @4 d4 B0 `% L* i
  8. #include <ft2build.h>
      ^0 E4 L: g7 F5 H9 _8 f. d% N
  9. #include FT_FREETYPE_H
    4 h( N" @# h! H5 w/ }0 w
  10. % I" d) ^* k* O0 I2 Z4 D, F
  11. // 定义字形数据的字节数组
    ( W2 v$ u* [; ]
  12. unsigned char fontData[] = {! j% F) m8 N" P* R- o" E6 \
  13.     // 字形数据的字节表示1 o& F4 s( p8 T9 e* q  m. h3 m8 f
  14.     // 例如,这里可以包含字母、数字和符号的字形数据
    % Z5 w) t5 z. n
  15. };. u& b1 f3 e, Q' w- \

  16. 0 A5 [1 q2 m; d% D- @0 P1 N
  17. FT_Library library;$ K5 m, [4 a5 N! z5 q# S3 y
  18. FT_Face face;0 \% }2 N! h* \( @* \5 W! ]
  19. GLuint fontTexture;. ~0 z! s8 q5 {

  20. " Z% J8 u4 h1 w4 `3 z
  21. // 初始化FreeType库和OpenGL5 |$ F# b2 }( r  y5 m/ ]( R( D
  22. void initialize() {
    , k; ?! r7 R2 K( |/ H4 q3 F
  23.     if (FT_Init_FreeType(&library)) {
    6 H4 z9 \  j- W9 `8 x7 A* X
  24.         fprintf(stderr, "Failed to initialize FreeType\n");/ c5 Q# ]6 A/ u# m0 M# L
  25.         exit(EXIT_FAILURE);
    % d7 d- w- X3 ^
  26.     }4 j% J7 n/ K9 T; a3 U( g
  27. " _7 v7 \0 J: Q$ i# M4 p  M8 i
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {/ j- ^$ A3 ]5 G: ^0 v
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
      H2 [& q# e* M7 W4 M: J
  30.         exit(EXIT_FAILURE);9 \" y6 O5 \/ [& s
  31.     }
    * x0 h- [: a1 o8 S( F: C1 \# l
  32.   V' }6 X" x/ ^" i
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小
    $ _0 p$ K. p1 ]) i/ _
  34.         fprintf(stderr, "Failed to set font size\n");$ U5 q8 p" i( y6 M7 C& A1 w8 `
  35.         exit(EXIT_FAILURE);& a4 r) W" g. ]& _" d$ |: I
  36.     }0 O. q- _( Q  |/ n  O$ A: I
  37. $ A9 o6 P: Q! ^( p* ?2 y
  38.     glGenTextures(1, &fontTexture);
    $ u) y. r& A1 H# |1 _' N3 e
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);3 H/ @* V9 t1 r2 v; R/ U/ u; Z
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);" J, o3 n& U1 q- V  ]: r
  41. * j; E0 r, Z! k2 r* M7 e
  42.     // 将字形数据传递给OpenGL纹理
    + q- D7 f$ j6 \, x
  43.     for (int i = 0; i < 128; i++) {
    & \* D# m! k6 Q8 @* z. X% T- p4 ~
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
    ' [: G* g% e3 a4 f
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);
    7 K, D! X6 U( N0 q  d/ m2 S
  46.             continue;
    # ]' @$ L/ D4 p- h3 a8 Y
  47.         }
    " u0 T2 Q$ `' y: T4 e" U
  48. & _/ X9 W  Z6 s4 P' b
  49.         glTexImage2D(  i$ ]) n5 j! N+ J4 Q  B
  50.             GL_TEXTURE_2D,5 [# g" O/ F3 D; F" G! }/ o
  51.             0,
    ; c- D: v9 D: {( V( m# a6 X
  52.             GL_RED,
    , W  o( T) w+ m5 U9 Z
  53.             face->glyph->bitmap.width,
    % P0 z( k1 `' \. e$ B2 @& ]+ Z) {/ z
  54.             face->glyph->bitmap.rows,7 K4 ]$ ?- \; a7 K
  55.             0,4 i8 _, s# Q" L, A  j, _
  56.             GL_RED,
    3 [  r+ Y! s' K) w; |; v! Y2 u; T
  57.             GL_UNSIGNED_BYTE,
    . ^. V) G7 Z% A) p9 L
  58.             face->glyph->bitmap.buffer
    " Z+ K, y: U9 B
  59.         );
    $ Q2 z' s2 ~5 }! A) B; l- L( @

  60. : C( ]9 E( _" a' S0 [& _
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    " [2 C  ]* `8 Y( ^! H
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);' y/ O& A# k* v4 G
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);3 B( V0 M5 P3 V' h+ `, I
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    3 ^* Z9 @& c6 U7 v0 d
  65.     }* ^' k5 m7 c6 G+ q( q, R- x
  66. }
    2 A1 r0 j5 }, G4 n

  67. 8 E$ r4 ?8 Y" E: c- u1 g2 y
  68. // 渲染字符串
    " |' A: H/ W8 F7 I$ `% y' D5 k
  69. void renderString(const char* text, float x, float y) {9 _! `+ q, h1 Z8 i$ v
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    $ g, I8 a; L+ p9 D) A# @5 [
  71. ( e# e; h+ \/ K
  72.     glEnable(GL_BLEND);5 ^- O; T$ Z9 Q/ W2 s
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);% W2 T: x8 p+ m# r8 q" c6 q9 }
  74. , A; J% Q8 N- q; g' J' w5 d
  75.     glBegin(GL_QUADS);" P" @0 Z, g5 R9 m, S9 D- c7 X9 o
  76.     for (const char* p = text; *p; p++) {5 b6 x, [. E$ h
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);7 }4 U' R3 ~+ X+ G
  78. " f; k& l0 @6 y+ t, T6 N5 o. P$ _
  79.         glTexImage2D(
    . |. g  V0 ^6 U0 @2 }" G
  80.             GL_TEXTURE_2D,3 m# ?/ `. Y: R: y6 v: A
  81.             0,/ }/ E6 k8 T( x
  82.             GL_RED,' v# U* `1 _: I7 i' I( {/ v
  83.             face->glyph->bitmap.width,/ G* V/ x) I, P2 N. E/ Z
  84.             face->glyph->bitmap.rows,' X. ~' [1 C3 Z7 _; D
  85.             0,  U+ _- X$ w- T' {# g. q
  86.             GL_RED,$ O$ w0 q7 A3 g" D" l- Y" ]
  87.             GL_UNSIGNED_BYTE,' x6 e7 B) L! `: |1 _
  88.             face->glyph->bitmap.buffer
    ' f& n! f5 A9 o: }
  89.         );
    ) L  D/ z/ ?9 x- b

  90. 2 a. [8 L: U9 H2 O' }1 F6 z$ T
  91.         float xpos = x + face->glyph->bitmap_left;
    # X2 o6 O3 g" a- A* u
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);
    ; g# {( V+ O0 O

  93. - ^& e( e0 n; h
  94.         float w = face->glyph->bitmap.width;
    9 F' a/ m" q% J& N2 A' h' w
  95.         float h = face->glyph->bitmap.rows;& E' E) M% S3 L! e3 N

  96. . Z) x5 _3 r# K/ k! u% J2 g
  97.         glTexCoord2f(0, 0);9 k: G9 N9 g. h/ x  T
  98.         glVertex2f(xpos, ypos);
    2 r4 a; q" b5 G, ]  U* w8 v- g5 x
  99. 1 I% x8 `+ f$ [  @+ ^
  100.         glTexCoord2f(0, 1);/ B( K" k) X/ `1 }& O; T# h
  101.         glVertex2f(xpos, ypos + h);
    5 z  G+ h/ i$ y- N( n; ^4 W2 z
  102. + n5 i) Y3 |% |- c7 }3 k% a
  103.         glTexCoord2f(1, 1);  i& Z! [" \9 E5 Z) W
  104.         glVertex2f(xpos + w, ypos + h);
    ) ]8 U% s" R- A% s6 G4 @( R

  105. . g" [' t! \) A; L' b) u
  106.         glTexCoord2f(1, 0);( V/ D) u9 x$ [! i$ \4 q
  107.         glVertex2f(xpos + w, ypos);: L- l# w$ M$ m2 g" u

  108. ' u; L) r& r9 r, }9 c
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距
    ! I; S: L% L' ?' K0 L6 q
  110.     }
    , R+ o8 f! w) i, u0 K+ ^% x
  111.     glEnd();
    : M1 O6 P0 R; a* y

  112.   v% Q/ n6 v6 J/ s# L0 [! O) \
  113.     glDisable(GL_BLEND);
    ; }) L, b0 [. X. a' u( F- M
  114. }- r# b  z* t; g
  115. ! C- M- m6 q- V* r( N
  116. int main() {
    . Q' A, y2 C# t2 ]# X. \, _" N3 d
  117.     if (!glfwInit()) {# S8 U" H# H% ?& W4 r' H1 f
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    ; z2 J3 T8 r- |% q0 o* M
  119.         return -1;
    ( ^% d+ h* p0 S* g& b1 ~* P3 ^
  120.     }. x/ o" g! {! ~) J

  121. . U! }/ @+ Q( C/ F
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);/ @8 J, c1 n. w' W* }' |& L7 Q3 o
  123.     if (!window) {
    & H$ X% P, b+ O1 q  _/ A6 j0 F
  124.         fprintf(stderr, "Failed to create GLFW window\n");: L! i) m0 `0 t, R8 y, ^
  125.         glfwTerminate();
    0 N$ k- [8 p' `- V& Q( X$ ~0 ~
  126.         return -1;
    , B% w# ~9 w- s: J
  127.     }
    8 Y& e; P1 l5 o) ]

  128. 3 U- B% B3 [8 L; g# b) o
  129.     glfwMakeContextCurrent(window);& J' Q& e4 e, U7 I# k
  130.     glewInit();
    $ f* C. R8 n2 H9 b3 M+ A
  131. & b0 v( }0 n4 c: ~* F" }1 k. S: m
  132.     initialize();
    ) A! }/ Z+ ~+ Y- o0 |2 {: @

  133. 4 @( M" `1 r5 q7 Y4 X, _
  134.     while (!glfwWindowShouldClose(window)) {
    4 V8 W, c5 P( P1 B" M! \2 e7 z
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);, _# O: Y# o. W/ @
  136.         glClear(GL_COLOR_BUFFER_BIT);4 _% n+ u: z& l( b& T! [
  137. ( K: L: k# ^5 ^- k
  138.         glColor3f(1.0f, 1.0f, 1.0f);
    ' X" H$ b: u, p4 R
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);$ X, e3 ]1 s0 Y* A

  140. . T- v3 J. S1 f, ]; |1 f# ?6 Q
  141.         glfwSwapBuffers(window);" a6 S( B9 R: {$ z8 c6 f
  142.         glfwPollEvents();/ ]. [/ e1 y9 D9 C8 a
  143.     }" j$ Y4 B; X3 f) c; _; s4 v/ U4 [* E
  144. ' a0 m- ~+ j1 B- l8 S2 i, N2 n
  145.     FT_Done_Face(face);, c+ I, s# {; B# v( m% W
  146.     FT_Done_FreeType(library);
    # k5 D6 o% G$ A" J; u6 E4 U

  147. % Y) R% P2 Z; V- K% j$ |
  148.     glfwTerminate();
    ( I4 y* m2 f5 x, H8 u) |+ t: z
  149. ' n8 y. b8 d  w9 ^6 z9 {& z# P
  150.     return 0;1 ^& Q# t3 K1 L( r
  151. }9 i- R! R& g: F) o, e/ Q; t* x
复制代码

3 S3 d3 e+ Y- q6 j+ R  V
' [( z& P* R' `+ L$ 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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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