OpenGL纹理闪烁

时间:2017-01-08 18:29:18

标签: opengl rust

我有以下Rust代码来渲染带纹理的多维数据集。我正在使用piston2d-opengl_graphics来加载纹理。 我的main.rs

extern crate sdl2;
extern crate glm;
extern crate gl;
extern crate libc;
extern crate num_traits;
extern crate opengl_graphics;

mod graphics;

use graphics::shader::Shader;

use sdl2::video::GLProfile;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;

use std::ffi::CString;
use std::ptr;
use num_traits::identities::One;
use gl::types::*;
use std::mem;
use std::path::Path;

fn find_sdl_gl_driver() -> Option<u32> {
    for (index, item) in sdl2::render::drivers().enumerate() {
        if item.name == "opengl" {
            return Some(index as u32);
        }
    }
    None
}

fn main() {
    let sdl_context = sdl2::init().unwrap();
    let video_subsystem = sdl_context.video().unwrap();
    let gl_attr = video_subsystem.gl_attr();

    gl_attr.set_context_profile(GLProfile::Core);
    gl_attr.set_context_flags().debug().set();
    gl_attr.set_context_version(3, 3);

    gl_attr.set_depth_size(24);
    gl_attr.set_red_size(8);
    gl_attr.set_green_size(8);
    gl_attr.set_blue_size(8);
    gl_attr.set_alpha_size(8);
    gl_attr.set_stencil_size(8);

    let window = video_subsystem.window("Renderer", 1024, 768,).opengl().build().unwrap();
    let renderer = window.renderer().present_vsync().index(find_sdl_gl_driver().unwrap()).build().unwrap();

    unsafe {
        gl::load_with(|name| video_subsystem.gl_get_proc_address(name) as *const _);
        renderer.window().unwrap().gl_set_context_to_current().unwrap();

        gl::ClearColor(0.0, 0.0, 0.0, 1.0);
        gl::Enable(gl::DEPTH_TEST);
        gl::DepthFunc(gl::LESS);
    }

    let mut vao = 0;

    unsafe {
        gl::GenVertexArrays(1, &mut vao);
        gl::BindVertexArray(vao);
    }

    let shader_program = Shader::new("shader.vert", "shader.frag").unwrap();
    let mvp_location;
    let texture_sampler_id;

    unsafe {
        mvp_location = gl::GetUniformLocation(shader_program.program, CString::new("MVP").unwrap().as_ptr());
        texture_sampler_id = gl::GetUniformLocation(shader_program.program, CString::new("texture_sampler").unwrap().as_ptr());
    }

    let projection = glm::ext::perspective(45f32, 4f32 / 3f32, 0.1f32, 100f32);
    let view = glm::ext::look_at(glm::Vec3::new(4f32, 3f32, 3f32),
                            glm::Vec3::new(0f32, 0f32, 0f32),
                            glm::Vec3::new(0f32, 1f32, 0f32));

    let model_mat = glm::Matrix4::<f32>::one();
    let mvp = projection * view * model_mat;

    let mvp_array_vec4 = mvp.as_array();

    let mut mvp_array: Vec<f32> = Vec::new();

    for i in 0..mvp_array_vec4.len() {
        for j in 0..4 {
            mvp_array.push(mvp_array_vec4[i][j]);
        }
    }

    let cube_vertices = vec![
        -1.0f32,-1.0f32,-1.0f32,
        -1.0f32,-1.0f32, 1.0f32,
        -1.0f32, 1.0f32, 1.0f32,
         1.0f32, 1.0f32,-1.0f32,
        -1.0f32,-1.0f32,-1.0f32,
        -1.0f32, 1.0f32,-1.0f32,
         1.0f32,-1.0f32, 1.0f32,
        -1.0f32,-1.0f32,-1.0f32,
         1.0f32,-1.0f32,-1.0f32,
         1.0f32, 1.0f32,-1.0f32,
         1.0f32,-1.0f32,-1.0f32,
        -1.0f32,-1.0f32,-1.0f32,
        -1.0f32,-1.0f32,-1.0f32,
        -1.0f32, 1.0f32, 1.0f32,
        -1.0f32, 1.0f32,-1.0f32,
         1.0f32,-1.0f32, 1.0f32,
        -1.0f32,-1.0f32, 1.0f32,
        -1.0f32,-1.0f32,-1.0f32,
        -1.0f32, 1.0f32, 1.0f32,
        -1.0f32,-1.0f32, 1.0f32,
         1.0f32,-1.0f32, 1.0f32,
         1.0f32, 1.0f32, 1.0f32,
         1.0f32,-1.0f32,-1.0f32,
         1.0f32, 1.0f32,-1.0f32,
         1.0f32,-1.0f32,-1.0f32,
         1.0f32, 1.0f32, 1.0f32,
         1.0f32,-1.0f32, 1.0f32,
         1.0f32, 1.0f32, 1.0f32,
         1.0f32, 1.0f32,-1.0f32,
        -1.0f32, 1.0f32,-1.0f32,
         1.0f32, 1.0f32, 1.0f32,
        -1.0f32, 1.0f32,-1.0f32,
        -1.0f32, 1.0f32, 1.0f32,
         1.0f32, 1.0f32, 1.0f32,
        -1.0f32, 1.0f32, 1.0f32,
         1.0f32,-1.0f32, 1.0f32
    ];

    let cube_uv_coords: Vec<GLfloat> = vec![
        0.000059, 1.0-0.000004,
        0.000103, 1.0-0.336048,
        0.335973, 1.0-0.335903,
        1.000023, 1.0-0.000013,
        0.667979, 1.0-0.335851,
        0.999958, 1.0-0.336064,
        0.667979, 1.0-0.335851,
        0.336024, 1.0-0.671877,
        0.667969, 1.0-0.671889,
        1.000023, 1.0-0.000013,
        0.668104, 1.0-0.000013,
        0.667979, 1.0-0.335851,
        0.000059, 1.0-0.000004,
        0.335973, 1.0-0.335903,
        0.336098, 1.0-0.000071,
        0.667979, 1.0-0.335851,
        0.335973, 1.0-0.335903,
        0.336024, 1.0-0.671877,
        1.000004, 1.0-0.671847,
        0.999958, 1.0-0.336064,
        0.667979, 1.0-0.335851,
        0.668104, 1.0-0.000013,
        0.335973, 1.0-0.335903,
        0.667979, 1.0-0.335851,
        0.335973, 1.0-0.335903,
        0.668104, 1.0-0.000013,
        0.336098, 1.0-0.000071,
        0.000103, 1.0-0.336048,
        0.000004, 1.0-0.671870,
        0.336024, 1.0-0.671877,
        0.000103, 1.0-0.336048,
        0.336024, 1.0-0.671877,
        0.335973, 1.0-0.335903,
        0.667969, 1.0-0.671889,
        1.000004, 1.0-0.671847,
        0.667979, 1.0-0.335851
    ];

    let texture = opengl_graphics::Texture::from_path(&Path::new("uvtemplate.jpg")).unwrap();

    let mut vertex_buffer: GLuint = 0;
    let mut uv_buffer: GLuint = 0;

    unsafe {
        // generate buffer for the cube vertices
        gl::GenBuffers(1, &mut vertex_buffer);
        gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer);
        gl::BufferData(gl::ARRAY_BUFFER, (cube_vertices.len() * mem::size_of::<f32>()) as GLsizeiptr,
            mem::transmute(&cube_vertices[0]), gl::STATIC_DRAW);

        // generate buffer for the uv coordinates
        gl::GenBuffers(1, &mut uv_buffer);
        gl::BindBuffer(gl::ARRAY_BUFFER, uv_buffer);
        gl::BufferData(gl::ARRAY_BUFFER, (cube_uv_coords.len() * mem::size_of::<f32>()) as GLsizeiptr,
            mem::transmute(&cube_uv_coords[0]), gl::STATIC_DRAW);
    }

    let mut event_pump = sdl_context.event_pump().unwrap();

    'running: loop {

        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    break 'running
                },
                _ => {}
            }
        }

        unsafe { gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT) };

        shader_program.use_program();

        unsafe {

            gl::UniformMatrix4fv(mvp_location, 1, gl::FALSE, mvp_array.as_ptr());

            // bind texture to texture unit 0 and tell sampler to use unit 0
            gl::ActiveTexture(gl::TEXTURE0);
            gl::BindTexture(gl::TEXTURE_2D, texture.get_id());
            gl::Uniform1i(texture_sampler_id, 0);

            // set vertex data
            gl::EnableVertexAttribArray(0);
            gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer);
            gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, 0, ptr::null_mut());

            // set uv data
            gl::EnableVertexAttribArray(1);
            gl::BindBuffer(gl::ARRAY_BUFFER, uv_buffer);
            gl::VertexAttribPointer(1, 2, gl::FLOAT, gl::FALSE, 0, ptr::null_mut());

            gl::DrawArrays(gl::TRIANGLES, 0, 12 * 3);

            gl::DisableVertexAttribArray(0);
            gl::DisableVertexAttribArray(1);
        }

        renderer.window().unwrap().gl_swap_window();
    }
}

