Frambuffer对象的问题 - 与我的屏幕分辨率相关的限制

时间:2015-08-03 14:59:12

标签: opengl glew freeglut fbo

我需要有一个图像作为我的代码(尺寸:3507x3281)的输出,由两个三角形(左上角和右下角)组成,每个三角形将在我的输出上给出一个不同的颜色/图像。

我读取了两个图像并用2个纹理(texture_1和texture_2)绑定它们。 之后我创建了与其各自图像相关的两个三角形。 我创建并绑定了Framebuffer对象并附加了纹理。最后,我将内容保存到图像文件(.ppm)。

问题:

  

我的结果(输出图像)是连贯的,几何上是正确的。但是,只有部分输出图像可见。它可见的部分有1366x768作为尺寸,这是我的屏幕分辨率。我在代码上遗漏了什么吗?

     

是否有与选项相关的内容" GL_DRAW_FRAMEBUFFER,GL_READ_FRAMEBUFFER和GL_FRAMEBUFFER"?只有" GL_DRAW_FRAMEBUFFER"给出连贯的结果。

     

我真的使用Framebuffer吗?因为,我读到,因为你使用FBO这种问题不会出现。

CODE:

#include <windows.h>
#define  GLEW_STATIC

#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/freeglut.h>

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <cstdio>
#include <string>

/// Definitions
#define checkImageWidth    500 /// for image - texture 1
#define checkImageHeight   500
#define width   2464           /// for image - texture 2
#define height  1648

static  GLuint texture_1, texture_2;
static  GLubyte checkImage[checkImageHeight][checkImageWidth][3];
GLuint  fb = 1; ///Frame-buffer Object

/// Headers
GLuint  raw_texture_load();
void    FBO_2_PPM_file(int output_width, int output_height);

/// Functions
GLuint raw_texture_load()
{
    /// image used for texture 1
    unsigned char *data;
    FILE *file;

    // open texture data
    file = fopen("C:\\Dataset\\image_1.raw", "rb");
    if (file == NULL) return 0;

    // allocate buffer
    data = (unsigned char*) malloc(width * height * 3);

    // read texture data
    fread(data, width * height * 3, 1, file);
    fclose(file);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    /// Texture 1
    // allocate a texture name
    glGenTextures(1, &texture_1);
    // select our current texture
    glBindTexture(GL_TEXTURE_2D, texture_1);
    // select modulate to mix texture with color for shading
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_DECAL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_DECAL);
    // when texture area is small, bilinear filter the closest mipmap
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    // when texture area is large, bilinear filter the first mipmap
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // texture should tile
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    // build our texture mipmaps
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
    // free buffer
    free(data);

    /// image used for texture 2
    FILE *image_4tx2;
    if( (image_4tx2 = fopen("C:\\dataset\\image2.ppm","r")) == NULL )
    {
        printf("\n Problem with input for texture 2\n");
        system("pause");
        exit(1);
    }

    int i, j, max_ND, n_col, n_lin, Red, G, B;
    char s1[20];

    /// Read header
    fscanf(image_4tx2,"%s",&s1);
    fscanf(image_4tx2,"%s %s %s %s",&s1, &s1, &s1, &s1);
    fscanf(image_4tx2,"%d %d",&n_col, &n_lin);
    fscanf(image_4tx2,"%d",&max_ND);

    for (i = 0; i < checkImageWidth; i++)
    {
        for (j = 0; j < checkImageHeight; j++)
        {
            fscanf(image_4tx2,"%d %d %d ",&Red, &G, &B);
            checkImage[i][j][0] = (GLubyte) Red;
            checkImage[i][j][1] = (GLubyte) G;
            checkImage[i][j][2] = (GLubyte) B;
        }
    }
    fclose(image_4tx2);

    /// Texture 2
    glGenTextures(2, &texture_2);
    glBindTexture(GL_TEXTURE_2D, texture_2);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, checkImageWidth, checkImageHeight,
                 0, GL_RGB, GL_UNSIGNED_BYTE, checkImage);

    return texture_1;
}

