把OpenGL场景保存成bmp图片

文件名: 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;
}

//=============================================================================



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值