天天看點

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*函數設定的“開始位置”不一定就是矩形的左下角)。

繼續閱讀