openGl2

图元装配(Primitive Assembly)

Primitive
也就是对顶点坐标,进行装配,形成形状

裁剪

原文:片段着色器运行之前会执行裁切(Clipping)。裁切会丢弃超出你的视图以外的所有像素,用来提升执行效率
裁剪默认在片段着色前

最后一个阶段

在着色后,是Alpha测试和混合。会进行深度测试、会检测透明度进行混合

必须定义的着色器

现代openGl有必须定义的着色器,因为GPU没有默认的。他们是:顶点shader、片段shader

顶点缓冲对象(Vertex Buffer Objects, VBO)

用于一次性CPU给GPU发送顶点,多次发送慢,所以缓存后一次发送
生成buffer->设置当前绑定buffer->设置buffer内容
genBuffer->bind->bufferData

glBufferData函数里有一个选项,可以选择buffer的性能。分为几乎不会变的、常变的、每帧变的
好的,至此,显存里有数据了

继续根据https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/

有点不同的是,我分解成了class,为后续更方便添加代码

运行后出现了一个问题,窗口上画了一个橙色的方块,有时也不会画出方块而是完全黑屏,而且方块的位置不固定,有时在右上角,有时在左下角



分析一下:首先,没有报错,说明shader编译之类的都是对的,也就是整个流程是跑通的。那么大概率是数据的问题。读入数据的时候有一个地方我和教程不一样,我用了vector。将vector改为float v2[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};后,正常了
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);//异常
glBufferData(GL_ARRAY_BUFFER, sizeof(v2), v2, GL_STATIC_DRAW);//正常
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW);//三角形高度减半,也就是一个点变成了0,0,0
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*vertices.size(), &vertices[0], GL_STATIC_DRAW);//正常
由此,有2件之前没注意的事,vector是一个obj,里面封装了一些指针,sizeof(vec)=32,有的资料说里面只有3个指针,不过是32的话,显然是4个,可能因为我在debug模式下MSVC会加一个debugSize,不过这不重要,重要的是传读取长度得用size算。其次是传入的指针,bufferData需要传入的是连续地址0位的指针,传&vec的话,是obj的指针

异常分析:用renderDoc


因为传成了地址。所以点取成了一些 接近0 or 接近无穷的点,当恰好能形成三角形的时候,渲染就会这样。虽然看到的是四边形,但实际上是三角形,只是因为y太大或太小,导致视角内看起来是四边形。

EBO (IBO)

教程里本章用的术语是EBO,个人认为从特性层面看,IBO更符合。简单来说,重复的点不重复传入,加传点的索引,从而获得更高的效率
EBO在active vao 中的时候,不能解绑,会运行错误

练习

玩玩

2个点相同,然后注意第三个点不要在第一个三角形内就行
以为之前封装好了操作,所以第二个只要复制一下就行
int main()
{
auto myWindow = MyWindow();
if (myWindow.IsSuccess() == false) {
return -1;
}

auto v = VertexShader();
auto f = FragmentShader();
auto shaderProgram = Tool::LinkShader(v, f);
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);

auto vbo = VBObject(triangleVertices);
auto ebo = EBObject(indces);


glBindBuffer(GL_ARRAY_BUFFER, 0);//解绑
glBindVertexArray(0);//解绑

unsigned int VAO2;
glGenVertexArrays(1, &VAO2);
glBindVertexArray(VAO2);

auto vbo2 = VBObject(triangleVertices2);
auto ebo2 = EBObject(indces);


glBindBuffer(GL_ARRAY_BUFFER, 0);//解绑
glBindVertexArray(0);//解绑

std::vector<unsigned int>vaos={VAO, VAO2};
Tool::BindAutoAdaptSize(myWindow.GetWindow());
Tool::RenderLoop(myWindow.GetWindow(), shaderProgram, vaos);

return 0;

}
不同色也差不多

#include<glad/glad.h>
#include"Tool.h"
#include"VBObject.h"
#include"MyWindow.h"
#include"EBObject.h"
#include <vector>


std::vector<float> triangleVertices = {
    0.0f, 0.0f, 0.0f,   // 右上角
    0.0f, -0.5f, 0.0f,  // 右下角
    -0.5f, -0.5f, 0.0f, // 左下角

    0.5f, 0.5f, 0.0f,   // 左上角
     0.5f, 0.0f, 0.0f ,  // 左上角
    
};

std::vector<int> indces = {
    0, 1, 2, // 第一个三角形
    
};
std::vector<int> indces2 = {
    0, 4, 3  // 第二个三角形

};



int main()
{
    auto myWindow = MyWindow();
    if (myWindow.IsSuccess() == false) {
        return -1;
    }

    auto v = VertexShader();
    auto f = FragmentShader("#version 330 core\n"
        "out vec4 FragColor;\n"
        "void main()\n"
        "{\n"
        "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
        "}\0");
    auto f2 = FragmentShader("#version 330 core\n"
        "out vec4 FragColor;\n"
        "void main()\n"
        "{\n"
        "   FragColor = vec4(0.2f, 0.5f, 0.2f, 1.0f);\n"
        "}\0");
    auto shaderProgram = Tool::LinkShader(v, f);
    auto shaderProgram2 = Tool::LinkShader(v, f2);
    unsigned int VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    auto vbo = VBObject(triangleVertices);
    auto ebo = EBObject(indces);

    
    glBindBuffer(GL_ARRAY_BUFFER, 0);//解绑
    glBindVertexArray(0);//解绑

    unsigned int VAO2;
    glGenVertexArrays(1, &VAO2);
    glBindVertexArray(VAO2);

    auto vbo2 = VBObject(triangleVertices);
    auto ebo2 = EBObject(indces2);


    glBindBuffer(GL_ARRAY_BUFFER, 0);//解绑
    glBindVertexArray(0);//解绑

    std::vector<unsigned int>vaos = { VAO, VAO2 };
    std::vector<unsigned int>shaderPrograms ={ shaderProgram,shaderProgram2};
    Tool::BindAutoAdaptSize(myWindow.GetWindow());
    Tool::RenderLoop(myWindow.GetWindow(), shaderPrograms, vaos);
    
    return 0;
} 
posted @ 2025-03-21 18:30  vil4  阅读(17)  评论(0)    收藏  举报