OpenGL-入门-BMP像素图glDrawPixels

3、glDrawPixels 的用法和举例

glDrawPixels:绘制一些像素。当前可以简单理解为“把内存中一些数据作为像素数据,进行绘制”。
  
glDrawPixels函数是OpenGL中的一个绘图函数,它用于在窗口中绘制像素数据。这个函数可以将一组像素数据直接绘制在窗口的指定位置,不需要通过顶点和图元来定义几何图形。glDrawPixels适用于简单的像素级绘制,但在实际应用中较少使用,因为它相对较慢且不支持硬件加速。

void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
/*width和height:绘制区域的宽度和高度,以像素为单位。
format:指定像素数据的颜色格式,常见的有 GL_RGB(红绿蓝颜色)和 GL_RGBA(红绿蓝透明颜色)等。
type:指定像素数据的数据类型,常见的有 GL_UNSIGNED_BYTE(无符号字节)等。
pixels:指向存储像素数据的指针。*/

注意,glDrawPixels函数绘制的像素数据会覆盖在当前绘制区域的位置,所以确保你在适当的位置调用该函数

#include 

void display() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear color to black
    glClear(GL_COLOR_BUFFER_BIT); // Clear the color buffer

    GLsizei width = 300;
    GLsizei height = 300;
    GLubyte* pixels = new GLubyte[width * height * 3];

    // Fill the pixel array with colors (e.g., red and green stripes)
    //这段代码会在绘制区域的左半部分创建红色的条纹,右半部分创建绿色的条纹。
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            int index = (y * width + x) * 3;
            if (x < width / 2) {
                // Red color
                pixels[index] = 255;
                pixels[index + 1] = 0;
                pixels[index + 2] = 0;
            }
            else {
                // Green color
                pixels[index] = 0;
                pixels[index + 1] = 255;
                pixels[index + 2] = 0;
            }
        }
    }

    glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);

    glFlush(); // Ensure all drawing commands are executed
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(800, 600);
    glutCreateWindow("glDrawPixels Example");

    glutDisplayFunc(display);

    glutMainLoop();
    return 0;
}

在窗口中绘制一个红绿相间的图案
OpenGL-入门-BMP像素图glDrawPixels_第1张图片

glDrawPixels 函数与 glReadPixels 函数相比,参数内容大致相同。它的第一、二、三、四个参数分别对应于 glReadPixels 函数的第三、四、五、六个参数,依次表示图象宽度、图象高度、像素数据内容、像素数据在内存中的格式。两个函数的最后一个参数也是对应的,glReadPixels 中表示像素读取后存放在内存中的位置,glDrawPixels 则表示用于绘制的像素数据在内存中的位置。
  注意到 glDrawPixels 函数比 glReadPixels 函数少了两个参数,这两个参数在glReadPixels 中分别是表示图象的起始位置。在 glDrawPixels 中,不必显式的指定绘制的位置,这是因为绘制的位置是由另一个函数 glRasterPos来指定的。glRasterPos函数的参数与 glVertex*类似,通过指定一个二维/三维/四维坐标,OpenGL 将自动计算出该坐标对应的屏幕位置,并把该位置作为绘制像素的起始位置。
  自己画一个dummy.bmp文件,程序如下

// glDrawPixels举例.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include "pch.h"
#include 
#include 
#define FileName "dummy.bmp"
static GLint ImageWidth;
static GLint ImageHeight;
static GLint PixelLength;
static GLubyte* PixelData;
#include 
#include 
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_第2张图片
 运行结果OpenGL-入门-BMP像素图glDrawPixels_第3张图片
  OpenGL 在绘制像素之前,可以对像素进行若干处理。最常用的可能就是对整个像素图象进行放大/缩小。使用 glPixelZoom来设置放大/缩小的系数,该函数有两个参数,分别是水平方向系数和垂直方向系数。例如设置 glPixelZoom(0.5f, 0.8f);则表示水平方向变为原来的 50%大小,而垂直方向变为原来的 80%大小。我们甚至可以使用负的系数,使得整个图象进行水平方向或垂直方向的翻转(默认像素从左绘制到右,但翻转后将从右绘制到左。默认像素从下绘制到上,但翻转后将从上绘制到下。因此,glRasterPos*函数设置的“开始位置”不一定就是矩形的左下角)。

你可能感兴趣的:(OpenGL,glDrawPixels,opengl,bmp像素图操作)