我的shader.rs

extern crate glm;
extern crate gl;

use self::gl::types::*;
use std::fs::File;
use std::io::Read;
use std::io;
use std::fmt;
use std::error;
use std::ffi::CString;
use std::ptr;
use std::str; 

#[derive(Debug)]
pub enum ShaderError {
    IoError(io::Error),
    CompilationError(String),
    LinkError(String),
    InfoLogError(str::Utf8Error)
}

impl fmt::Display for ShaderError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ShaderError::IoError(ref error) => write!(f, "IO Error: {}", error),
            ShaderError::CompilationError(ref error) => write!(f, "Shader compilation error: {}", error),
            ShaderError::LinkError(ref error) => write!(f, "Linking error: {}", error),
            ShaderError::InfoLogError(ref error) => write!(f, "InfoLog Error: {}", error),
        }
    }
}

impl error::Error for ShaderError {
    fn description(&self) -> &str {
        match *self {
            ShaderError::IoError(ref err) => err.description(),
            ShaderError::CompilationError(..) => "Error during shader compilation",
            ShaderError::LinkError(..) => "Error during linking",
            ShaderError::InfoLogError(ref err) => err.description(),
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            ShaderError::IoError(ref error) => Some(error),
            ShaderError::InfoLogError(ref error) => Some(error),
            _ => None
        }
    }
}