void render()
{
    GLdouble    COORD_1[3], COORD_2[3], COORD_3[3], COORD[3];

    /// Output image size
    double col_siz_double = 3507.0;
    double row_siz_double = 3281.0;

    int col_siz_output_image = 3507;
    int row_siz_output_image = 3281;

    /// Aspect ratio
    double ratio_col_row = col_siz_double/row_siz_double;

    double aspect_E, aspect_N;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    if(ratio_col_row>=0.0)
    {
        aspect_E = 1.0;
        aspect_N = 1.0/ratio_col_row;
        glOrtho(0.0, 1.0*aspect_E, 0.0, 1.0*aspect_N, 0.0, 1.0);
    }
    else
    {
        aspect_E = 1.0/ratio_col_row;
        aspect_N = 1.0;
       glOrtho(0.0, 1.0*aspect_E, 0.0, 1.0*aspect_N, 0.0, 1.0);
    }

    gluLookAt(  0.0, 0.0, 1.0,  /* eye    */
                0.0, 0.0, 0.0,  /* center */
                0, 1, 0);       /* up     */

    /// Viewport
    glViewport(0,0,col_siz_output_image,row_siz_output_image);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

    /// Triangle 1 (upper-left half of the output)
    glBindTexture(GL_TEXTURE_2D, texture_1);

    glBegin(GL_TRIANGLES);
        glTexCoord2d(0.0, 0.0);
                    COORD[0]= 0.0*aspect_E;
                    COORD[1]= 0.0*aspect_N;
                    COORD[2]= 1.0;
        glVertex3d(COORD[0], COORD[1], COORD[2]);

        glTexCoord2d(1.0, 1.0);
                    COORD[0]= 1.0*aspect_E;
                    COORD[1]= 1.0*aspect_N;
                    COORD[2]= 1.0;
        glVertex3d(COORD[0], COORD[1], COORD[2]);

        glTexCoord2d(0.0, 1.0);
                    COORD[0]= 0.0*aspect_E;
                    COORD[1]= 1.0*aspect_N;
                    COORD[2]= 1.0;
        glVertex3d(COORD[0], COORD[1], COORD[2]);
    glEnd();

    /// Triangle 2 (low-right half of the output)
    glBindTexture(GL_TEXTURE_2D, texture_2);

    glBegin(GL_TRIANGLES);
        glTexCoord2d(0.0, 0.0);
                    COORD[0]= 0.0*aspect_E;
                    COORD[1]= 0.0*aspect_N;
                    COORD[2]= 1.0;
        glVertex3d(COORD[0], COORD[1], COORD[2]);

        glTexCoord2d(1.0, 1.0);
                    COORD[0]= 1.0*aspect_E;
                    COORD[1]= 1.0*aspect_N;
                    COORD[2]= 1.0;
        glVertex3d(COORD[0], COORD[1], COORD[2]);

        glTexCoord2d(1.0, 0.0);
                    COORD[0]= 1.0*aspect_E;
                    COORD[1]= 0.0*aspect_N;
                    COORD[2]= 1.0;
        glVertex3d(COORD[0], COORD[1], COORD[2]);
    glEnd();

    glFlush();
    glDisable(GL_TEXTURE_2D);

    static const GLenum draw_buffers[] =
    {
        GL_COLOR_ATTACHMENT0,
        GL_COLOR_ATTACHMENT1
    };

    /// Generating and Biding the Framebuffer Object (FBO)
    glGenFramebuffers(1, &fb);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);

    ///Attaching both 2D texture to the FBO as color attachments
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, draw_buffers[0], GL_TEXTURE_2D, texture_2, 0);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, draw_buffers[1], GL_TEXTURE_2D, texture_1, 0);

    /// Specifying a list of color buffers to be drawn into
    glDrawBuffers(2, draw_buffers);

    /// Checking the FBO status
    GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if( status != GL_FRAMEBUFFER_COMPLETE)
    {
        printf("\n\nFramebuffer status: %s\n\n",status);
        system("pause");
    }

    /// Saving the results from the FBO (fb) to a PPM image file
    FBO_2_PPM_file(col_siz_output_image,row_siz_output_image);
 }

void init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);

    texture_1 = raw_texture_load();

    render();
}

void FBO_2_PPM_file(int output_width, int output_height)
{
    FILE    *output_image;

    /// READ THE PIXELS VALUES from FBO AND SAVE TO A .PPM FILE
    int             i, j, k;
    unsigned char   *pixels = (unsigned char*)malloc(output_width*output_height*4);

    /// READ THE CONTENT FROM THE FBO
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    glReadBuffer(GL_COLOR_ATTACHMENT1);

    glReadPixels(0, 0, output_width, output_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

    output_image = fopen("C:\\Dataset\\output.ppm", "wt");
    if(output_image == NULL)
    {
        printf("Problem @ output file!\n\n");
        system("pause");
    }
    fprintf(output_image,"P3\n");
    fprintf(output_image,"# Created by Ricao\n");
    fprintf(output_image,"%d %d\n",output_width,output_height);
    fprintf(output_image,"255\n");

    k = 0;
    for(i=output_height-1; i>-1; i--)
    {
        for(j=0; j<output_width; j++)
        {
            k = (i*output_width)+j;
            /// saving only RGB
            fprintf(output_image,"%u %u %u ",(unsigned int)pixels[4*k],(unsigned int)pixels[(4*k)+1],
                                             (unsigned int)pixels[(4*k)+2]);
        }
        fprintf(output_image,"\n");
    }
    free(pixels);
}

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(3507, 3281);
    glutCreateWindow("Do not close this window!");
    glutHideWindow();

    /// Checking GLEW library
    glewExperimental=TRUE;
    GLenum err=glewInit();

    if(err!=GLEW_OK)
    {
        printf("glewInit failed, aborting.");
        printf("\tError: %s\n\n",glewGetErrorString(err));
        system("pause");
    }

    if (GLEW_EXT_framebuffer_object != GL_TRUE)
    {
        printf("\n\n\t ** Error! GLEW_EXT_framebuffer_object != GL_TRUE \n\n");
        system("pause");
    }

    /// To check the max size of the Framebuffer
    int dims[2];
    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &dims[0]);

    ///Executing the rendering process
    init();

    return 0;

0 个答案:

没有答案