我正在try 在OpenGL中渲染以下图像:
(忽略白线,这不是图像的一部分)
为了渲染,我将文本的静态纹理设置为PNG,如下所示:
目前,这是我的Cargo.toml
分:
[package]
name = "render-clock"
version = "0.1.0"
edition = "2021"
[dependencies]
elara-gfx = { git = "https://github.com/elaraproject/elara-gfx" }
这是我的顶点着色器代码:
#version 100
attribute highp vec2 position;
attribute highp vec2 tex_coord;
attribute lowp vec4 vertex_color;
varying highp vec2 TexCoord;
varying lowp vec4 VertexColor;
void main() {
VertexColor = vertex_color;
TexCoord = tex_coord;
gl_Position = vec4(position.x * 0.66, position.y, 0.0, 1.0);
}
和我的片段着色器:
#version 100
varying highp vec2 TexCoord;
varying lowp vec4 VertexColor;
uniform sampler2D uTexture;
void main() {
lowp vec4 col = texture2D(uTexture, TexCoord);
gl_FragColor = vec4(VertexColor.rgb, col.a);
}
和我的程序代码:
use elara_gfx::{Buffer, BufferType, Program, Shader, VertexArray, PixelArray, Texture2D};
use elara_gfx::{GLWindow, HandlerResult, WindowHandler};
use std::error::Error;
const VERT_SHADER: &str = include_str!("shaders/clock.vert"); // code given above
const FRAG_SHADER: &str = include_str!("shaders/clock.frag"); // code given above
const IMG_PATH: &str = "clock_text.png"; // image shown above
struct Handler {
vao: VertexArray,
texture: Texture2D
}
impl Handler {
fn new() -> Result<Handler, String> {
let vertices: [f32; 42] = [
// positions // colors // texture coords
0.5, 0.5, 0.13, 0.15, 0.16, 1.0, 1.0, // top right
0.5, -0.5, 0.13, 0.15, 0.16, 1.0, 0.0, // bottom right
-0.5, 0.5, 0.13, 0.15, 0.16, 0.0, 1.0, // top left
0.5, -0.5, 0.13, 0.15, 0.16, 1.0, 0.0, // bottom right
-0.5, -0.5, 0.13, 0.15, 0.16, 0.0, 0.0, // bottom left
-0.5, 0.5, 0.13, 0.15, 0.16, 0.0, 1.0, // top left
];
let texture = Texture2D::new()?;
texture.bind();
texture.parameter_2d(gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32);
texture.parameter_2d(gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32);
let mut img = PixelArray::load_png(IMG_PATH).unwrap();
img.flipv();
texture.set_image_2d(img);
texture.generate_mipmap();
let vao = VertexArray::new()?;
vao.bind();
let vbo = Buffer::new()?;
vbo.bind(BufferType::Array);
vbo.data::<f32>(BufferType::Array, &vertices, gl::STATIC_DRAW);
let vertex_shader = Shader::new(&VERT_SHADER, gl::VERTEX_SHADER)?;
let fragment_shader = Shader::new(&FRAG_SHADER, gl::FRAGMENT_SHADER)?;
let program = Program::new(&[vertex_shader, fragment_shader])?;
program.use_program();
let pos_attrib = vao.get_attrib_location(&program, "position");
let col_attrib = vao.get_attrib_location(&program, "vertex_color");
let tex_coord_attrib = vao.get_attrib_location(&program, "tex_coord");
vao.enable_vertex_attrib(pos_attrib as u32);
vao.enable_vertex_attrib(col_attrib as u32);
vao.enable_vertex_attrib(tex_coord_attrib as u32);
vao.vertex_attrib_pointer::<f32>(pos_attrib as u32, 2, gl::FLOAT, false, 7, 0);
vao.vertex_attrib_pointer::<f32>(col_attrib as u32, 3, gl::FLOAT, false, 7, 2);
vao.vertex_attrib_pointer::<f32>(tex_coord_attrib as u32, 2, gl::FLOAT, false, 7, 5);
Ok(Handler {vao, texture})
}
}
impl WindowHandler for Handler {
fn on_draw(&mut self) -> HandlerResult<()> {
unsafe {
gl::ClearColor(1.0, 1.0, 1.0, 1.0);
gl::Clear(gl::COLOR_BUFFER_BIT);
self.texture.bind();
self.vao.bind();
gl::DrawArrays(gl::TRIANGLES, 0, 6);
self.vao.unbind();
self.texture.unbind();
}
Ok(())
}
}
fn main() -> Result<(), Box<dyn Error>> {
let (app, window) = GLWindow::new_with_title("OpenGL clock")?;
window.get_context()?;
let render_handler = Handler::new()?;
app.run_loop(window, render_handler);
Ok(())
}
我的两难境地是,要渲染我想要的图像,需要渲染2个四边形,其中一个文本是透明的,下面是一个填充了纯色的矩形四边形.文本四边形需要有纹理坐标,但矩形四边形不应该有(也不需要)纹理坐标.然而,try 使用单个着色器程序/VAO/VBO渲染两者似乎不是OpenGL所能做到的.我必须求助于使用2个VAOS/VBO/着色器程序来在矩形四边形上分层文本四边形吗?有没有更好的办法?