impl From<io::Error> for ShaderError {
    fn from(err: io::Error) -> ShaderError {
        ShaderError::IoError(err)
    }
}

impl From<str::Utf8Error> for ShaderError {
    fn from(err: str::Utf8Error) -> ShaderError {
        ShaderError::InfoLogError(err)
    }
}

pub struct Shader
{
    pub vertex_path: String,
    pub fragment_path: String,
    pub program: GLuint
}

impl Shader
{
    pub fn new(vert_path: &str, frag_path: &str) -> Result<Shader, ShaderError> {
        let vertex_shader = try!(Shader::compile_shader(vert_path, gl::VERTEX_SHADER));
        let fragment_shader = try!(Shader::compile_shader(frag_path, gl::FRAGMENT_SHADER));
        let program = try!(Shader::link_program(vertex_shader, fragment_shader));

        Ok(Shader {
            vertex_path: vert_path.to_string(),
            fragment_path: frag_path.to_string(),
            program: program
        })
    }

    fn compile_shader(path: &str, shader_type: GLenum) -> Result<GLuint, ShaderError> {
        let mut shader_data = String::new();
        let mut file = try!(File::open(path));

        try!(file.read_to_string(&mut shader_data));

        let shader;

        unsafe {
            shader = gl::CreateShader(shader_type);
            let shader_src = CString::new(shader_data.as_bytes()).unwrap();
            gl::ShaderSource(shader, 1, &shader_src.as_ptr(), ptr::null());
            gl::CompileShader(shader);

            // Get the compile status
            let mut status = gl::FALSE as GLint;
            gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

            // Fail on error
            if status != (gl::TRUE as GLint) {
                let mut len = 0;
                gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
                let mut buf = Vec::with_capacity(len as usize);
                buf.set_len((len as usize) - 1); // subtract 1 to skip the trailing null character
                gl::GetShaderInfoLog(shader, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);

                return match str::from_utf8(&buf) {
                    Ok(msg) => Err(ShaderError::CompilationError(msg.to_string())),
                    Err(err) => Err(ShaderError::InfoLogError(err))
                }
            }
        }
        Ok(shader)
    }

