OpenGL ES 渲染单通道图像

  • Post author:
  • Post category:其他




OpenGL ES 渲染单通道图像

使用 TOF 相机获取深度图一般获取到的深度图是 16 bit 单通道,有时为了方便查看深度图是否正确,需要渲染改单通道图像。

下面简单的介绍几个渲染单通道图像的注意事项:

首先,需要将 16 bit 的深度图转为换 8 bit 深度图,部分代码如下:

typedef struct _tag_image_info {
	int width;
	int height;
	int format;
	int pitch[4];
	unsigned char* data[4];
}ImageInfo, LPImageInfo;

LPImageInfo convertU16ToGray8(ImageInfo *const pSrcImage)
{
    // convert depth u 16 to gray 8 bit, need test time cost
    int width = pSrcImage->width;
    int height = pSrcImage->height;
    for (int i = 0; i < height; ++i) {
        for (int j = 0; j < width; ++j) {
            *(m_DstImage.data[0] + i * width + j) = *(pSrcImage->data[0] + i * width * 2 + j * 2);
        }
    }
    return &m_DstImage;
}

创建纹理对象和上传纹理图像的部分代码:

// create texture id
GLuint textureGray = GL_NONE;
glGenTextures(1, &textureGray);
glBindTexture(TargetType, textureGray);
glTexParameterf(TargetType, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(TargetType, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(TargetType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(TargetType, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(TargetType, GL_NONE);

// upload iamge data
glBindTexture(GL_TEXTURE_2D, textureGray);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, pGrayImg->width, pGrayImg->height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pGrayImg->data[0]);
glBindTexture(GL_TEXTURE_2D, GL_NONE);

关键在于使用

GL_LUMINANCE

这个 color format。

接着是 vertex shader 和 fragment shader 的写法:

#define GLES_VERSION_STRING        "#version 300 es\n"
#define GLES_MEDIUMP_STRING        "precision mediump float;\n"

const char* rect_vertex_shader =
    GLES_VERSION_STRING
    R"(
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec2 aTexCoords;
    uniform mat4 mvp;
    out vec2 TexCoords;
    void main() {
        gl_Position = mvp * vec4(aPos, 1.0);
        TexCoords = aTexCoords;
    }
    )";

const char* rect_fragment_shader_gray =
    GLES_VERSION_STRING
    GLES_MEDIUMP_STRING
    R"(    
    in vec2 TexCoords;
    out vec4 FragColor;
    uniform sampler2D y_texture;
    
    // 读取单通道至 r,将 g 和 b 通道设置为何 r 通道一致
    void ConvertGray8 () {
        vec3 rgb;
        rgb.x = texture(y_texture, TexCoords).r;
        rgb.y = rgb.x;
        rgb.z = rgb.x;
        FragColor = vec4(rgb, 1);
    }
    
    void main() {
    	ConvertGray8();
    }
    )";

之后渲染部分代码即正常渲染 rgb 的方式,绑定 VAO,绑定纹理对象,绘制即可。

渲染效果如下:





单通道灰度图渲染效果



版权声明:本文为cgwang_1580原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。