zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    放缩ImageView
    2017/5/3 afternoon
    2017/5/3 morning
    2017/5/2 afternoon
    2017/5/2 morning
    2017/4/28 afternoon
    2017/4/28 morning
    2017/4/27 afternoon
    2017/4/27 morning
    2017/4/26 afternoon
  • 原文地址:https://www.cnblogs.com/charlee44/p/5745127.html
Copyright © 2011-2022 走看看