    fn link_program(vertex_shader: GLuint, fragment_shader: GLuint) -> Result<GLuint, ShaderError> {
        unsafe {
            let program = gl::CreateProgram();
            gl::AttachShader(program, vertex_shader);
            gl::AttachShader(program, fragment_shader);
            gl::LinkProgram(program);

            // get link status
            let mut status = gl::FALSE as GLint;

            gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

            // Fail on error
            if status != (gl::TRUE as GLint) {
                let mut len: GLint = 0;
                gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
                let mut buf = Vec::with_capacity(len as usize);
                buf.set_len((len as usize) - 1); // subtract 1 to skip the trailing null character
                gl::GetProgramInfoLog(program, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);

                return match str::from_utf8(&buf) {
                    Ok(msg) => Err(ShaderError::LinkError(msg.to_string())),
                    Err(err) => Err(ShaderError::InfoLogError(err))
                }
            }

            Ok(program)
        }
    }

    pub fn use_program(&self) {
        unsafe {
            gl::UseProgram(self.program);
        }
    }
}

我的顶点着色器:

#version 330 core

layout(location = 0) in vec3 vertex_position_modelspace;
layout(location = 1) in vec2 vertex_uv;

out vec2 uv_coord;

uniform mat4 MVP;

void main()
{
    gl_Position = MVP * vec4(vertex_position_modelspace, 1);

    uv_coord = uv_coord;
}

我的片段着色器:

#version 330 core

in vec2 uv_coord;

out vec3 color;

uniform sampler2D texture_sampler;

void main()
{
    color = texture(texture_sampler, uv_coord).rgb;
}

每当我尝试渲染立方体时,我总会得到像

这样的结果

enter image description here

enter image description here

它总是闪烁,并没有显示出正确的结果:

enter image description here

我尝试使用glutin作为窗口管理器,但这不起作用,所以我尝试切换到SDL2,但这也不起作用。我也尝试使用BMP文件而不是JPEG,但我得到了相同的结果。但是,如果我在C ++中编写相同的代码,那么我会得到正确的结果。

这是我的C ++代码,它可以正确呈现多维数据集:

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>

// Include GLEW
#include <GL/glew.h>

// Include GLFW
#include <glfw3.h>
GLFWwindow* window;

// Include GLM
#include <glm/glm.hpp>
#include <glm/ext.hpp>
using namespace glm;

GLuint LoadShader(const char * vertex_file_path, const char * fragment_file_path) {

    // Create the shaders
    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    // Read the Vertex Shader code from the file
    std::string VertexShaderCode;
    std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
    if (VertexShaderStream.is_open()) {
        std::string Line = "";
        while (getline(VertexShaderStream, Line))
            VertexShaderCode += "\n" + Line;
        VertexShaderStream.close();
    }
    else {
        printf("Impossible to open %s. \n", vertex_file_path);
        getchar();
        return 0;
    }

    // Read the Fragment Shader code from the file
    std::string FragmentShaderCode;
    std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
    if (FragmentShaderStream.is_open()) {
        std::string Line = "";
        while (getline(FragmentShaderStream, Line))
            FragmentShaderCode += "\n" + Line;
        FragmentShaderStream.close();
    }

    GLint Result = GL_FALSE;
    int InfoLogLength;

    // Compile Vertex Shader
    printf("Compiling shader : %s\n", vertex_file_path);
    char const * VertexSourcePointer = VertexShaderCode.c_str();
    glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
    glCompileShader(VertexShaderID);

    // Check Vertex Shader
    glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if (InfoLogLength > 0) {
        std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
        glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
        printf("%s\n", &VertexShaderErrorMessage[0]);
    }

    // Compile Fragment Shader
    printf("Compiling shader : %s\n", fragment_file_path);
    char const * FragmentSourcePointer = FragmentShaderCode.c_str();
    glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
    glCompileShader(FragmentShaderID);

    // Check Fragment Shader
    glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if (InfoLogLength > 0) {
        std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
        glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
        printf("%s\n", &FragmentShaderErrorMessage[0]);
    }

    // Link the program
    printf("Linking program\n");
    GLuint ProgramID = glCreateProgram();
    glAttachShader(ProgramID, VertexShaderID);
    glAttachShader(ProgramID, FragmentShaderID);
    glLinkProgram(ProgramID);

    // Check the program
    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if (InfoLogLength > 0) {
        std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
        glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
        printf("%s\n", &ProgramErrorMessage[0]);
    }

    glDetachShader(ProgramID, VertexShaderID);
    glDetachShader(ProgramID, FragmentShaderID);

    glDeleteShader(VertexShaderID);
    glDeleteShader(FragmentShaderID);

    return ProgramID;
}

