Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / OpenGL显示图片

最近想用C++在windows下实现一个基本的图像查看器功能,目前只想到了使用GDI或OpenGL两种方式。由于实在不想用GDI的API了,就用OpenGL的方式实现了一下基本的显示功能。用GDAL读取图像,这样就能与图像格式无关。OpenGL的glDrawPixels()函数也能实现图像显示,但是现在高版本的OpenGL都采用glTexImage2D()贴纹理的方式了,也不用考虑图像大小是否是2的N次方,或者4字节对齐的问题。具体实现如下:
// ImageShow.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include "ImageShow.h"#include <iostream>
#include <glglew.h>            // 包含最新的gl.h,glu.h库
#include <glfreeglut.h>            // 包含OpenGL实用库
#include <gdal_priv.h>using namespace std;unsigned int  texture;    // 纹理对象
unsigned char* imgBuf = nullptr;
int imgWidth;
int imgHeight;void ReadImage()
{
    GDALAllRegister();    GDALDataset* img = (GDALDataset *)GDALOpen("lena.bmp", GA_ReadOnly);
    //GDALDataset* img = (GDALDataset *)GDALOpen("dst.tif", GA_ReadOnly);
    if (img == nullptr)
    {
        return;
    }      imgWidth = img->GetRasterXSize(); //图像宽度
    imgHeight = img->GetRasterYSize();  //图像高度
    int bandNum = img->GetRasterCount();    //波段数 
    int depth = GDALGetDataTypeSize(img->GetRasterBand(1)->GetRasterDataType()) / 8;    //图像深度    //申请buf
    size_t imgBufNum = (size_t)imgWidth * imgHeight * bandNum * depth;
    size_t imgBufOffset = (size_t)imgWidth * (imgHeight - 1) * bandNum * depth;
    imgBuf = new GByte[imgBufNum];
    //读取
    img->RasterIO(GF_Read, 0, 0, imgWidth, imgHeight, imgBuf + imgBufOffset, imgWidth, imgHeight,
        GDT_Byte, bandNum, nullptr, bandNum*depth, -imgWidth*bandNum*depth, depth);    GDALClose(img);
}void InitGL()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);    glShadeModel(GL_SMOOTH);      //平滑着色
    glEnable(GL_DEPTH_TEST);     //深度测试
    glEnable(GL_CULL_FACE);    //只渲染某一面
    glFrontFace(GL_CCW);   //逆时针正面
           
    glEnable(GL_TEXTURE_2D);    //启用2D纹理映射     //载入纹理图像:
    ReadImage();
   
    //生成纹理对象:
    glGenTextures(1, &texture);       
}void DrawGLScene()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glBindTexture(GL_TEXTURE_2D, texture);    //绑定纹理:
   
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //支持4字节对齐    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);      //S方向上贴图
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);      //T方向上贴图
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);     //放大纹理过滤方式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);     //缩小纹理过滤方式
       
    glTexImage2D(GL_TEXTURE_2D, 0, 3, imgWidth, imgHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, imgBuf);  //载入纹理:                                                                                                          glMatrixMode(GL_MODELVIEW);                       // 选择模型观察矩阵
    glLoadIdentity();                                 // 重置模型观察矩阵   
    glMatrixMode(GL_PROJECTION);                        // 选择投影矩阵     
    glLoadIdentity();
       
    glEnable(GL_TEXTURE_2D);    //启用2D纹理映射
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(-0.5f, -0.5f, 0.0f);
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(0.5f, -0.5f, 0.0f);
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(0.5f, 0.5f, 0.0f);
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(-0.5f, 0.5f, 0.0f);
    glEnd();
    glDisable(GL_TEXTURE_2D);    glutSwapBuffers();
}GLvoid ReSizeGLScene(GLsizei width, GLsizei height)    // 重置OpenGL窗口大小
{
    glViewport(0, 0, width, height);
}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
   
    glutInitContextProfile(GLUT_CORE_PROFILE);
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("opengl");
   
    InitGL(); 
    glutDisplayFunc(DrawGLScene);
    glutReshapeFunc(ReSizeGLScene);
    //glutKeyboardFunc(keyboard);
    //glutMouseWheelFunc(mouse_wheel);
    //glutIdleFunc(idle);    glutMainLoop();
       
    return 0;
}
最后显示的情况如下:另外注意最后需要释放资源:
glDeleteTextures(1, &texture);
if (imgBuf)
{
    delete[] imgBuf;
    imgBuf = nullptr;
}OpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htmUbuntu 13.04 安装 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htmOpenGL三维球体数据生成与绘制【附源码】 http://www.linuxidc.com/Linux/2013-04/83235.htmUbuntu下OpenGL编程基础解析 http://www.linuxidc.com/Linux/2013-03/81675.htm如何在Ubuntu使用eclipse for c++配置OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm《OpenGL超级宝典》学习笔记 http://www.linuxidc.com/Linux/2013-10/91414.htm本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-08/133984.htm