• [OpenGL]纹理贴图实现 总结


    实现步骤

    第一步:设置所需要的OpenGL环境
    设置上下文环境
    删除已经存在的渲染的缓存
    设置颜色缓存
    设置帧缓存
    清除缓存
    设置窗口大小
    开启功能
    编译shander
    使用program
    获取shader中的属性和uniform索引

    第二步:绘制图片
    获取图片数据并且的到对应的纹理id
    指定纹理,绑定纹理
    开始对图形进行渲染
    (
    启用顶点属性数组纹理坐标,将纹理坐标传递到shader中
    启用顶点属性数组顶点坐标,将顶点坐标传递到shader中
    启用索引数组
    开始绘制
    )
    解绑纹理

    实现

    这次实现的过程有些艰难啊,走了很多的弯路,不过也因此学到蛮多的,自己写的怎么都运行不了,但是在别人的基础上运行就不行,其中错误的地方有:1.纹理的数据错误,使用png的库失败;2.绘制函数的参数错误;3.使用新版本的glsl语言版本,但是xcode并不支持,并不熟悉期间的语言版本迭代;

    实现代码:

    主程序

    #include "SOIL.h"
    
    static void error_callback(int error, const char* description)
    {
        fprintf(stderr, "Error: %s
    ", description);
    }
    
    int main(void)
    {
        GLFWwindow* window;
        
        glfwSetErrorCallback(error_callback);
        
        if (!glfwInit())
            exit(EXIT_FAILURE);
        
        window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
        if (!window)
        {
            std::cout << "Failed to create GLFW window" << std::endl;
            glfwTerminate();
            exit(EXIT_FAILURE);
        }
    
        glfwMakeContextCurrent(window);
        glewExperimental = GL_TRUE;
        glewInit();
        
        glfwSwapInterval(1);
        glViewport(0, 0, 640, 480);
        
        bool ret = getImageData("/Users/staff/Desktop/Moni/Moni/wall.png");
        if (!ret) {
            cout << "get iamge data is failed." << endl;
        }
        else {
            cout << "get iamge data is success." << endl;
            
            //测试图片数据
            //        FILE * file;
            //        file = fopen("/Users/staff/Desktop/abc.png","wb");
            //        if (file)
            //        {
            //            fwrite(_sp_image_data.getBytes(),1,_sp_image_data.getSize(), file);
            //        }
            //        fclose(file);
        }
        
        // 第一行和第三行不是严格必须的,默认使用GL_TEXTURE0作为当前激活的纹理单元
        
        /**
         *  GL_TEXTURE_2D表示操作2D纹理
         *  创建纹理对象,
         *  绑定纹理对象,
         */
        glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
        glGenTextures(1, &_sp_textureID);
        glBindTexture(GL_TEXTURE_2D, _sp_textureID);
        
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    //    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
    //    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
    
        /**
         *  将图像数据传递给到GL_TEXTURE_2D中, 因其于textureID纹理对象已经绑定,所以即传递给了textureID纹理对象中。
         *  glTexImage2d会将图像数据从CPU内存通过PCIE上传到GPU内存。
         *  不使用PBO时它是一个阻塞CPU的函数,数据量大会卡
         */
    //    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _sp_image_size.getX(), _sp_image_size.getY(), 0, GL_RGBA, GL_UNSIGNED_BYTE, _sp_image_data.getBytes());
    //    glGenerateMipmap(GL_TEXTURE_2D);
        
        int width, height;
        unsigned char* image = SOIL_load_image("/Users/staff/Desktop/fgh/fgh/wall.jpg", &width, &height, 0, SOIL_LOAD_RGB);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
        glGenerateMipmap(GL_TEXTURE_2D);
        SOIL_free_image_data(image);
        
        glBindTexture(GL_TEXTURE_2D, 0);
        
        _vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(_vertexShader, 1, &CCPositionTextureColorVert, NULL);
        glCompileShader(_vertexShader);
        
        GLint status;
        glGetShaderiv(_vertexShader, GL_COMPILE_STATUS, &status);
        if (!status) {
            GLint infoLen = 0;
            glGetShaderiv(_vertexShader, GL_INFO_LOG_LENGTH, &infoLen);
            if (infoLen) {
                char* infoLog = static_cast<char *>(malloc(sizeof(char) * infoLen));
                glGetShaderInfoLog(_vertexShader, infoLen, NULL, infoLog);
                cout << "compile vert shader wrong..." << infoLog << endl;
            }
        }
        else {
            cout << "compile vert shader success..." << endl;
        }
        
        _fragShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(_fragShader, 1, &CCPositionTextureColorFrag, NULL);
        glCompileShader(_fragShader);
        
        glGetShaderiv(_fragShader, GL_COMPILE_STATUS, &status);
        if (!status) {
            GLint infoLen = 0;
            glGetShaderiv(_fragShader, GL_INFO_LOG_LENGTH, &infoLen);
            if (infoLen) {
                char* infoLog = static_cast<char *>(malloc(sizeof(char) * infoLen));
                glGetShaderInfoLog(_fragShader, infoLen, NULL, infoLog);
                cout << "compile frag shader wrong..." << infoLog << endl;
            }
        }
        else {
            cout << "compile vert frag success..." << endl;
        }
        
        _program = glCreateProgram();
        glAttachShader(_program, _vertexShader);
        glAttachShader(_program, _fragShader);
        glLinkProgram(_program);
        
        glGetProgramiv(_program, GL_LINK_STATUS, &status);
        if (status == GL_FALSE) {
            GLint infoLen = 0;
            glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &infoLen);
            if (infoLen) {
                char* infoLog = static_cast<char *>(malloc(sizeof(char) * infoLen));
                glGetProgramInfoLog(_program, infoLen, NULL, infoLog);
                cout << "link program wrong..." << infoLog << endl;
            }
        }
        else {
            cout << "the program link success." << endl;
        }
        
        //设置顶点数据(和缓冲)和属性指针
        GLfloat vertices[] = {
            // Positions          // Colors           // Texture Coords
            0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   2.0f, 0.1f,
            0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   2.0f, 0.8f,
            -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.5f, 0.8f,
            -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.5f, 0.1f
        };
        GLuint indices[] = {
            0, 1, 3,
            1, 2, 3
        };
        
        
        GLuint VBO, VAO, EBO;
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glGenBuffers(1, &EBO);
        
        glBindVertexArray(VAO);
        
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
        
        GLuint _positionSlot = glGetAttribLocation(_program, "position");
        GLuint _colorSlot = glGetAttribLocation(_program, "color");
        GLuint _textureCoordsSlot = glGetAttribLocation(_program, "texCoord");
        //GLuint _textureSlot = glGetUniformLocation(shader.program, "ourTexture");
        
        glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
        glEnableVertexAttribArray(_positionSlot);
        
        glVertexAttribPointer(_colorSlot, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
        glEnableVertexAttribArray(_colorSlot);
        
        glVertexAttribPointer(_textureCoordsSlot, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
        glEnableVertexAttribArray(_textureCoordsSlot);
        
        glBindVertexArray(0);
        
        while (!glfwWindowShouldClose(window))
        {
            glfwPollEvents();
            int width, height;
            glfwGetFramebufferSize(window, &width, &height);
            glViewport(0, 0, width, height);
            glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
            
            //use
            glUseProgram(_program);
            
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, _sp_textureID); // 绑定,即可从_textureID中取出图像数据
            glUniform1i(glGetUniformLocation(_program, "ourTexture1"), 0);
            
            //draw
            glBindVertexArray(VAO);
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
            glBindVertexArray(0);
            
            glfwPollEvents();
            glfwSwapBuffers(window);
        }
        
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
        glDeleteBuffers(1, &EBO);
        
        glfwDestroyWindow(window);
        
        glfwTerminate();
        exit(EXIT_SUCCESS);
    }
    
    

    上面是主程序的代码,除了这个,还需要顶点shader和片元shader;其实这里有个坑,就是glsl的语言版本,越望越后面,增加了更多的新 功能,导致我不认识,从而使用了新版本的,同时xcode只更新了到了2.0上,其他版本在xcode并不能使用,因此导编编译失败。

    先是顶点shader:

    const char* CCPositionTextureColorVert = STRINGIFY(
    attribute vec3 position;
    attribute vec3 color;
    attribute vec2 texCoord;
                                                       
    varying vec3 ourColor;
    varying vec2 TexCoord;
                                                       
    void main() {
        gl_Position = vec4(position, 1.0);
        ourColor = color;
        TexCoord = texCoord;
    }
    );
    
    

    接下来的是片元shader

    const char* CCPositionTextureColorFrag = STRINGIFY(
    varying vec3 ourColor;
    varying vec2 TexCoord;
                                                       
    //varying vec4 color;
                                                       
    uniform sampler2D ourTexture1;
    uniform sampler2D ourTexture2;
    uniform float mixValue;
                                                       
    void main() {
        gl_FragColor = mix(texture2D(ourTexture1, TexCoord) * vec4(ourColor, 1.0), texture2D(ourTexture2, vec2(-TexCoord.x, TexCoord.y)), mixValue);
    }
    );
    
    
  • 相关阅读:
    efwplus框架
    注册区域
    社招面试记录与总结
    验证码 Captcha 之大插件
    发生内存泄漏?
    Flume+LOG4J+Kafka
    协议如何保证可靠传输
    oracle之spool详细使用总结(转)
    SSH协议详解(转)
    oracle nologging用法(转)
  • 原文地址:https://www.cnblogs.com/George1994/p/6292370.html
Copyright © 2020-2023  润新知