GLuint loadBMP(const char * imagepath) {

    printf("Reading %s\n", imagepath);

    // Data read from the header of the BMP file
    unsigned char header[54];
    unsigned int dataPos;
    unsigned int imageSize;
    unsigned int width, height;
    // Actual RGB data
    unsigned char * data;

    // Open the file
    FILE * file = fopen(imagepath, "rb");
    if (!file)
    {
        printf("%s could not be opened.\n", imagepath);
        getchar();
        return 0;
    }

    // Read the header, i.e. the 54 first bytes

    // If less than 54 bytes are read, problem
    if (fread(header, 1, 54, file) != 54) {
        printf("Not a correct BMP file\n");
        return 0;
    }
    // A BMP files always begins with "BM"
    if (header[0] != 'B' || header[1] != 'M') {
        printf("Not a correct BMP file\n");
        return 0;
    }
    // Make sure this is a 24bpp file
    if (*(int*)&(header[0x1E]) != 0)
    {
        printf("Not a correct BMP file\n");
        return 0;
    }
    if (*(int*)&(header[0x1C]) != 24)
    {
        printf("Not a correct BMP file\n");
        return 0;
    }

    // Read the information about the image
    dataPos = *(int*)&(header[0x0A]);
    imageSize = *(int*)&(header[0x22]);
    width = *(int*)&(header[0x12]);
    height = *(int*)&(header[0x16]);

    if (imageSize == 0)    imageSize = width*height * 3;
    if (dataPos == 0)      dataPos = 54;

    data = new unsigned char[imageSize];

    // Read the actual data from the file into the buffer
    fread(data, 1, imageSize, file);

    fclose(file);

    GLuint textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);

    // Give the image to OpenGL
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);

    delete[] data;

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glGenerateMipmap(GL_TEXTURE_2D);

    return textureID;
}

