FFmpeg4.3系列之52:Android OpenGL实现3D画图及抛骰子案例实战

128 阅读3分钟

FFmpeg4.3系列之52:Android OpenGL实现3D画图及抛骰子案例实战

FFmpeg4.3系列之52:Android OpenGL实现3D画图及抛骰子案例实战

获取ZY↑↑方打开链接↑↑

OpenGL着色器绘制三角形的代码细节

在OpenGL中使用着色器绘制三角形涉及顶点着色器和片段着色器的编写,以及相关的OpenGL API调用。以下是一个简单的示例,展示了如何使用GLSL(OpenGL Shading Language)编写着色器并绘制一个三角形。

1. 顶点着色器 (vertex shader)

顶点着色器负责处理顶点数据,通常用于顶点变换和光照计算。以下是一个简单的顶点着色器示例,它仅将顶点位置传递给片段着色器:

Glsl

#version 330 corelayout (location = 0) in vec3 aPos; // 顶点位置属性void main(){    gl_Position = vec4(aPos, 1.0); // 将顶点位置传递给片段着色器}

2. 片段着色器 (fragment shader)

片段着色器负责处理每个片段(像素)的颜色。以下是一个简单的片段着色器示例,它将所有片段设置为红色:

Glsl

#version 330 coreout vec4 FragColor;void main(){    FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 设置片段颜色为红色}

3. OpenGL代码 (C++)

接下来是C++中的OpenGL代码,用于设置OpenGL环境、编译着色器、创建VAO/VBO并绘制三角形。

Cpp

#include <GL/glew.h>#include <GLFW/glfw3.h>#include <iostream>// 顶点着色器源码const char* vertexShaderSource = R"(#version 330 corelayout (location = 0) in vec3 aPos;void main(){    gl_Position = vec4(aPos, 1.0);})";// 片段着色器源码const char* fragmentShaderSource = R"(#version 330 coreout vec4 FragColor;void main(){    FragColor = vec4(1.0, 0.0, 0.0, 1.0);})";// 编译着色器unsigned int compileShader(unsigned int type, const char* source) {    unsigned int shader = glCreateShader(type);    glShaderSource(shader, 1, &source, nullptr);    glCompileShader(shader);    int success;    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);    if (!success) {        char infoLog[512];        glGetShaderInfoLog(shader, 512, nullptr, infoLog);        std::cerr << "ERROR::SHADER::COMPILATION_FAILED\n" << infoLog << std::endl;    }    return shader;}// 创建着色器程序unsigned int createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource) {    unsigned int vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);    unsigned int fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);    unsigned int shaderProgram = glCreateProgram();    glAttachShader(shaderProgram, vertexShader);    glAttachShader(shaderProgram, fragmentShader);    glLinkProgram(shaderProgram);    int success;    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);    if (!success) {        char infoLog[512];        glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);        std::cerr << "ERROR::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;    }    glDeleteShader(vertexShader);    glDeleteShader(fragmentShader);    return shaderProgram;}int main() {    // 初始化GLFW    if (!glfwInit()) {        std::cerr << "Failed to initialize GLFW" << std::endl;        return -1;    }    // 创建窗口    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Window", nullptr, nullptr);    if (!window) {        std::cerr << "Failed to create GLFW window" << std::endl;        glfwTerminate();        return -1;    }    glfwMakeContextCurrent(window);    // 初始化GLEW    glewExperimental = GL_TRUE;    if (glewInit() != GLEW_OK) {        std::cerr << "Failed to initialize GLEW" << std::endl;        return -1;    }    // 构建和编译我们的着色器程序    unsigned int shaderProgram = createShaderProgram(vertexShaderSource, fragmentShaderSource);    // 设置顶点数据,并配置顶点属性    float vertices[] = {        -0.5f, -0.5f, 0.0f,         0.5f, -0.5f, 0.0f,         0.0f,  0.5f, 0.0f    };    unsigned int VBO, VAO;    glGenVertexArrays(1, &VAO);    glGenBuffers(1, &VBO);    glBindVertexArray(VAO);    glBindBuffer(GL_ARRAY_BUFFER, VBO);    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);    glEnableVertexAttribArray(0);    // 渲染循环    while (!glfwWindowShouldClose(window)) {        // 输入        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)            glfwSetWindowShouldClose(window, true);        // 渲染指令        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);        glClear(GL_COLOR_BUFFER_BIT);        // 绘制我们的第一个三角形        glUseProgram(shaderProgram);        glBindVertexArray(VAO);        glDrawArrays(GL_TRIANGLES, 0, 3);        // 交换缓冲区        glfwSwapBuffers(window);        glfwPollEvents();    }    // 清理资源    glDeleteVertexArrays(1, &VAO);    glDeleteBuffers(1, &VBO);    glfwTerminate();    return 0;}

代码说明

  1. 顶点着色器和片段着色器:使用GLSL语言编写,定义了顶点位置和片段颜色的计算方式。
  2. 编译着色器compileShader函数用于编译顶点着色器和片段着色器。
  3. 创建着色器程序createShaderProgram函数将编译后的顶点着色器和片段着色器链接成一个着色器程序。
  4. 初始化GLFW和GLEW:设置OpenGL上下文。
  5. 设置顶点数据:定义三角形的顶点位置,并使用VBO和VAO进行顶点数据的存储和配置。
  6. 渲染循环:在渲染循环中,清空颜色缓冲区,使用着色器程序绘制三角形,并交换前后缓冲区以显示内容。

确保你已经安装了GLFW和GLEW库,并且正确配置了开发环境以编译和运行此代码。