glut窗口除了可以绘制矢量图之外,还可以显示BMP文件,用函数glDrawPixels把内存块中的图像数据绘制到窗口上,glDrawPixels函数原型:

glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
  • 第一到第四个参数分别表示图象宽度、图象高度、像素数据内容、像素数据在内存中的格式。
  • 第五个参数表示用于绘制的像素数据在内存中的位置。glDrawPixels函数会把该快内存中的图像数据绘制到窗口上。

glDrawPixel在窗口上绘制的位置可以由函数glRasterPos2d/glRasterPos2f定义,glRasterPos2d有两个GLdoulbe类型的参数,范围都是-1~1,(-1,-1)是窗口的左下角位置,(1,1)是窗口的右上角位置 ,(0,0)是中心位置,默认是从(-1,-1)即窗口的左下角位置开始绘制。

glPixelZoom函数可以实现把图像按比例缩放功能,两个参数分别是在x和y方向上的缩放比例。

glDrawPixel的应用实例,把一幅图像的图像数据读入内存,并通过glDrawPixel绘制到窗口上:

#include "glut.h"
#include <stdio.h>
#include <stdlib.h> #define FileName "SeaAndTree.bmp" static GLint ImageWidth; //BMP图像宽
static GLint ImageHeight; //BMP图像高
static GLint PixelLength; //图像数据长度
static GLubyte* PixelData; void ReadBmpFile()
{
// 打开文件
FILE* pFile = fopen("SeaAndTree.bmp", "rb");
if( pFile == 0 )
exit(0); // 读取图象的宽高信息
fseek(pFile, 0x0012, SEEK_SET);
fread(&ImageWidth, sizeof(ImageWidth), 1, pFile);
fread(&ImageHeight, sizeof(ImageHeight), 1, pFile); // 计算像素数据长度,不足4位补齐4位
PixelLength = ImageWidth * 3;
while( PixelLength % 4 != 0 )
++PixelLength;
PixelLength *= ImageHeight; // 读取像素数据
PixelData = (GLubyte*)malloc(PixelLength);
if( PixelData == 0 )
exit(0); fseek(pFile, 54, SEEK_SET); //跳过文件头和信息头
fread(PixelData, PixelLength, 1, pFile); // 关闭文件
fclose(pFile);
} void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPixelZoom(0.5f,0.5f);
glRasterPos2f(-0.5,-0.5); // 绘制像素
glDrawPixels(ImageWidth, ImageHeight,
GL_BGR_EXT, GL_UNSIGNED_BYTE, PixelData); // 完成绘制
glutSwapBuffers();
} int main(int argc, char* argv[])
{
ReadBmpFile(); //读取BMP图像数据到内存,并获取图像的宽高信息
// 初始化GLUT并运行
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(ImageWidth, ImageHeight);
glutCreateWindow(FileName);
glutDisplayFunc(&display);
glutMainLoop();
// 释放内存
free(PixelData);
return 0;
}

原始图像绘制:

宽高缩小一半,并且改变绘制起点:

图像数据的复制

另外可以通过glCopyPixels函数实现图像数据的复制功能,glCopyPixels直接从像素数据复制出新的像素数据,避免了多余的数据的格式转换,并且可能直接由显卡负责复制,不需要经过主内存,因此效率比较高。

glCopyPixels函数原型:

glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);

  • 第一、二个参数表示复制像素来源的矩形的左下角坐标;
  • 第三、四个参数表示复制像素来源的矩形框的宽度和高度;
  • 第五个参数通常使用GL_COLOR,表示复制像素的颜色;也可以是GL_DEPTH或GL_STENCIL,分别表示复制深度缓冲数据或模板缓冲数据。

更改上边程序中的display函数,加入glCopyPixels对图像数据的复制功能:

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPixelZoom(0.5f,0.5f);
glRasterPos2f(-1,-1); // 绘制像素
glDrawPixels(ImageWidth, ImageHeight,
GL_BGR_EXT, GL_UNSIGNED_BYTE, PixelData); // 完成绘制
glutSwapBuffers(); //重新定义图像的缩放比例和绘制位置
glPixelZoom(1,1);
glRasterPos2f(0,0); glCopyPixels(0, 0,
ImageWidth/2, ImageHeight/2, GL_COLOR); //更改图像的绘制位置为左上部分
glRasterPos2f(-1,0);
glCopyPixels(0, 0,
ImageWidth/2, ImageHeight/2, GL_COLOR); //更改图像的绘制位置为左下部分
glRasterPos2f(0,-1);
glCopyPixels(0, 0,
ImageWidth/2, ImageHeight/2, GL_COLOR); glutSwapBuffers();
}

读入原图像并且宽高缩小一倍后绘制,之后使用glCopyPixels复制3份图像,分别绘制在窗口的另外3个区域:

