opengl 绘制三角形(一)

1 win 操作系统:需要Visual studio,glfw, glad;详细安装和配置请自行百度


 

知识:(来源于奇境)

1 MVP变换

模型变换:平移,旋转,缩放

观察变换:计算机在摄像机视角下的位置

投影变换:将摄像机坐标系下的物体,投影到渲染平面

2 shader:着色器语言,是一种运行在GPU上的语言;

3渲染管线:顶点->顶点着色器->片元着色器->显示;一条链路

4 双缓存:主要是为了解决当你电子枪逐行画图很慢的时候,屏幕能看到逐行画图的现象,画面就会出现上半边是后一帧,下半边还是前一帧的;

5基础函数:

  GlclearColor:用什么颜色清除当前画布,glClear:擦除画布上的内容

  Glviewport设置视窗大小;然后就开始画东西了;画完swapbuffer交换前后缓冲,进行显示

 

6 shader 是如何从CPU读数据的

(1)      数据传入GPU buffer

(2)      告诉GPU数据是啥意思,怎么解析这些数据

(3)      让GPU开始画画

 

7 VAO,VBO

Vertex Buffer Object,在GPU上开辟空间,装入顶点数据

(1)      获取VBO的index

(2)      绑定VBO的index

(3)      给VBO分配显存空间,传输数据

(4)      告诉shader数据解析方式

(5)      激活锚点,激活一个个布局

做完VBO之后;初始化着色器,创建着色器,编译链接成着色器程序;

创建VAO;VOB就可以包含在VAO内使用;

然后就是使用VAO,着色器program,进行画图;

8 如果你使用VBO直接渲染,同一个锚点只能指定到最后一次设置的VBO缓冲对象;但是如果你使用不同的VAO分别包住各自的VBO,那同一个锚点可以分别绘制多个不同VBO的图形

cpp : 定义应用程序的入口点。
//

#include "stdafx.h"

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include<string>
#include<fstream>
#include<sstream>
#include<iostream>

#include <stdio.h>

// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
unsigned int VBO = 0;
unsigned int VAO = 0;
int shaderProgram = 0;
//画图
void render()
{
    glBindVertexArray(VAO);
    glUseProgram(shaderProgram);
    glDrawArrays(GL_TRIANGLES,0,3);
    glUseProgram(0);
}

void initmodule()
{
    //做个一模型
    float vertexs[] = {

        0.0f,0.0f,0.0f,
        0.5f,0.0f,0.0f,
        0.0f,0.5f,0.0f,
    };
    
    //做VAO
    glGenVertexArrays(1,&VAO);
    glBindVertexArray(VAO);

    //做VBO

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    //创建显存空间
    glBufferData(GL_ARRAY_BUFFER,sizeof(vertexs), vertexs, GL_STATIC_DRAW);
    //设置第0个锚点,3个点,不需要归一化,跨度3个float可以读下一个点
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);
    //打开顶点
    glEnableVertexAttribArray(0);
    //解除绑定VBO
    glBindBuffer(GL_ARRAY_BUFFER,0);

    //解绑VAO
    glBindVertexArray(0);

}

void initshader(const char* verpath,const char* fragpath)
{
    //编译shader,并记录shaderID
    std::string VerCode("");
    std::string fregCode("");
    //读文件
    std::ifstream  vShaderFile;
    std::ifstream  fShaderFile;

    vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    
    try
    {
        vShaderFile.open(verpath);
        fShaderFile.open(fragpath);

        std::stringstream vsstream, fsstream;
        vsstream << vShaderFile.rdbuf();
        fsstream << fShaderFile.rdbuf();
        VerCode = vsstream.str();
        fregCode = fsstream.str();
        
    }
    catch (const std::exception&)
    {
        std::cout << "read file error" << std::endl;
    }

    const char* vshader = VerCode.c_str();
    const char* fshader = fregCode.c_str();

    //shader 编译连接
    unsigned int vertexID = 0, fragID = 0;
    char infoLog[512];//存储错误信息
    int  successflag = 0;
    vertexID = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexID,1,&vshader,NULL );
    glCompileShader(vertexID);
    //获取编译是否成功
    glGetShaderiv(vertexID,GL_COMPILE_STATUS,&successflag);
    if (!successflag)
    {
        glGetShaderInfoLog(vertexID,512,NULL,infoLog);
        std::string errstr(infoLog);
        std::cout << "v shader err"<<infoLog;
    }
    //frag
    fragID = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragID, 1, &fshader, NULL);
    glCompileShader(fragID);
    //获取编译是否成功
    glGetShaderiv(fragID, GL_COMPILE_STATUS, &successflag);
    if (!successflag)
    {
        glGetShaderInfoLog(fragID, 512, NULL, infoLog);
        std::string errstr(infoLog);
        std::cout << "f shader err"<<infoLog;
    }
    //链接
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram,vertexID);
    glAttachShader(shaderProgram,fragID);
    glLinkProgram(shaderProgram);
    glGetProgramiv(shaderProgram,GL_LINK_STATUS,&successflag);
    if (!successflag)
    {
        glGetShaderInfoLog(shaderProgram, 512, NULL, infoLog);
        std::string errstr(infoLog);
        std::cout << "link error";
    }

    //编译完成后,可以把中间的步骤程序删除
    glDeleteShader(vertexID);
    glDeleteShader(fragID);
}
void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    {
        //将窗口设置为关闭,跳出循环
        glfwSetWindowShouldClose(window, true);
    }
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

int main()
{
    //glfw初始化
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    //glfw创建窗口
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        printf("创建窗口失败");
        //终止
        glfwTerminate();
        return -1;
    }
    //设置窗口上下文
    glfwMakeContextCurrent(window);

    //设置回调,当窗口大小调整后将调用该回调函数
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // glad初始化
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        printf("加载失败");
        return -1;
    }
    initmodule();
    initshader("vertexShader.glsl","fragmentShader.glsl");

    // 使用循环达到循环渲染效果
    while (!glfwWindowShouldClose(window))
    {
        //自定义输入事件
        processInput(window);

        glClearColor(0.5f,0.5f,0.3f,1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
//画三角形 render();
//交互缓冲区;双缓冲 glfwSwapBuffers(window); //输入输出事件,否则无法对窗口进行交互 glfwPollEvents(); } //终止渲染 关闭并清理glfw本地资源 glfwTerminate(); return 0; }

 //顶点着色器和片元着色器的 GLSL 语言;

#version 330 core
layout(location = 0) in vec3 aPos;
void main()
{
   gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0);
};

#version 330 core
out vec4 FragColor;
void main()
{
    FragColor = vec4(0.5f,0.9f,0.5f,1.0f);
};

 

posted on 2022-04-23 21:55  邗影  阅读(212)  评论(0编辑  收藏  举报

导航