使用OpenGL和OpenCV加载和显示纹理

时间:2017-03-28 14:29:28

标签: c++ opencv opengl-es

我是OpenGL的血腥新手,它看起来有时像黑魔法。我只是想加载并显示一个纹理用于​​测试目的,我不想使用教程库来真正理解会发生什么。但我只是得到一个黑屏,我找不到它的原因。

我的c ++源代码

int main(){
    new cpp_logger();
    GLint program_rgb_;
    Mat img = imread("plane.jpg");
    std::string file_path = "plane.jpg";

    // Set viewport window size and clear color bit.
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    //set viewport
    glViewport(0, 0, img.size().width, img.size().height);

    // Create a Vertex Buffer Object and copy the vertex data to it
    GLuint vbo;
    glGenBuffers(1, &vbo);
    GLfloat vertices[] = {-1, 1, -1, -1, 1, 1, 1, -1,
                          0, 0, 0, 1, 1, 0, 1, 1};
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //create program and shader
    program_rgb_ = glCreateProgram();
    const char* vertexShader = read_shader("vertex.glsl"); //simple method to read the shader files
    const char* fragmentShader = read_shader("fragment.glsl");
    CreateShader(program_rgb_, GL_VERTEX_SHADER, vertexShader); //simple method to link and compile shader programs
    CreateShader(program_rgb_, GL_FRAGMENT_SHADER, fragmentShader);
    glLinkProgram(program_rgb_);
    glUseProgram(program_rgb_);

    //use fast 4-byte alignment (default anyway) if possible because using OpenCV
    glPixelStorei(GL_UNPACK_ALIGNMENT, (img.step & 3) ? 1 : 4);
    //set length of one complete row in data (doesn't need to equal image.cols)
    glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, img.step/img.elemSize());
    flip(img, img, 0);

    // Load texture
    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);

    //set parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.cols, img.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data);
    glUniform1i(glGetUniformLocation(program_rgb_,"tex"), 0);

    uint8_t* result = new uint8_t[img.cols * img.rows * 4];
    while(true){
        GLint pos_location = glGetAttribLocation(program_rgb_, "a_position");
        GLint tc_location = glGetAttribLocation(program_rgb_, "a_texCoord");

        // Specify the layout of the vertex data
        glEnableVertexAttribArray(pos_location);
        glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, 0);

        //specify color data
        glEnableVertexAttribArray(tc_location);
        glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, static_cast<float*>(0) + 8);

        // Draw a rectangle from the 2 triangles using 6 indices
        glDrawArrays(GL_TRIANGLES, 0, 8);
        glReadPixels(0, 0, img.rows, img.cols, GL_BGRA_EXT, GL_UNSIGNED_BYTE, (void*)result);

        auto result_ = cv::Mat(img.rows, img.cols, CV_8UC4, result);
        imshow("img", result_);
        if(waitKey(1) >= 0) break;
    }

    destroyAllWindows();
    return EXIT_SUCCESS;
}

我的片段着色器

#version 150 core
precision mediump float;
in vec2 texCoord;
uniform sampler2D tex;
void main()
{
    gl_FragColor = texture2D(tex, texCoord);
}

我的顶点着色器

#version 150 core
out vec2 texCoord;
attribute vec2 a_texCoord;
attribute vec4 a_position;
void main()
{
    texCoord = a_texCoord;
    gl_Position = a_position;
}

非常感谢你的帮助!

修改 对不起有误解。我的意思是:我不想使用像SOIL和SFML这样的库,我想用另一种方法来完全理解实际发生的事情。

0 个答案:

没有答案