1

我目前正在阅读 Opengl 的优秀作品。我遇到了书中显示的一些源代码的问题。特别是该代码是用于截取当前场景的屏幕截图的代码。这是提供的代码:

GLint gltWriteTGA(const char *szFileName)  
{  
FILE *pFile;                // File pointer  
TGAHEADER tgaHeader;        // TGA file header  
unsigned long lImageSize;   // Size in bytes of image  
GLbyte  *pBits = NULL;      // Pointer to bits  
GLint iViewport[4];         // Viewport in pixels  
GLenum lastBuffer;          // Storage for the current read buffer setting  

// Get the viewport dimensions  
glGetIntegerv(GL_VIEWPORT, iViewport);  

// How big is the image going to be (targas are tightly packed)  
lImageSize = iViewport[2] * 3 * iViewport[3];     
// Allocate block. If this doesn't work, go home  
pBits = new GLbyte[lImageSize];
if(pBits == NULL)  
    return 0;  
// Read bits from color buffer  
glPixelStorei(GL_PACK_ALIGNMENT, 1);  
glPixelStorei(GL_PACK_ROW_LENGTH, 0);  
glPixelStorei(GL_PACK_SKIP_ROWS, 0);  
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

// Get the current read buffer setting and save it. Switch to  
// the front buffer and do the read operation. Finally, restore  
// the read buffer state   
glGetIntegerv(GL_READ_BUFFER, &lastBuffer);  
glReadBuffer(GL_FRONT);  
glReadPixels(0, 0, iViewport[2], iViewport[3], GL_BGR_EXT, GL_UNSIGNED_BYTE, pBits);  
glReadBuffer(lastBuffer);    

// Initialize the Targa header  
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;  

// Attempt to open the file  
pFile = fopen(szFileName, "wb");  
if(pFile == NULL)  
    {  
    free(pBits);    // Free buffer and return error  
    return 0;  
    }  

// Write the header  
fwrite(&tgaHeader, sizeof(TGAHEADER), 1, pFile);  

// Write the image data  
fwrite(pBits, lImageSize, 1, pFile);  

// Free temporary buffer and close the file  
free(pBits);      
fclose(pFile);  

// Success!  
return 1;  
}  

代码的问题在于它会输出一个大小正确的文件,但包含某种垃圾数据。它不会生成可打开的 .tga 文件。另一个问题是“glGetIntegerv”函数需要一个 GLint,但上面的源代码为它提供了一个 GLenum。

4

1 回答 1

0

当我用在互联网上找到的 TGA_Header 尝试它时,它首先失败了,因为 colorMapStart 和 colorMapLength 在它们应该是短裤时是字节。这是应该工作的修改代码:

struct TGA_Header
{
    GLbyte  identsize;
    GLbyte  colorMapType;
    GLbyte  imageType;
    // Color map specifications
    GLshort colorMapStart;
    GLshort colorMapLength;
    GLbyte colorMapBits;

    //image specification
    GLshort xstart;
    GLshort ystart;
    GLshort width;
    GLshort height;
    GLbyte  bits;
    GLbyte descriptor;
}__attribute__((packed));

GLint gltWriteTGA(const char *szFileName)
{
    FILE *pFile;                // File pointer
    struct TGA_Header tgaHeader;        // TGA file header
    unsigned long lImageSize;   // Size in bytes of image
    GLint iViewport[4];         // Viewport in pixels
    GLint lastBuffer;          // Storage for the current read buffer setting

    // Get the viewport dimensions
    glGetIntegerv(GL_VIEWPORT, iViewport);

    // How big is the image going to be (targas are tightly packed)
    lImageSize = iViewport[2] * 3 * iViewport[3];
    // Allocate block. If this doesn't work, go home
    GLbyte  pBits[lImageSize];
    if(pBits == NULL)
        return 0;
    // Read bits from color buffer
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
    glPixelStorei(GL_PACK_SKIP_ROWS, 0);
    glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

    // Get the current read buffer setting and save it. Switch to
    // the front buffer and do the read operation. Finally, restore
    // the read buffer state
    glGetIntegerv(GL_READ_BUFFER, &lastBuffer);
    glReadBuffer(GL_FRONT);
    glReadPixels(0, 0, iViewport[2], iViewport[3], GL_BGR_EXT, GL_UNSIGNED_BYTE, pBits);
    glReadBuffer(lastBuffer);

    // Initialize the Targa header
    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;

    // Attempt to open the file
    pFile = fopen(szFileName, "wb");
    if(pFile == NULL)
        {
        return 0;
        }

    // Write the header  
    fwrite(&tgaHeader, sizeof(tgaHeader), 1, pFile);

    // Write the image data
    fwrite(pBits, lImageSize, 1, pFile);

    fclose(pFile);

    // Success!
    return 1;
}
于 2013-05-02T09:40:36.820 回答