天天看点

OpenGL-入门-BMP像素图glDrawPixels

3、glDrawPixels 的用法和举例

glDrawPixels:绘制一些像素。当前可以简单理解为“把内存中一些数据作为像素数据,进行绘制”。

  glDrawPixels 函数与 glReadPixels 函数相比,参数内容大致相同。它的第一、二、三、四个参数分别对应于 glReadPixels 函数的第三、四、五、六个参数,依次表示图象宽度、图象高度、像素数据内容、像素数据在内存中的格式。两个函数的最后一个参数也是对应的,glReadPixels 中表示像素读取后存放在内存中的位置,glDrawPixels 则表示用于绘制的像素数据在内存中的位置。

  注意到 glDrawPixels 函数比 glReadPixels 函数少了两个参数,这两个参数在glReadPixels 中分别是表示图象的起始位置。在 glDrawPixels 中,不必显式的指定绘制的位置,这是因为绘制的位置是由另一个函数 glRasterPos来指定的。glRasterPos函数的参数与 glVertex*类似,通过指定一个二维/三维/四维坐标,OpenGL 将自动计算出该坐标对应的屏幕位置,并把该位置作为绘制像素的起始位置。

  自己画一个dummy.bmp文件,程序如下

// glDrawPixels举例.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include "pch.h"
#include <iostream>
#include <gl/glut.h>
#define FileName "dummy.bmp"
static GLint ImageWidth;
static GLint ImageHeight;
static GLint PixelLength;
static GLubyte* PixelData;
#include <stdio.h>
#include <stdlib.h>
void display(void)
{
	// 清除屏幕并不必要
	// 每次绘制时,画面都覆盖整个屏幕
	// 因此无论是否清除屏幕,结果都一样
	// glClear(GL_COLOR_BUFFER_BIT);
	// 绘制像素
	glDrawPixels(ImageWidth, ImageHeight,GL_BGR_EXT, GL_UNSIGNED_BYTE, PixelData);
	// 完成绘制
	glutSwapBuffers();
}
int main(int argc, char* argv[])
{
	// 打开文件
	FILE* pFile;
	errno_t err;
	err= fopen_s(&pFile,"C:\\*********\\dummy.bmp", "rb");
	if (pFile == 0)
		exit(0);

	// 读取图象的大小信息
	fseek(pFile, 0x0012, SEEK_SET);
	fread(&ImageWidth, sizeof(ImageWidth), 1, pFile);
	fread(&ImageHeight, sizeof(ImageHeight), 1, pFile);

	// 计算像素数据长度
	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);

	// 初始化 GLUT 并运行
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(ImageWidth, ImageHeight);
	glutCreateWindow(FileName);
	glutDisplayFunc(&display);
	glutMainLoop();
	// 释放内存
	// 实际上,glutMainLoop 函数永远不会返回,这里也永远不会到达
	// 这里写释放内存只是出于一种个人习惯
	// 不用担心内存无法释放。在程序结束时操作系统会自动回收所有内存
	free(PixelData);
	return 0;
}
           
OpenGL-入门-BMP像素图glDrawPixels

 运行结果

OpenGL-入门-BMP像素图glDrawPixels

  OpenGL 在绘制像素之前,可以对像素进行若干处理。最常用的可能就是对整个像素图象进行放大/缩小。使用 glPixelZoom来设置放大/缩小的系数,该函数有两个参数,分别是水平方向系数和垂直方向系数。例如设置 glPixelZoom(0.5f, 0.8f);则表示水平方向变为原来的 50%大小,而垂直方向变为原来的 80%大小。我们甚至可以使用负的系数,使得整个图象进行水平方向或垂直方向的翻转(默认像素从左绘制到右,但翻转后将从右绘制到左。默认像素从下绘制到上,但翻转后将从上绘制到下。因此,glRasterPos*函数设置的“开始位置”不一定就是矩形的左下角)。

继续阅读