文件名: bmp.h //bmp图片格式描述
//=====================================================================
typedef struct tagBITMAPFILEHEADER {
unsigned char bfType[2];
unsigned char bfSize[4];
unsigned char bfReserved1[2];
unsigned char bfReserved2[2];
unsigned char bfOffBits[4];
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
unsigned char biSize[4];
unsigned char biWidth[4];
unsigned char biHeight[4];
unsigned char biPlanes[2];
unsigned char biBitCount[2];
unsigned char biCompression[4];
unsigned char biSizeImage[4];
unsigned char biXPelsPerMeter[4];
unsigned char biYPelsPerMeter[4];
unsigned char biClrUsed[4];
unsigned char biClrImportant[4];
} BITMAPINFOHEADER;
找一个OpenGL官方的例子(surface.c),稍加修改就可以实现把场景打印为bmp图片
全部的代码:
//=====================================================================
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include "bmp.h"
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
GLfloat ctlpoints[4][4][3];
GLUnurbsObj *theNurb;
//=====================================================================
void LongToByte(unsigned long value,unsigned char * outResult){
int i=0;
for(i=0;i<4;i++){
outResult[i] = (unsigned char)(value%16);
value = value/16;
outResult[i] += (unsigned char)(value%16)*16;
value = value/16;
}
outResult[4] = '\0';
}
//=====================================================================
/*
* Initializes the control points of the surface to a small hill.
* The control points range from -3 to +3 in x, y, and z
*/
void init_surface(void) {
int u, v;
for (u = 0; u < 4; u++) {
for (v = 0; v < 4; v++) {
ctlpoints[u][v][0] = 2.0 * ((GLfloat) u - 1.5);
ctlpoints[u][v][1] = 2.0 * ((GLfloat) v - 1.5);
if ((u == 1 || u == 2) && (v == 1 || v == 2))
ctlpoints[u][v][2] = 3.0;
else
ctlpoints[u][v][2] = -3.0;
}
}
}
void nurbsError(GLenum errorCode) {
const GLubyte *estring;
estring = gluErrorString(errorCode);
fprintf(stderr, "Nurbs Error: %s\n", estring);
exit(0);
}
/* Initialize material property and depth buffer.
*/
void init(void) {
GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 100.0 };
glClearColor(0.0, 0.0, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
init_surface();
theNurb = gluNewNurbsRenderer();
gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0);
gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
gluNurbsCallback(theNurb, GLU_ERROR, nurbsError);
}
void display(void) {
GLfloat knots[8] = { 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 };
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(330.0, 1., 0., 0.);
glScalef(0.5, 0.5, 0.5);
gluBeginSurface(theNurb);
gluNurbsSurface(theNurb, 8, knots, 8, knots, 4 * 3, 3, &ctlpoints[0][0][0],
4, 4, GL_MAP2_VERTEX_3);
gluEndSurface(theNurb);
glPopMatrix();
glFlush();
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLdouble) w / (GLdouble) h, 3.0, 8.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
}
void keyboard(unsigned char key, int x, int y) {
GLint viewPort[4] = { 0 };
switch (key) {
case 'c':
case 'C':
glGetIntegerv(GL_VIEWPORT, viewPort);
GLbyte * buffer =
malloc(viewPort[2] * viewPort[3] * sizeof(GLbyte) * 3);
glReadPixels(viewPort[0], viewPort[1], viewPort[2], viewPort[3],
GL_BGR, GL_UNSIGNED_BYTE, buffer);
long fileSize = viewPort[2] * viewPort[3] * 3 + 54;
//int i=0;
fileHeader.bfType[0] = 0x42;
fileHeader.bfType[1] = 0x4d;
LongToByte(fileSize, fileHeader.bfSize);
LongToByte(54, fileHeader.bfOffBits);
LongToByte(sizeof(infoHeader), infoHeader.biSize);
LongToByte(viewPort[2], infoHeader.biWidth);
LongToByte(viewPort[3], infoHeader.biHeight);
infoHeader.biPlanes[0] = 0x01;
infoHeader.biPlanes[1] = 0x00;
infoHeader.biBitCount[0] = 0x18;
infoHeader.biBitCount[1] = 0x00;
LongToByte(0, infoHeader.biCompression);
LongToByte((viewPort[2] * viewPort[3]), infoHeader.biSizeImage);
FILE * fp = fopen("aaa.bmp", "w+");
fwrite(&fileHeader, sizeof(fileHeader), 1, fp);
fwrite(&infoHeader, sizeof(infoHeader), 1, fp);
fwrite(buffer, 1, (viewPort[2] * viewPort[3] * 3), fp);
fclose(fp);
free(buffer);
break;
case 27:
exit(0);
break;
default:
break;
}
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
//=============================================================================