#pragma comment(lib, "gltools.lib")
#define _CRT_SECURE_NO_DEPRECATE
#include <GLTools.h> // OpenGL toolkit
#include <GLShaderManager.h>
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
#pragma pack(1)
typedef struct
{
GLbyte identsize; // Size of ID field that follows header (0)
GLbyte colorMapType; // 0 = None, 1 = paletted
GLbyte imageType; // 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rle
unsigned short colorMapStart; // First colour map entry
unsigned short colorMapLength; // Number of colors
unsigned char colorMapBits; // bits per palette entry
unsigned short xstart; // image x origin
unsigned short ystart; // image y origin
unsigned short width; // width in pixels
unsigned short height; // height in pixels
GLbyte bits; // bits per pixel (8 16, 24, 32)
GLbyte descriptor; // image descriptor
} TGAHEADER;
#pragma pack()
GLShaderManager shaderManager;
void SetupRC()
{
glClearColor(0, 0, 1, 1);
shaderManager.InitializeStockShaders();
}
void ChangeSize(int w, int h)
{
glViewport(0, 0, w, h);
}
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glutSwapBuffers();
}
//程序清单5.1 用gltWriteTGA函数来将屏幕图像保存为一个Targa文件
GLint gltWriteTGA(const char *szFileName)
{
FILE *pFile; //文件指针
TGAHEADER tgaHeader; //TGA文件头(TGAHEADER结构体是在上方定义的,原本是没有的百度找了个)
unsigned long lImageSize;// 图像的大小 字节表示
GLbyte *pBits = NULL; //指向位的指针
GLint iViewport[4]; //以像素表示的视口
GLint lastBuffer; //存储当前的读取缓冲区设置(书籍是GLenum但由于类型不符改为GLint)
//获取视口大小
glGetIntegerv(GL_VIEWPORT, iViewport);
//图像应该多大(targa文件将被紧密包装)
lImageSize = iViewport[2] * 3 * iViewport[3];
//分配块
pBits = (GLbyte *)malloc(lImageSize);
if (pBits == NULL)
return 0;
//从颜色缓冲区读取位
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
//获取当前读取缓冲区设置并进行保存
glGetIntegerv(GL_READ_BUFFER, &lastBuffer);
//切换到前台缓冲区并进行读取操作
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, iViewport[2], iViewport[3], GL_BGR, GL_UNSIGNED_BYTE, pBits);
//恢复读取缓冲区状态
glReadBuffer(lastBuffer);
//初始化Targa头
tgaHeader.identsize = 0;
tgaHeader.colorMapType = 0;
tgaHeader.imageType = 2;
tgaHeader.colorMapStart = 0;
tgaHeader.colorMapLength = 0;
tgaHeader.colorMapBits = 0;
tgaHeader.xstart = 0;
tgaHeader.ystart = 0;
tgaHeader.width = iViewport[2];
tgaHeader.height = iViewport[3];
tgaHeader.bits = 24;
tgaHeader.descriptor = 0;
//为大小字节存储顺序问题而进行字节交换
#ifdef __APPLE__
LITTLE_ENDIAN_WORD(&tgaHeader.colorMapStart);
LITTLE_ENDIAN_WORD(&tgaHeader.colorMapLength);
LITTLE_ENDIAN_WORD(&tgaHeader.xstart);
LITTLE_ENDIAN_WORD(&tgaHeader.ystart);
LITTLE_ENDIAN_WORD(&tgaHeader.width);
LITTLE_ENDIAN_WORD(&tgaHeader.height);
#endif
//尝试打开文件
pFile = fopen(szFileName, "wb");
if (pFile == NULL)
{
free(pBits); //释放缓冲区并返回错误
return 0;
}
//写入头文件
fwrite(&tgaHeader, sizeof(TGAHEADER), 1, pFile);
//写入图像数据
fwrite(pBits, lImageSize, 1, pFile);
//释放临时缓冲区并关闭文件
free(pBits);
fclose(pFile);
//成功!
return 1;
}
void KeyboardFunc(unsigned char key, int x, int y)
{
if (key == 32)
{
gltWriteTGA("hahaha");
}
}
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Test Read Write Pixel");
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "Error:%s\n", glewGetErrorString(err));
return 1;
}
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutKeyboardFunc(KeyboardFunc);
SetupRC();
glutMainLoop();
return 0;
}
【OpenGL】gltWriteTGA函数保存像素运用实例
猜你喜欢
转载自blog.csdn.net/qq_39574690/article/details/115221543
今日推荐
周排行