OpenGL(十一) BMP真彩文件的显示和复制操作的更多相关文章

  1. Win8 Metro中文件读写删除与复制操作

    Win8Metro中,我们不能在向以前那样调用WIN32的API函数来进行文件操作,因此,下面就来介绍一下Win8 Metro中文件的读写操作. 1 Windows 8 Metro Style App ...

  2. [转]opengl入门例题(读取bmp图片,并显示)

    #include<gl/glut.h> #define FileName "bliss.bmp" static GLint imagewidth; static GLi ...

  3. OpenGL 保存bmp图像

    今天我们先简单介绍Windows中常用的BMP文件格式,然后讲OpenGL的像素操作.虽然看起来内容可能有点多,但实际只有少量几个知识点,如果读者对诸如”显示BMP图象”等内容比较感兴趣的话,可能不知 ...

  4. 图像编程学习笔记1——bmp文件结构处理与显示

    文本内容转载自<数字图像处理编程入门>,代码为自己实现 1.1图和调色板的概念 如今Windows(3.x以及95,98,NT)系列已经成为绝大多数用户使用的操作系统,它比DOS成功的一个 ...

  5. 图像处理笔记(1): bmp文件结构处理与显示

    1.1图和调色板的概念 如今Windows(3.x以及95,98,NT)系列已经成为绝大多数用户使用的操作系统,它比DOS成功的一个重要因素是它可视化的漂亮界面.那么Windows是如何显示图象的呢? ...

  6. Linux C语言解析.bmp格式图片并显示汉字

    bmp.h 文件 #ifndef __BMP_H__ #define __BMP_H__ #include <unistd.h> #include <stdio.h> #inc ...

  7. SNF开发平台WinForm之十三-单独从服务器上获取PDF文件进行显示-SNF快速开发平台3.3-Spring.Net.Framework

    1运行效果: 2开发实现: 如果需要单独显示PDF文件时用下面代码去实现,指定url地址. 地址: . 获取附件管理的实体对象: List<KeyValuePair<string, obj ...

  8. [自制操作系统] BMP格式文件读取&图形界面系统框架/应用接口设计

    本文将介绍在本人JOS中实现的简单图形界面应用程序接口,应用程序启动器,以及一些利用了图形界面的示例应用程序. 本文主要涉及以下部分: 内核/用户RW/RW调色板framebuffer共享区域 8bi ...

  9. GDI+ gif文件的显示和格式转换

    GDI+ gif文件的显示和格式转换   gdi+imagedeletenulltiff GDI+ gif文件的显示和格式转换 怎么获取gif文件的每一帧,并且显示出来呢? 1.怎么用gid+显示gi ...

随机推荐

  1. stm32的pwm波

  2. POJ 1775 Sum of Factorials (ZOJ 2358)

    http://poj.org/problem?id=1775 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1334 题目大意: ...

  3. 【2016 Summary】为过往补课、为将来夯实

    前言 看了CSDN上非常多"我的2016"年终总结,也就不能免俗地来写一波.按着时间轴捋一捋这过去一年的经过,也算是这元旦假期总一个午后的休闲时光了.(结果没想到的是午饭前開始写的 ...

  4. ios开发网络学习二:URL转码以及字典转模型框架MJExtension的使用

    一:url转码,当url中涉及到中文的时候,要考虑转码,用UTF8对中文的url进行转码 #import "ViewController.h" @interface ViewCon ...

  5. php 字符串 去掉 html标签

    echo strip_tags("Hello <b>world!</b>");

  6. 洛谷 P2197 nim游戏

    洛谷 P2197 nim游戏 题目描述 甲,乙两个人玩Nim取石子游戏. nim游戏的规则是这样的:地上有n堆石子(每堆石子数量小于10000),每人每次可从任意一堆石子里取出任意多枚石子扔掉,可以取 ...

  7. 用CMake代替makefile进行跨平台交叉编译

    在开始介绍如何使用CMake编译跨平台的静态库之前,先讲讲我在没有使用CMake之前所趟过的坑.因为很多开源的程序,比如png,都是自带编译脚本的.我们可以使用下列脚本来进行编译: 1 2 3 ./c ...

  8. 图标插件--jqplot实现柱状图及饼图,表盘图演示样例

    柱状图 在jqPlot图表插件使用说明(一)中,我们已经能够通过jqPlot绘制出比較简单的线形图.通过查看源码.我们也能够看出,线形图是jqPlot默认的图表类型: /** * Class: Ser ...

  9. url前面双斜杠、单斜杠、无斜杠、点+单斜杠的总结

    原文:url前面双斜杠.单斜杠.无斜杠.点+单斜杠的总结 本来只是一个绝对url和相对url的简单问题,但实际使用中会碰到一些不常见的,比如双斜杠,经常不用竟然忘了,做一下总结.可以参考一下这篇文章 ...

  10. WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush)

    原文:WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush) 前面我们介绍到,Path对象表示一个用直线或者曲线连接的图形,我们可以使用Path.Data ...