zoukankan      html  css  js  c++  java
  • -OPENGL 2-

    Read OIIO->Qt QImage

    import sys,os
    import OpenImageIO as oiio
    from PySide2 import QtWidgets,QtCore,QtGui
    import numpy as np
    
    
    
    if __name__ == "__main__":
        img_input = oiio.ImageInput.open('timg.jpg')
        img_spec = img_input.spec()
        nchans = img_spec.nchannels # JPG is 3 / PNG is 4
        width = img_spec.width
        height = img_spec.height
        print("img %s,height:%s"%(width,height))
        #pixels = []
        pixels = img_input.read_image(oiio.UINT8)
        pixels = pixels.flatten()
        print(len(pixels) ) 
        print(width*height*nchans)
    
    
        app = QtWidgets.QApplication(sys.argv)
        qtimg = QtGui.QImage(pixels,width,height,QtGui.QImage.Format_RGB888)  # CREATGE QT IMAGE
        #qtimg.save('test.jpg')
    
    
    
        print('Create Pixmap')
        qtimg = QtGui.QPixmap.fromImage(qtimg)
        label = QtWidgets.QLabel()
        label.resize(500,500)
        label.setPixmap(qtimg)
        label.show()
    
        app.exec_()
    View Code

    GL测试全部由CMakeLists负责构建:

    cmake_minimum_required(VERSION 3.5)
    
    project(Triangle)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    # OPENGL
    find_package(OpenGL REQUIRED)
    include_directories(${OpenGL_INCLUDE_DIRS})
    link_directories(${OpenGL_LIBRARY_DIRS})
    add_definitions(${OpenGL_DEFINITIONS})
    
    if(NOT OPENGL_FOUND)
        message(ERROR " OPENGL not found!")
    endif(NOT OPENGL_FOUND)
    
    # GLEW
    set(GLEW_HOME D:/plugin_dev/libs/glew-2.1.0)
    include_directories(${GLEW_HOME}/include)
    link_directories(${GLEW_HOME}/lib/Release/x64)
    
    # GLFW
    set(GLFW_HOME D:/plugin_dev/libs/glfw-3.3.1.bin.WIN64)
    include_directories(${GLFW_HOME}/include/)
    link_directories(${GLFW_HOME}/lib-vc2019)
    
    # output excutable dir
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
    
    
    add_executable(Triangle main.cpp LoadShader.h)
    target_link_libraries(Triangle glew32s glfw3 opengl32)
    View Code

    CP01:

    MODERN OGL Triangle

    #define GLEW_STATIC
    // GLEW
    
    #include <GL/glew.h>
    #include <cstdlib>
    #undef GLFW_DLL
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    
    using namespace std;
    
    const int NPTS = 3;
    GLuint VBO,VAO;
    
    // Shaders
    const GLchar* vertexShaderSource = "#version 450 core
    "
    "layout (location = 0) in vec4 vPosition;
    "
    "void main()
    "
    "{
    "
    "gl_Position = vPosition;
    "
    "}";
    const GLchar* fragmentShaderSource = "#version 450 core
    "
    "out vec4 fColor;
    "
    "void main()
    "
    "{
    "
    "fColor = vec4(0.6,0,0.3,1);
    "
    "}
    ";
    
    
    
    
    
    
    void init(){
        static const GLfloat verticles[NPTS][3] = {
            {-0.5f, -0.5f, 0.0f},
            {0.5f, -0.5f, 0.0f},
            {0.0f,  0.5f, 0.0f}
        };
    
        // Vertex shader
        GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
        glShaderSource( vertexShader, 1, &vertexShaderSource, NULL );
        glCompileShader( vertexShader );
        GLint success;
        GLchar infoLog[512];
    
        glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &success );
        if ( !success )
        {
            glGetShaderInfoLog( vertexShader, 512, NULL, infoLog );
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
        }
    
    
         // Fragment shader
        GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
        glShaderSource( fragmentShader, 1, &fragmentShaderSource, NULL );
        glCompileShader( fragmentShader );
        glGetShaderiv( fragmentShader, GL_COMPILE_STATUS, &success );
        if ( !success )
        {
            glGetShaderInfoLog( fragmentShader, 512, NULL, infoLog );
            std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
    " << infoLog << std::endl;
        }
    
        // Link shaders
        GLuint shaderProgram = glCreateProgram( );
        glAttachShader( shaderProgram, vertexShader );
        glAttachShader( shaderProgram, fragmentShader );
        glLinkProgram( shaderProgram );
    
    
        // Check for linking errors
        glGetProgramiv( shaderProgram, GL_LINK_STATUS, &success );
        if ( !success )
        {
           glGetProgramInfoLog( shaderProgram, 512, NULL, infoLog );
           std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED
    " << infoLog << std::endl;
        }
    
        glUseProgram(shaderProgram);
        glDeleteShader( vertexShader );
        glDeleteShader( fragmentShader );
    
        glCreateBuffers(1,&VBO);
        glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 );
        glBindBuffer(GL_ARRAY_BUFFER,VBO);
    
        glCreateVertexArrays(1,&VAO);
        glBindVertexArray(VAO);
        glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,0, 0 );
        glEnableVertexAttribArray(0);
    
        cout << "VAO:" << VAO << endl;
        cout << "VBO:" << VBO << endl;
    
    }
    
    void display(){
    
        static const float black[] = {0.0f,0.0f,0.0f,0.0f};
        glClearBufferfv(GL_COLOR,0,black);
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES,0 ,NPTS);
    }
    
    int main()
    {
        glfwInit();
        GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL);
        glfwMakeContextCurrent(window);
        glewInit();
    
        init();
    
    
        while(!glfwWindowShouldClose(window)){
            display();
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        glfwDestroyWindow(window);
        glfwTerminate();
    
        return 0;
    }
    View Code

    CP02:

    >>使用P位置着色

    Attrib不变,点位置也不变

    // position Attrib
    glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,0, 0 );
    glEnableVertexAttribArray(0);

    .vert .frag的source变化:

    // Shaders
    const GLchar* vertexShaderSource = "#version 450 core
    "
    "layout (location = 0) in vec4 vPosition;
    "
    "layout (location = 0) in vec4 vColor;
    "
    "out vec4 ourColor;
    "
    "void main()
    "
    "{
    "
    "gl_Position = vPosition;
    "
    "ourColor = vColor;
    "
    "}";
    
    
    const GLchar* fragmentShaderSource = "#version 450 core
    "
    "in vec4 ourColor;
    "
    "out vec4 fColor;
    "
    "void main()
    "
    "{
    "
    "fColor = ourColor;
    "
    "}
    ";

    CP03:

    >>属性创建1:

    创建Position属性:

    // position Attrib
    glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,0, 0 );
    glEnableVertexAttribArray(0);

    函数原型是这个:

    glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr)

    第一个参数:着色器需要这个变量的location值

    第二个参数:每个顶点的元素数目,如果是上面的,则是3

    第三个参数:数据类型,GL_FLOAT

    第四个参数:是不是要normalize,这里是position类型的数据,则是GL_FALSE

    第五个参数:stride,等于0,则是数据“紧密链接”

    第六个参数:偏移bytes,这里数据不许用指定offset。 所以写(void*)0

    ---------------------------------------------------------------------------------------------------------------------

    >>属性创建2:

    创建2个location,一个是为了gl_Position,一个为了自定义颜色

    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // color attribute
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float)));
    glEnableVertexAttribArray(1);
    #define GLEW_STATIC
    // GLEW
    
    #include <GL/glew.h>
    #include <cstdlib>
    #undef GLFW_DLL
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    
    using namespace std;
    
    const int NPTS = 3;
    GLuint VBO,VAO;
    
    // Shaders
    const GLchar* vertexShaderSource = "#version 450 core
    "
    "layout (location = 0) in vec4 vPosition;
    "
    "layout (location = 1) in vec4 vColor;
    "
    "out vec4 ourColor;
    "
    "void main()
    "
    "{
    "
    "gl_Position = vPosition;
    "
    "ourColor = vColor;
    "
    "}";
    
    
    const GLchar* fragmentShaderSource = "#version 450 core
    "
    "in vec4 ourColor;
    "
    "out vec4 fColor;
    "
    "void main()
    "
    "{
    "
    "fColor = ourColor;
    "
    "}
    ";
    
    
    
    
    
    
    void init(){
        static const GLfloat verticles[NPTS][6] = {
            { 0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f },
            { -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f },
            { 0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f }
        };
    
        // Vertex shader
        GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
        glShaderSource( vertexShader, 1, &vertexShaderSource, NULL );
        glCompileShader( vertexShader );
        GLint success;
        GLchar infoLog[512];
    
        glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &success );
        if ( !success )
        {
            glGetShaderInfoLog( vertexShader, 512, NULL, infoLog );
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
        }
    
    
         // Fragment shader
        GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
        glShaderSource( fragmentShader, 1, &fragmentShaderSource, NULL );
        glCompileShader( fragmentShader );
        glGetShaderiv( fragmentShader, GL_COMPILE_STATUS, &success );
        if ( !success )
        {
            glGetShaderInfoLog( fragmentShader, 512, NULL, infoLog );
            std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
    " << infoLog << std::endl;
        }
    
        // Link shaders
        GLuint shaderProgram = glCreateProgram( );
        glAttachShader( shaderProgram, vertexShader );
        glAttachShader( shaderProgram, fragmentShader );
        glLinkProgram( shaderProgram );
    
    
        // Check for linking errors
        glGetProgramiv( shaderProgram, GL_LINK_STATUS, &success );
        if ( !success )
        {
           glGetProgramInfoLog( shaderProgram, 512, NULL, infoLog );
           std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED
    " << infoLog << std::endl;
        }
    
        // Use shader program
        glUseProgram(shaderProgram);
        glDeleteShader( vertexShader );
        glDeleteShader( fragmentShader );
    
        glCreateBuffers(1,&VBO);
        glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 );
        glBindBuffer(GL_ARRAY_BUFFER,VBO);
    
        glCreateVertexArrays(1,&VAO);
        glBindVertexArray(VAO);
    
        // position Attrib
        glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)0 );
        glEnableVertexAttribArray(0);
    
        // color Attrib
        glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)(3* sizeof(float)) );
        glEnableVertexAttribArray(1);
    
    
        cout << "VAO:" << VAO << endl;
        cout << "VBO:" << VBO << endl;
    
    }
    
    void display(){
    
        static const float black[] = {0.0f,0.0f,0.0f,0.0f};
        glClearBufferfv(GL_COLOR,0,black);
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES,0 ,NPTS);
    }
    
    int main()
    {
        glfwInit();
        GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL);
        glfwMakeContextCurrent(window);
        glewInit();
    
        init();
    
    
        while(!glfwWindowShouldClose(window)){
            display();
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        glfwDestroyWindow(window);
        glfwTerminate();
    
        return 0;
    }
    Full Src

    CP04:

    将读取材质加载到另外一个头文件中。

    将材质vert和frag分离

    #version 450 core
    layout ( location = 0 ) in vec4 vPosition;
    layout ( location = 1 ) in vec4 vColor;
    
    out vec4 ourColor;
    void main(){
        gl_Position = vPosition;
        ourColor = vColor;
    }
    shader.vert
    #version 450 core
    out vec4 fColor;
    in vec4 ourColor;
    void main(){
        fColor = ourColor;
    }
    shader.frag
    #ifndef LOADSHADER_H
    #define LOADSHADER_H
    
    
    #include <GL/glew.h>
    
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <sstream>
    
    using namespace std;
    struct LoadShader
    {
        LoadShader(const char*vertPath, const char* fragPath){
            load(vertPath,fragPath);
        }
    
        string _readFile(const char *path){
            ifstream stream;
            stringstream ss;
            stream.exceptions(ifstream::badbit);
            try
            {
                stream.open(path);    // open file
                ss << stream.rdbuf(); // get strings from file
            } catch (ifstream::failure e)
            {
                cout << "ERROR::OPEN FILE:" << path << endl;
            }
            // close file handle
            stream.close();
    
            // get str() from stringstream
            string shaderCode = ss.str();
            return shaderCode;
        }
    
        void _loadVertexShader(const char *path){
    
            // read shader code
            auto handle = _readFile(path);
            const char * shaderCode = handle.c_str();
            // Vertex shader
            vertexShader = glCreateShader( GL_VERTEX_SHADER );
            glShaderSource( vertexShader, 1, &shaderCode, NULL );
            glCompileShader( vertexShader );
            GLint success;
            GLchar infoLog[512];
    
            glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &success );
            if ( !success )
            {
                glGetShaderInfoLog( vertexShader, 512, NULL, infoLog );
                std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
            }
    
        }
    
        void _loadFragmentShader(const char *path){
            // read shader code
            auto handle = _readFile(path);
            const char * shaderCode = handle.c_str();
            // Vertex shader
            fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
            glShaderSource( fragmentShader, 1, &shaderCode, NULL );
            glCompileShader( fragmentShader );
            GLint success;
            GLchar infoLog[512];
    
            glGetShaderiv( fragmentShader, GL_COMPILE_STATUS, &success ); // Get Compile status
            if ( !success )
            {
                glGetShaderInfoLog( fragmentShader, 512, NULL, infoLog );
                std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
    " << infoLog << std::endl;
            }
        }
    
        void load(const char* vertShaderPath, const char* fragShaderPath){
            _loadVertexShader(vertShaderPath);
            _loadFragmentShader(fragShaderPath);
    
    
            // create shader program and check it
            GLint success;
            GLchar infoLog[512];
            shaderProgram = glCreateProgram();
            glAttachShader(shaderProgram,vertexShader);
            glAttachShader(shaderProgram,fragmentShader);
            glLinkProgram(shaderProgram );
            glGetProgramiv( shaderProgram, GL_LINK_STATUS, &success );  // Get Link Status
            if (!success)
            {
               glGetProgramInfoLog( shaderProgram, 512, NULL, infoLog );
               std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED
    " << infoLog << std::endl;
            }
            // Delete the shaders as they're linked into our program now and no longer necessery
            glDeleteShader( vertexShader );
            glDeleteShader( fragmentShader );
        }
    
        void use(){
            glUseProgram(shaderProgram);
        }
    
        GLuint shaderProgram;
        GLuint vertexShader;
        GLuint fragmentShader;
    };
    
    
    
    
    
    #endif // LOADSHADER_H
    LoadShader.h
    #define GLEW_STATIC
    // GLEW
    
    #include <GL/glew.h>
    #include <cstdlib>
    #undef GLFW_DLL
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include "LoadShader.h"
    using namespace std;
    
    const int NPTS = 3;
    static GLuint VBO,VAO;
    
    
    
    void init(){
        static const GLfloat verticles[NPTS][6] = {
            { 0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f },
            { -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f },
            { 0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f }
        };
    
        LoadShader shader("shader.vert","shader.frag");
        shader.use();
        glCreateBuffers(1,&VBO);
        glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 );
        glBindBuffer(GL_ARRAY_BUFFER,VBO);
    
        glCreateVertexArrays(1,&VAO);
        glBindVertexArray(VAO);
    
        // position Attrib
        glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)0 );
        glEnableVertexAttribArray(0);
    
        // color Attrib
        glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)(3* sizeof(float)) );
        glEnableVertexAttribArray(1);
    
    
        cout << "VAO:" << VAO << endl;
        cout << "VBO:" << VBO << endl;
    
    }
    
    void display(){
    
        static const float black[] = {0.0f,0.0f,0.0f,0.0f};
        glClearBufferfv(GL_COLOR,0,black);
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES,0 ,NPTS);
    }
    
    int main()
    {
        glfwInit();
        GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL);
        glfwMakeContextCurrent(window);
        glewInit();
    
        init();
    
    
        while(!glfwWindowShouldClose(window)){
            display();
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        glfwDestroyWindow(window);
        glfwTerminate();
    
        return 0;
    }
    main.cpp

    CP05:

    Uniform的作用。当前感觉是可以直接在UI->C++->GLSL

    在C++中设置frag的uniform 变量值

    #version 450 core
    out vec4 fColor;  // out to our fragment shader color
    in vec4 ourColor; // from the vertex shader src
    
    uniform vec4 cpp_color; // from c++ src
    void main(){
        fColor = cpp_color;
    }
    shader.frag

    Now that we know how to set the values of uniform variables, we can use them for rendering. If we want the color to gradually change, we want to update this uniform every frame, otherwise the triangle would maintain a single solid color if we only set it once. So we calculate the greenValue and update the uniform each render iteration:

    接下来就是在每帧刷新:

    void display(){
    
        static const float black[] = {0.0f,0.0f,0.0f,0.0f};
        glClearBufferfv(GL_COLOR,0,black);
    
    
        // get the location of uniform color in shader.frag
        int cpp_color_location = glGetUniformLocation(shader.shaderProgram,"cpp_color");
    
        float timeValue = glfwGetTime();
        float greenValue = sin(timeValue*2) / 2.0f + 0.5f;
    
        // set uniform value
        glUniform4f(cpp_color_location, 0.0f, greenValue, 0.0f, 1.0f);
    
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES,0 ,NPTS);
    }

    如果在shader.vert里这样写,可以看到三角形上下飞。

    #version 450 core
    layout ( location = 0 ) in vec4 vPosition;
    layout ( location = 1 ) in vec4 vColor;
    uniform vec4 cpp_color; // from c++ src
    
    
    out vec4 ourColor;
    void main(){
        gl_Position = vPosition + cpp_color;
        ourColor = vColor;
    }

    CP06:

    uniform 块的使用

    相关过程:

    1,通过glGetUniformBlockIndex()获取uniform块的索引值

    2,获取uniform块的大小glGetActiveUniformBlockiv(),目的是为了C++客户端的要修改的  (GLvoid *buffer)开辟正确的内存。

    3,通过glGetUniformIndices()根据所有的glsl中uniform中的每个变量名称(在C++可能要const char * name[num_uniforms])的索引值

    4,根据这些索引值可以得到uniform块中每个变量所占用的内存大小,类型,内存偏移值

    5,把准备好的数据复制到(GLvoid *buffer)中

    6,建立uniform缓存对象,初始化内容,与着色器关联。通过glCreateBuffers(),glBindBuffer(),glBufferData(),glBindBufferBase()函数完成。

    我按照书中的示例做了个简单的测试,结果发现根本TM的就在现代C++编译器无法跑过去,尼玛的void* + int? 用来偏移内存这么玩的吗?VS2019 表示完全无法通过。

    但是如果前期的编译器要是能编译这个,我觉得void*请牛逼的,可以指向任意各种内存”区域“,带上正确的offset完全可以实现正确的访问。

    先看书中的示例:

     

      

    最后一幅图里的代码根本无法编译,可能C语言编译器能编译?memcpy不带这么玩的。

    针对这个问题,我想了下由于是内存不带offset的,我直接用个透明的结构体不就解决了,果然:

    Fragment:

    #version 450 core
    out vec4 fColor;  // out to our fragment shader color
    in vec4 ourColor; // from the vertex shader src
    
    
    uniform Block{
        vec4 cpp_color;
        float cpp_ypos;
    };
    
    
    void main(){
        fColor = cpp_color;
    }

    Vertex:

    #version 450 core
    layout ( location = 0 ) in vec4 vPosition;
    //layout ( location = 1 ) in vec4 vColor;  // from c++ attribute transfer
    // out vec4 ourColor; No longer used,just for test
    
    
    uniform Block{
        vec4 cpp_color;
        float cpp_ypos;
    };
    
    void main(){
        gl_Position = vPosition + vec4(0.0f,cpp_ypos, 0.0f,0.0f);
    
    }

    main.cpp:

    #define GLEW_STATIC
    // GLEW
    
    #include <GL/glew.h>
    #include <cstdlib>
    #undef GLFW_DLL
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include "LoadShader.h"
    using namespace std;
    
    const int NPTS = 3;
    static GLuint VBO,VAO;
    
    // load shader
    static LoadShader shader;
    
    struct UData{
        float color[4];
        float inc_ypos;
    };
    
    
    void init(){
        static const GLfloat verticles[NPTS][6] = {
            { 0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f },
            { -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f },
            { 0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f }
        };
    
        shader.load("shader.vert","shader.frag");
        shader.use();
        glCreateBuffers(1,&VBO);
        glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 );
        glBindBuffer(GL_ARRAY_BUFFER,VBO);
    
        glCreateVertexArrays(1,&VAO);
        glBindVertexArray(VAO);
    
        // position Attrib
        glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)0 );
        glEnableVertexAttribArray(0);
    
        // color Attrib
        glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,6 * sizeof(float), (void*)(3* sizeof(float)) );
        glEnableVertexAttribArray(1);
    
    
        cout << "VAO:" << VAO << endl;
        cout << "VBO:" << VBO << endl;
    
    }
    
    void display(){
    
        static const float black[] = {0.0f,0.0f,0.0f,0.0f};
        glClearBufferfv(GL_COLOR,0,black);
        glUseProgram(shader.shaderProgram);
        // Get Uniform Block index
        GLuint uniform_block_index;
        uniform_block_index = glGetUniformBlockIndex(shader.shaderProgram, "Block");
        //cout << "shader program:" << shader.shaderProgram <<endl;
    
        //cout <<"Block id x:" <<uniform_block_index <<endl;
        // Get Uniform Block Mem Size
        GLint uniform_block_size;
        glGetActiveUniformBlockiv(shader.shaderProgram, uniform_block_index,
                                  GL_UNIFORM_BLOCK_DATA_SIZE, &uniform_block_size);
    
        //cout << "Block Size:" << uniform_block_size <<endl;
        // We Just have two variable in our "vars" uniform block
        const GLuint var_count = 2;
    
        // static write our per variable name
        const char *var_names[var_count] = {"cpp_color","cpp_ypos"};
    
        // Get uniform per variable index
        GLuint indices[var_count];
        glGetUniformIndices(shader.shaderProgram, var_count, var_names,indices); // Get Block per var index
    
        // Get Uniform per variable data size
        GLint var_sizes[var_count];
        glGetActiveUniformsiv(shader.shaderProgram, var_count, indices, GL_UNIFORM_SIZE, var_sizes);
    
        // Get uniform per variable data offset
        GLint var_offsets[var_count];
        glGetActiveUniformsiv(shader.shaderProgram, var_count, indices, GL_UNIFORM_OFFSET, var_offsets);
    
        // Get uniform per variable data type
        GLint var_types[var_count];
        glGetActiveUniformsiv(shader.shaderProgram, var_count, indices, GL_UNIFORM_TYPE, var_types);
    
    
        // Create buffer object
        GLuint uniform_buffers_index;
        glCreateBuffers(1, &uniform_buffers_index);
        glBindBuffer(GL_UNIFORM_BUFFER, uniform_buffers_index);
    
        // this value for y pos offset
        float timeValue = glfwGetTime();
        float greenValue = sin(timeValue*2) / 2.0f + 0.5f;
    
        UData data;
        data.inc_ypos = greenValue;
        data.color[0] = 0.0f;
        data.color[1] = 0.0f;
        data.color[2] = 1.0f;
        data.color[3] = 1.0f;
        
        //cout << "sizeof data:" << sizeof(data) <<endl;
        glNamedBufferStorage(uniform_buffers_index, sizeof(data), &data, 0);
        //glBufferStorage(GL_UNIFORM_BUFFER,sizeof(data), &data, 0);              // SAME AS ABOVE
        //glBufferData(GL_UNIFORM_BUFFER,sizeof(data), &data, GL_STATIC_DRAW);    // SAME AS ABOVE
        //glNamedBufferData(uniform_buffers_index, sizeof(data), &data, GL_STATIC_DRAW); // SAME AS ABOVE
        
        // bind to our block
        glBindBufferBase(GL_UNIFORM_BUFFER, uniform_block_index, uniform_buffers_index);
    
    
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES,0 ,NPTS);
    }
    
    int main()
    {
        cout << sizeof(float) <<endl;
        glfwInit();
        GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL);
        glfwMakeContextCurrent(window);
        glewInit();
    
        init();
    
    
        while(!glfwWindowShouldClose(window)){
            display();
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        glfwDestroyWindow(window);
        glfwTerminate();
    
        return 0;
    }
    View Code

    结果发现用结构体是最简单访问形式。前提主要内存是要对齐:

    如图三角形按照y偏移,颜色为蓝色。都是C++预先设置好的。

     

     

    >>1,顺便到这里发现了一点,这俩函数完全一个东西。

    glNamedBufferStorage(uniform_buffers_index, sizeof(data), &data, 0);
    glBufferStorage(GL_UNIFORM_BUFFER,sizeof(data), &data, 0);

    glBufferStorage, glNamedBufferStorage — creates and initializes a buffer object's immutable data store

     

    >>2,顺便到这里发现了一点,这俩函数完全一个东西。

    glBufferData(GL_UNIFORM_BUFFER,sizeof(data), &data, GL_STATIC_DRAW);
    glNamedBufferData(uniform_buffers_index, sizeof(data), &data, GL_STATIC_DRAW);

     CP07:

    贴图部分,看了整篇文章,第一个案例讲解一个贴图,在fragment shader里有个uniform sampler2d类型的。

    #version 330 core
    out vec4 FragColor;
    in vec3 ourColor;
    in vec2 TexCoord;
    uniform sampler2D ourTexture;
    void main()
    {
        FragColor = texture(ourTexture, TexCoord);
    }

    但是在他的源码里没见用glUniform*设置这个值。

    作者介绍了这个原因是由于Texture Unit,默认的一个贴图location 永远是=0

    ------------------------------------------------------------

    参考原文:

    https://learnopengl.com/Getting-started/Textures

    一个贴图时候的源代码:

    https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/4.1.textures/textures.cpp

    有多个贴图时候的源代码:

    https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/4.2.textures_combined/textures_combined.cpp

    --------------------------------------------------------------

    >> 一个贴图物体如何创建,还有没按照官方的方法绘制,同样是个正方形,我用的   glDrawArrays(GL_QUADS,0 ,NPTS); 直接绘制了。

    这个是一个贴图物体创建的源代码:

    进入正篇,在这里我测试了两种shader方法都是可以的(opengl编程指南第二章介绍的);

    先来看材质:

    shader.vert:

    #version 450 core
    layout ( location = 0 ) in vec4 vPosition; // c++ pos
    layout ( location = 1 ) in vec4 vColor;  // c++ attribute color
    layout ( location = 2 ) in vec2 vTexCoord; // c++ attribute st
    
    //out vec4 ourColor; // OUT TO OUR ->fragment
    //out vec2 ourTexCoord; // OUT TO OUR ->fragment
    out block{
        vec4 ourColor;
        vec2 ourTexCoord;
    };
    void main(){
        gl_Position = vPosition;
        ourColor = vColor;
        ourTexCoord = vTexCoord;
    }

    shader.frag:

    #version 450 core
    out vec4 fColor;  // out to our fragment shader color
    
    //in vec4 ourColor; // from the vertex shader src
    //in vec2 ourTexCoord;
    in block{
        vec4 ourColor;
        vec2 ourTexCoord;
    };
    uniform sampler2D texture1;
    void main(){
        fColor = texture(texture1, ourTexCoord);
    }

    可以看到使用in/out块的方法制作材质。

    C++ SRC:

    #define GLEW_STATIC
    // GLEW
    
    #include <GL/glew.h>
    #include <cstdlib>
    #undef GLFW_DLL
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include "LoadShader.h"
    #define STB_IMAGE_IMPLEMENTATION
    #include <stb_image.h>
    
    
    using namespace std;
    
    const int NPTS = 4;
    static GLuint VBO,VAO;
    
    // load shader
    static LoadShader shader;
    
    // Texture
    static GLuint  texture;
    
    void init(){
        static const GLfloat verticles[NPTS][8] = {
            // positions          // colors           // texture coords
             {0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f},   // top right
             {0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f},   // bottom right
            {-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f},   // bottom left
            {-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f}    // top left
        };
    
        shader.load("shader.vert","shader.frag");
        shader.use();
        glCreateBuffers(1,&VBO);
        glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 );
        glBindBuffer(GL_ARRAY_BUFFER,VBO);
    
        glCreateVertexArrays(1,&VAO);
        glBindVertexArray(VAO);
    
        // position Attrib
        glVertexAttribPointer(0,                        // LOCATION
                              3,                        // vector is 3 length
                              GL_FLOAT,                 // float type
                              GL_FALSE,                 // not normalized
                              8 * sizeof(float),        // stride
                              (void*)0 );               // offset
        glEnableVertexAttribArray(0);
    
        // color Attrib
        glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(3* sizeof(float)) );
        glEnableVertexAttribArray(1);
    
    
        // st Attrib
        glVertexAttribPointer(2,2, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(6* sizeof(float)) );
        glEnableVertexAttribArray(2);
    
        //glGenTextures(1,&texture);
        glCreateTextures(GL_TEXTURE_2D, 1, &texture); // same as above method
        glBindTexture(GL_TEXTURE_2D, texture);
    
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        // same as above methods
        glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTextureParameteri(texture, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    
        // load imag
        int width,height,nchans;
        unsigned char *data = stbi_load("texture_02.jpg",&width, &height, &nchans, 0);
        cout << "WIDTH:" << width << "HEIGHT:" <<height <<endl;
        if(data){
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width,height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
            glGenerateTextureMipmap(texture);
    
        }
        else{
            cout << "Load texture error" <<endl;
        }
        stbi_image_free(data);
    
    
    }
    
    void display(){
    
        static const float black[] = {0.2f, 0.3f, 0.3f, 1.0f};
        glClearBufferfv(GL_COLOR,0,black);
        //glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        //glClear(GL_COLOR_BUFFER_BIT);
    
    
        //glBindTexture(GL_TEXTURE_2D, texture);
        glBindVertexArray(VAO);
        glDrawArrays(GL_QUADS,0 ,NPTS);
    }
    
    int main()
    {
        cout << sizeof(float) <<endl;
        glfwInit();
        GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL);
        glfwMakeContextCurrent(window);
        glewInit();
    
        init();
    
    
        while(!glfwWindowShouldClose(window)){
            display();
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        glfwDestroyWindow(window);
        glfwTerminate();
    
        return 0;
    }
    View Code

     一个贴图的套路就是:

    glCreateTextures()-> glBindTexture()  ->  glTexParameteri() -> glTexImage2D() -> glGenerateTextureMipmap()

    参考:

    https://learnopengl.com/Getting-started/Shaders

    https://github.com/SonarSystems/Modern-OpenGL-Tutorials

    https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/4.1.textures/textures.cpp

  • 相关阅读:
    Echarts动态加载柱状图和折线图混合展示的实例
    Webdynpro ABAP 简单剖析
    SAP NetWeaver Business Client (NWBC) 简介
    nginx and node.js配合使用 helloworld
    Nodejs连接mysql的增、删、改、查操作
    SAPUI5使用了哪些开源技术
    Javascript 严格模式详解
    SAPUI5实例一:来创建Web应用UI
    OPEN(SAP) UI5 学习入门系列之四:更好的入门系列-官方Walkthrough
    OPEN(SAP) UI5 学习入门系列之三:MVC (下)
  • 原文地址:https://www.cnblogs.com/gearslogy/p/12129234.html
Copyright © 2011-2022 走看看