冒险解谜游戏中文网 ChinaAVG

标题: 【Opengl游戏汉化 #5】 尼比鲁:秘密年代 (NiBiRu)字幕显示函数修改2 [打印本页]

作者: shane007    时间: 2023-9-6 15:25
标题: 【Opengl游戏汉化 #5】 尼比鲁:秘密年代 (NiBiRu)字幕显示函数修改2
本帖最后由 shane007 于 2023-9-6 15:32 编辑
5 E& @2 I' l, Q$ g- D3 ?
; l, o; ~6 j, [8 o以下是一个用来做参照的opengl显示字符串的代码,使用了freetype库。* ~( a  u: N  W7 S5 r3 d9 i0 o
本代码经过分析以及改写之后,将取代游戏原有的显示函数。
( u3 n( e0 X/ j( G
5 K) Z8 z. C1 }代码详细说明如下& T  g1 E( O+ p% o% S
# z+ m! G7 n3 Y4 M* Z3 P
  1. 在上述 renderString 函数中,我们有以下关键部分的解释:
    . E9 K* \: R" ]9 l& h

  2. ) t  A  Y6 s5 p/ i
  3. glBindTexture(GL_TEXTURE_2D, fontTexture);:将字体纹理绑定到当前的OpenGL上下文。这是因为我们要使用 fontTexture 中存储的字形位图数据进行渲染。( R: G& w# {: W9 E; [1 M
  4. ( ?2 p6 Q7 J4 b  d6 B7 i
  5. glEnable(GL_BLEND); 和 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);:启用混合模式以处理字符的透明度。混合模式通过 glBlendFunc 设置,这里使用了常见的源和目标因子来实现源颜色与目标颜色的混合,从而实现透明效果。
    7 m% h: ~/ d" E# V
  6. ( N  J0 I* F0 E: d4 R
  7. glBegin(GL_QUADS); 和 glEnd();:在这两个函数之间的代码用于指定字符的四边形顶点,以便在OpenGL上下文中绘制字符。
    & }, k& w! p- o. @. z0 W9 w

  8. " a0 y. v$ ~: \; c6 L7 t" E3 e
  9. for (const char* p = text; *p; p++) { ... }:这个循环遍历传递给函数的字符串 text 中的每个字符,然后为每个字符执行以下操作:2 [" @7 N: W0 }: s  V+ T$ F
  10. ( r9 m  N0 W, ^$ N! b6 Z
  11. FT_Load_Char(face, *p, FT_LOAD_RENDER);:使用FreeType加载字符的字形数据,包括轮廓和位图信息。加载后,可以从 face->glyph 中访问该字符的字形数据。8 u# A) \0 Y" p
  12. - H2 E7 ^8 B# w
  13. 计算字符在屏幕上的位置和大小,包括 xpos(x坐标)、ypos(y坐标)、w(宽度)和 h(高度)。
    # Y: u) X' |9 A3 V

  14. ( p. z" x# C, b( y- ?
  15. 使用 glTexCoord2f 和 glVertex2f 来指定字符的纹理坐标和顶点坐标,以创建一个四边形。这四边形将字形的位图数据绘制到屏幕上的指定位置。
    ; s2 v& [9 d+ N0 U& V4 M
  16. ' y; V/ `' A0 ?. }2 e
  17. x += (face->glyph->advance.x >> 6);:更新 x 坐标,以便将下一个字符紧密排列在当前字符的后面。face->glyph->advance.x 包含字符的横向位移信息,>> 6 是用来将其转换为像素单位的操作。* B3 j3 g9 A# @$ c4 k! i

  18. & a7 x( \* {0 |" d) ~- L
  19. 最后,glDisable(GL_BLEND); 用于禁用混合模式,以免影响后续的绘制操作。
    ( s7 _7 {* ]% V

  20. % d  O7 _( U( t, ]
  21. 总之,renderString 函数的作用是将传递给它的字符串中的字符一个接一个地绘制到OpenGL上下文中,使用FreeType加载的字形数据和字体纹理来实现文本渲染效果。渲染过程涉及到字符的位置计算、纹理坐标的设置以及混合模式的启用和禁用,以确保字符在屏幕上正确显示。) Y: p" [1 t$ A- a) P1 Y3 h7 R
复制代码
+ z+ d9 n+ X2 s

2 O# T! P7 e( S. \; H" G9 ^4 ?% T9 w
  1. 字形数据处理的关键函数之一。以下是 FT_Load_Char 函数的详细解释:
    # h' e0 {2 i3 P# _" @
  2.   e* M; f+ V1 a
  3. 参数:/ t' v- b; Z+ L+ W% K$ B, I% \
  4. " c/ A/ Y) e# ^9 T2 |: N' u5 H1 x
  5. face:一个指向已经打开的字体文件的 FT_Face 结构体的指针。FT_Face 包含了字体的各种信息,包括字形数据。
    & H- Y! r3 j" B$ _
  6. char_code:要加载的字符的Unicode编码值。您需要传递字符的Unicode编码作为此参数,以指定要加载的字符。
    0 k2 b7 X$ e4 m" ?  J
  7. load_flags:一个用于控制字形加载选项的标志位。您可以使用这些标志位来控制加载的方式,例如是否要加载字形的轮廓数据、是否要加载字形的位图数据等。! ?2 |  x3 T0 B1 x" E% F
  8. 功能:
    * J. D5 e5 P6 w# Q2 J' b  i

  9. 4 R9 p- C  o' ~9 W. c' R
  10. FT_Load_Char 函数的主要功能是加载指定字符的字形数据。
    % b$ z# A3 C5 z7 K/ ]$ ~2 b
  11. 如果成功,它将在 FT_Face 结构体中的 glyph 字段中填充有关字符的字形信息。7 O2 Z, `9 q" G! ^+ f8 T; A
  12. 这包括了字符的轮廓数据、位图数据、宽度、高度、位图偏移等等,具体取决于传递给 load_flags 参数的设置。; U# c( c4 J1 q
  13. 使用示例:
    6 e4 t& Q* g- ?1 d) E# v

  14. ; M0 U+ g2 r# Y+ \$ M0 m, n+ J
  15. c
    5 d4 x- V* ^# J1 z
  16. Copy code, B, @3 G" k5 e* ^
  17. FT_Load_Char(face, 'A', FT_LOAD_RENDER);; X9 N' x! y+ M1 M$ E) a& T" B# C
  18. 这个示例会加载字体中字符 'A' 的字形数据,并将其渲染到位图中。FT_LOAD_RENDER 标志告诉FreeType要渲染字符的位图数据。加载后,您可以在 face->glyph 结构体中找到有关 'A' 字符的相关信息,包括位图数据、宽度、高度、位图偏移等等。$ x. M! D9 B, q( {; }" g) f

  19. ' I% e$ L9 C8 S. k) @' z2 Y
  20. 错误处理:. r- t+ J6 j! l! t- R

  21. 5 U4 m1 A0 ]* l1 |9 |1 h
  22. 如果加载失败,FT_Load_Char 函数可以返回错误代码。您应该检查返回值以进行错误处理,并根据需要采取适当的措施,例如跳过加载失败的字符或终止渲染过程。6 n) F- s) }- R( b6 d, x
  23. 总之,FT_Load_Char 函数是FreeType库中用于加载指定字符的字形数据的重要功能之一,它使您能够准备要渲染的字符数据,以便在文本渲染中使用。加载的数据可以包括字符的轮廓信息(矢量数据)和位图信息,具体取决于 load_flags 参数的设置。这个函数在字体渲染中起到关键作用,以便将字符正确呈现在屏幕上。
复制代码
2 s: Q5 K: T, }* D3 y
& v+ R# i$ W) N# x( Z) I
代码4 J) y( U; O4 G" J7 [4 ?4 K# j
6 R) D- ^5 q6 u* g$ d( E5 S% b

  1. % d; H8 P: }4 P8 C5 [

  2. - R! {" A1 ]) T. D$ a2 e9 y3 |; U; e' ~
  3. ' r' M! r8 g2 ~8 J2 A
  4. #include <stdio.h>
    6 \# O; n3 g& f  d1 L
  5. #include <stdlib.h>
    + h" y. q. e0 W1 M8 y& I
  6. #include <GL/glew.h>
    ) p4 p9 f& p; o0 @9 a$ K. v
  7. #include <GLFW/glfw3.h>( F6 ?0 g- {- N) R- j! p, @3 r2 B
  8. #include <ft2build.h>
    3 h% E6 y  }5 A
  9. #include FT_FREETYPE_H
    / V  o/ x! G* `2 Z9 S
  10. , W2 r0 b" }$ {8 Y1 _- h- Y
  11. // 定义字形数据的字节数组4 |3 j8 y9 e2 {
  12. unsigned char fontData[] = {! D# u1 ^5 X# q! ?$ }( B# Z
  13.     // 字形数据的字节表示
    ( S# G9 T7 u5 k9 f: S
  14.     // 例如,这里可以包含字母、数字和符号的字形数据) S% X$ B* O: K4 ~) B2 u( g
  15. };
    , T" s' L* T4 L/ K6 y% F
  16. 4 U" l( f& y, h  k( o
  17. FT_Library library;' ?  m% [8 c! }$ g* `
  18. FT_Face face;8 Q( J# |/ u  d! C
  19. GLuint fontTexture;2 B, D6 r% ]5 {) K5 k: k* A  c

  20. 7 s3 A" C: U( {7 |  @" l
  21. // 初始化FreeType库和OpenGL+ a: {0 J) Y0 K3 T% X
  22. void initialize() {
    ! ^' N8 V6 i$ \$ W$ R
  23.     if (FT_Init_FreeType(&library)) {
    ( V( a3 m' U9 F" U6 {8 F
  24.         fprintf(stderr, "Failed to initialize FreeType\n");
    + l8 `" V, U! R! K8 g2 W* V1 R7 C
  25.         exit(EXIT_FAILURE);
    1 ^1 C) X" ?# e6 Y$ a8 ~- b0 s# A
  26.     }+ f$ D" [: c! J& W) T" r

  27. ' f0 X+ X: x2 i# H( {0 ^  Q
  28.     if (FT_New_Memory_Face(library, fontData, sizeof(fontData), 0, &face)) {
    ! g( [7 X( u7 x
  29.         fprintf(stderr, "Failed to create a FreeType font face\n");
    & X. N' \5 |! s& d: A: z, l8 Q
  30.         exit(EXIT_FAILURE);
    7 r; r. Q9 A- K' o% @* @
  31.     }
    9 s. `( z* G7 \8 s. b
  32. 8 z7 W/ G3 ~$ I9 a- p
  33.     if (FT_Set_Pixel_Sizes(face, 0, 48)) { // 设置字体大小0 u: w' Q: V: E- v
  34.         fprintf(stderr, "Failed to set font size\n");, M2 [' [! X' \8 t
  35.         exit(EXIT_FAILURE);+ t$ _$ j; _0 y& A2 d8 Y
  36.     }
    : Y3 a' L1 T: q- K' u8 }# F
  37. 0 F! x1 i8 _0 d# N
  38.     glGenTextures(1, &fontTexture);
    ! [# W: E6 w$ J1 q
  39.     glBindTexture(GL_TEXTURE_2D, fontTexture);
    1 Q' b# B& W9 i* ?$ K3 ~. q
  40.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    7 G+ f: w$ N- x) v9 N

  41. 4 E  h" ^7 p  y) X. H
  42.     // 将字形数据传递给OpenGL纹理0 M, q- R) D3 O3 Y
  43.     for (int i = 0; i < 128; i++) {
    ( e7 o+ M  K# f7 u# w) x
  44.         if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
      ~, h# [+ d4 G: S6 M2 T
  45.             fprintf(stderr, "Failed to load glyph for character '%c'\n", i);8 A0 p7 v7 _5 C# R: l2 l, V! i, n& x
  46.             continue;
    1 s9 }5 k4 N# j3 A9 g6 y
  47.         }* h/ z( q3 ?- M7 y" u) P
  48. , X) U5 }( Y$ X& K7 h
  49.         glTexImage2D(# z' g( i. l( k% y
  50.             GL_TEXTURE_2D,, E5 \. P& O0 G% o6 y5 j
  51.             0,
    & O: {  k' H* `1 b
  52.             GL_RED,9 I. J. e6 J* M+ ~2 ?7 p
  53.             face->glyph->bitmap.width,7 n/ |4 S7 L$ @& X. o$ H- k" }; h
  54.             face->glyph->bitmap.rows,4 Y& q6 p7 x: T# e" C+ O( m2 ?
  55.             0,
    ) u$ K' T0 k7 Z
  56.             GL_RED,& w- {" [) J' D9 ?! ^& G
  57.             GL_UNSIGNED_BYTE,
    ' p+ S# d; C- S) C( h, R3 F2 X
  58.             face->glyph->bitmap.buffer# b! x5 Q' `/ a, r3 y3 _8 D! L
  59.         );
    % Y% K" `9 P. ^9 @! d6 S& w& [
  60. % V( A- V2 `2 b* a4 O# g! e
  61.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);9 a; x. n! F, d
  62.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2 u# W- N4 W, ~; u, F3 x
  63.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    $ W; O7 z1 C5 `3 ^! I' }; t7 z
  64.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    ' B! p6 x, n. }
  65.     }
    5 R8 K/ m$ Q# C' L, `  ]% P
  66. }
    4 v+ f  D, h6 L% R; u

  67.   I. {3 D8 F  S, N" U# Y! A
  68. // 渲染字符串
    9 d5 b: A! L+ P1 y" S
  69. void renderString(const char* text, float x, float y) {
    * x$ i4 ~) U+ L, ~# [
  70.     glBindTexture(GL_TEXTURE_2D, fontTexture);& x/ D8 I/ j4 Y9 e! O8 W, w
  71. 3 f8 s2 `; D+ [( t# p: z% w; y$ H' Y
  72.     glEnable(GL_BLEND);
    1 t( b5 s' q& o6 r  R  W9 e
  73.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    . g4 L! M& }3 v% `7 _
  74. / P# f% h0 B. }/ R3 p' ?; @' @
  75.     glBegin(GL_QUADS);
    2 Q( E4 z4 ?; t( [$ _- Z
  76.     for (const char* p = text; *p; p++) {8 J, m2 D8 a( T/ o) S1 W% }; d! x$ W
  77.         FT_Load_Char(face, *p, FT_LOAD_RENDER);
    7 v9 }5 ?$ `. S$ @" I+ y4 @7 @) X
  78. : m8 d( i: t) I: S2 y# E1 V
  79.         glTexImage2D(
    " G6 a8 {( U$ J
  80.             GL_TEXTURE_2D,
    : t( z, ^& s# m1 r& m4 z
  81.             0,
    2 C) d0 c+ V; P$ ~
  82.             GL_RED,7 X, M& n' M5 M) I
  83.             face->glyph->bitmap.width,$ r' Z2 T/ J! F+ X
  84.             face->glyph->bitmap.rows,
      y3 R. }" Y6 p: l# f
  85.             0,. E  U1 l. g3 r* J  F: |* S/ G
  86.             GL_RED,
    1 X/ S6 E" f  [- p' K
  87.             GL_UNSIGNED_BYTE,
    & v5 z/ ^  [8 ~7 C6 m8 [* a" n
  88.             face->glyph->bitmap.buffer
    / i" w# K3 ^0 C/ Z5 ^" K; U  v
  89.         );
    / O! u9 g6 `. `* I! s4 [4 Y
  90. ; A  N6 Y7 [  h% Y7 e1 D
  91.         float xpos = x + face->glyph->bitmap_left;
    1 u: y' l7 B7 Q9 L+ Y4 ~8 ?
  92.         float ypos = y - (face->glyph->bitmap.rows - face->glyph->bitmap_top);
    ( i: A7 W& P9 b3 K5 ~7 O

  93. 0 n* t4 s( g1 T0 x9 ^
  94.         float w = face->glyph->bitmap.width;- `" ?% |3 v, R- @) H& _
  95.         float h = face->glyph->bitmap.rows;1 h5 p. @' {0 i

  96. ; c- N6 Z! N: R% z
  97.         glTexCoord2f(0, 0);9 _+ Y9 F) P5 R% H9 s
  98.         glVertex2f(xpos, ypos);- p0 F- }% S9 z- i; ~) }
  99. . C5 P; N( K2 |9 a5 Z! X
  100.         glTexCoord2f(0, 1);
    8 ?+ ]& f1 L* [9 U! {8 x3 R
  101.         glVertex2f(xpos, ypos + h);( p, @) N  j; z8 ^9 g$ t

  102. 1 a5 @3 {+ ?5 s) C" W% u+ z' V& t
  103.         glTexCoord2f(1, 1);" O' x  r% o5 d7 O
  104.         glVertex2f(xpos + w, ypos + h);9 ~/ k0 \! e, l& j& s( ]

  105. 3 A3 V' N, q. H0 m
  106.         glTexCoord2f(1, 0);, q8 W/ [. {7 e) u1 [- o8 m  e
  107.         glVertex2f(xpos + w, ypos);
    - k3 |. D+ ?6 j' ~+ ?" _  b: P

  108. 4 S& k  r  ]8 F: a
  109.         x += (face->glyph->advance.x >> 6); // 字符之间的间距* T" k+ t, R8 ^4 z  }  ~
  110.     }
    # e1 A# Q! P# Q1 Y
  111.     glEnd();  G% k) R5 H5 U2 u9 O$ V

  112.   @: p+ I- A9 Y
  113.     glDisable(GL_BLEND);
    : ~. J: N: N4 }0 C
  114. }6 y) H  D. X: f+ S7 \: E. i

  115. ) k" O& [/ E- H5 I3 G8 N7 T& z
  116. int main() {
    8 }7 @1 L7 _; W
  117.     if (!glfwInit()) {8 e5 X" q7 Y% j) g; T
  118.         fprintf(stderr, "Failed to initialize GLFW\n");
    ( y0 N9 }: O8 Z7 n% |  t$ K
  119.         return -1;+ G4 o$ D  n% H1 u0 l% ?
  120.     }6 P, ?+ J8 B+ W

  121. . B0 m! f4 Y6 v+ p8 W
  122.     GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Text Rendering", NULL, NULL);% \9 l6 v! Q5 f/ [0 H4 i
  123.     if (!window) {( \6 h- @' M3 \, {5 }4 M  d
  124.         fprintf(stderr, "Failed to create GLFW window\n");
    ! {/ w2 O: w6 J$ l$ x- _6 M& e; ?
  125.         glfwTerminate();
    ' k9 z) _0 K' d5 E6 ?- O( ?
  126.         return -1;
    2 m9 I% {! e8 e3 s- ~2 N
  127.     }  |. \1 ?7 O" J- @

  128. . V4 d9 h: {* }; H, ~( B* @0 w4 W
  129.     glfwMakeContextCurrent(window);
    / l. p2 {" y  V! h/ K
  130.     glewInit();
    - R1 j$ }8 Q; b6 ]! O0 n

  131. 3 J  T5 `- j; d  ?' u+ W7 M2 ?
  132.     initialize();$ @1 R& J! H, R, I0 o
  133. 3 Y( j, P6 J1 L; a
  134.     while (!glfwWindowShouldClose(window)) {4 ]( g- G! V+ y2 X6 n
  135.         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);/ i( d2 A) O# E% |' @
  136.         glClear(GL_COLOR_BUFFER_BIT);5 m" {, P5 Y5 u& w
  137. 2 {4 U2 L7 F0 s+ t! N2 q( K
  138.         glColor3f(1.0f, 1.0f, 1.0f);0 t, g; G; _: L6 g
  139.         renderString("Hello, OpenGL!", 100.0f, 100.0f);
    , w; ~4 X8 x& t, h2 M9 q1 R( ]8 {
  140. " |& P+ {- y6 i' Y6 S4 X# n& p
  141.         glfwSwapBuffers(window);
    . @' m' N6 H( g3 ]# h  a
  142.         glfwPollEvents();8 X- Q$ ?, W1 Z. S, a
  143.     }0 J: f7 R8 U9 d) c; }2 H

  144. + d, P" K- W2 _5 d9 d* a
  145.     FT_Done_Face(face);7 M. \2 w  D0 q* I& D1 Y
  146.     FT_Done_FreeType(library);+ ^5 |, O  v3 s- z$ ~& E' c* ?
  147. ) M  C! Y( e8 Q
  148.     glfwTerminate();
    / h( q( a. Q5 y4 c
  149. : {# z8 h8 y2 Z4 I4 U- h2 ~5 b
  150.     return 0;& q" S9 l% p( x2 v( a2 I* Z5 }
  151. }9 {: U! e; x8 i0 g
复制代码
3 N3 G) @. g2 m/ q

0 G5 C9 H" Q+ V, x




欢迎光临 冒险解谜游戏中文网 ChinaAVG (https://chinaavg.com/) Powered by Discuz! X3.2