int main(void)
{
    // Initialise GLFW
    if (!glfwInit())
    {
        fprintf(stderr, "Failed to initialize GLFW\n");
        return -1;
    }

    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    window = glfwCreateWindow(1024, 768, "Tutorial 05 - Textured Cube", NULL, NULL);
    if (window == NULL) {
        fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n");
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // Initialize GLEW
    glewExperimental = true;
    if (glewInit() != GLEW_OK) {
        fprintf(stderr, "Failed to initialize GLEW\n");
        return -1;
    }

    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    GLuint programID = LoadShader("shader.vert", "shader.frag");

    GLuint MatrixID = glGetUniformLocation(programID, "MVP");

    glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);

    glm::mat4 View = glm::lookAt(
        glm::vec3(4, 3, 3),
        glm::vec3(0, 0, 0),
        glm::vec3(0, 1, 0)
    );

    glm::mat4 Model = glm::mat4(1.0f);
    glm::mat4 MVP = Projection * View * Model;

    GLuint Texture = loadBMP("uvtemplate.bmp");

    // Get a handle for "textureSampler" uniform
    GLuint TextureID = glGetUniformLocation(programID, "textureSampler");

    static const GLfloat g_vertex_buffer_data[] = {
        -1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f, 1.0f,
        -1.0f, 1.0f, 1.0f,
        1.0f, 1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f,-1.0f,
        1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f,-1.0f,
        1.0f,-1.0f,-1.0f,
        1.0f, 1.0f,-1.0f,
        1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f,-1.0f,
        1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
        -1.0f,-1.0f, 1.0f,
        1.0f,-1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f,-1.0f,-1.0f,
        1.0f, 1.0f,-1.0f,
        1.0f,-1.0f,-1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f,-1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, 1.0f,-1.0f,
        -1.0f, 1.0f,-1.0f,
        1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f, 1.0f,
        1.0f,-1.0f, 1.0f
    };

    static const GLfloat g_uv_buffer_data[] = {
        0.000059f, 1.0f - 0.000004f,
        0.000103f, 1.0f - 0.336048f,
        0.335973f, 1.0f - 0.335903f,
        1.000023f, 1.0f - 0.000013f,
        0.667979f, 1.0f - 0.335851f,
        0.999958f, 1.0f - 0.336064f,
        0.667979f, 1.0f - 0.335851f,
        0.336024f, 1.0f - 0.671877f,
        0.667969f, 1.0f - 0.671889f,
        1.000023f, 1.0f - 0.000013f,
        0.668104f, 1.0f - 0.000013f,
        0.667979f, 1.0f - 0.335851f,
        0.000059f, 1.0f - 0.000004f,
        0.335973f, 1.0f - 0.335903f,
        0.336098f, 1.0f - 0.000071f,
        0.667979f, 1.0f - 0.335851f,
        0.335973f, 1.0f - 0.335903f,
        0.336024f, 1.0f - 0.671877f,
        1.000004f, 1.0f - 0.671847f,
        0.999958f, 1.0f - 0.336064f,
        0.667979f, 1.0f - 0.335851f,
        0.668104f, 1.0f - 0.000013f,
        0.335973f, 1.0f - 0.335903f,
        0.667979f, 1.0f - 0.335851f,
        0.335973f, 1.0f - 0.335903f,
        0.668104f, 1.0f - 0.000013f,
        0.336098f, 1.0f - 0.000071f,
        0.000103f, 1.0f - 0.336048f,
        0.000004f, 1.0f - 0.671870f,
        0.336024f, 1.0f - 0.671877f,
        0.000103f, 1.0f - 0.336048f,
        0.336024f, 1.0f - 0.671877f,
        0.335973f, 1.0f - 0.335903f,
        0.667969f, 1.0f - 0.671889f,
        1.000004f, 1.0f - 0.671847f,
        0.667979f, 1.0f - 0.335851f
    };

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

    GLuint uvbuffer;
    glGenBuffers(1, &uvbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_uv_buffer_data), g_uv_buffer_data, GL_STATIC_DRAW);

    do {

        // Clear the screen
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(programID);

        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, Texture);
        glUniform1i(TextureID, 0);

        // 1rst attribute buffer : vertices
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glVertexAttribPointer(
            0, 
            3,
            GL_FLOAT,
            GL_FALSE,
            0,
            (void*)0
        );

        // 2nd attribute buffer : UVs
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
        glVertexAttribPointer(
            1,
            2,
            GL_FLOAT,
            GL_FALSE,
            0,
            (void*)0
        );

        glDrawArrays(GL_TRIANGLES, 0, 12 * 3);

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);

        // Swap buffers
        glfwSwapBuffers(window);
        glfwPollEvents();

    } // Check if the ESC key was pressed or the window was closed
    while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
        glfwWindowShouldClose(window) == 0);

    // Cleanup VBO and shader
    glDeleteBuffers(1, &vertexbuffer);
    glDeleteBuffers(1, &uvbuffer);
    glDeleteProgram(programID);
    glDeleteTextures(1, &TextureID);
    glDeleteVertexArrays(1, &VertexArrayID);

    // Close OpenGL window and terminate GLFW
    glfwTerminate();

    return 0;
}

0 个答案:

没有答案