我想使用opengl子窗口显示两个不同的三角形,但只有后一个显示

时间:2014-10-17 14:12:51

标签: opengl

我想使用opengl子窗口在一个窗口中显示两个不同的三角形。但它只显示后者。如果我调整创建子窗口的顺序,后一个将始终显示,第二个创建的子窗口将不会显示。

enter image description here

如果我评论第二个,第一个将显示。请帮助我,谢谢。

enter image description here

main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/freeglut.h>

void mainDisplay();
void view1TriangleDisplay();
void view2TriangleDisplay();

// TODO: reshape
int initWindow(int argc, char *argv[])
{
    glutInit(&argc, argv);
    // TODO: glutInitContextVersion(3, 0);
    glutInitDisplayMode(GLUT_RGBA | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH);

    // glutInitWindowSize(640, 480);
    glutInitWindowSize(512, 512);
    GLuint window = glutCreateWindow("simple");
    glutDisplayFunc(mainDisplay);

    GLuint view1_triangle = glutCreateSubWindow(window, 0, 0, 256, 256);
    glutDisplayFunc(view1TriangleDisplay);

    GLuint view2_triangle = glutCreateSubWindow(window, 256, 0, 256, 256);
    glutDisplayFunc(view2TriangleDisplay);

    if (glewInit() != GLEW_OK){
        return 1;
    }

    return 0;
}

GLuint view1_program = 0, view2_program = 0;
char *load_file(const char * path)
{
    FILE *file_handler = fopen(path, "r");
    if (file_handler == NULL){
        return NULL;
    }

    if (fseek(file_handler, 0, SEEK_END) == -1){
        return NULL;
    }

    long size = ftell(file_handler);
    if (size == -1){
        return NULL;
    }

    if (fseek(file_handler, 0, SEEK_SET) == -1){
        return NULL;
    }

    char *content = (char *)malloc(size * sizeof(char) + 1);
    if (content == NULL){
        return NULL;
    }

    fread(content, 1, (size_t)size, file_handler);

    if (ferror(file_handler)){
        free(content);
        fclose(file_handler);
        return NULL;
    }

    fclose(file_handler);
    content[size] = '\0';
    // printf ("path : %s, size : %ld, content : %s\n", path, size, content);

    return content;
}

void printLog(GLuint object)
{
    char *logBuffer = NULL;
    GLint logLength;
    if (glIsShader(object)){
        glGetShaderiv(object, GL_INFO_LOG_LENGTH, &logLength);
        logBuffer = (char *)malloc(sizeof(char) * logLength);
        glGetShaderInfoLog(object, logLength, NULL, logBuffer);
    } else if (glIsProgram(object)){
        glGetProgramiv(object, GL_INFO_LOG_LENGTH, &logLength);
        logBuffer = (char *)malloc(sizeof(char) * logLength);
        glGetProgramInfoLog(object, logLength, NULL, logBuffer);
    } else {
        return;
    }

    fprintf(stderr, "%s", logBuffer);
    free(logBuffer);
}

GLint get_attrib(GLuint program, const char *attribute_name)
{
    GLint attribute = glGetAttribLocation(program, attribute_name);
    if (attribute == -1){
        fprintf(stderr, "glGetAttribLocation attribute_name %s failed\n", attribute_name);
        return -1;
    }

    return attribute;
}

GLint view1_attribute_coord2d, view2_attribute_coord2d;

GLuint create_shader(const char *path, GLenum type)
{
    GLuint shader = glCreateShader(type);
    char *shader_src = load_file(path);
    if (shader_src == NULL){
        return 0;
    }

    char *sources[2] = {
        (char *)"#version 130\n",
        shader_src
    };

    glShaderSource(shader, 2, (const char **)&sources, NULL);
    free(shader_src);
    glCompileShader(shader);

    GLint status = GL_FALSE;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);

    if (status == 0){
        fprintf(stderr, "compile shader failed\n");
        printLog(shader);
        return 0;
    }

    return shader;
}


GLuint create_program(const char *vertex_path, const char *fragment_path)
{
    GLint status = GL_FALSE;
    // create program
    GLuint program = glCreateProgram();
    GLuint shader = 0;
    if (vertex_path != NULL){
        // create vertex shader
        if ((shader = create_shader(vertex_path, GL_VERTEX_SHADER)) == -1){
            return -1;
        }
        glAttachShader(program, shader);
    }

    if (fragment_path != NULL){
        // create fragment shader
        if ((shader = create_shader(fragment_path, GL_FRAGMENT_SHADER)) == -1){
            return -1;
        }
        glAttachShader(program, shader);
    }

    glLinkProgram(program);
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status == 0){
        fprintf(stderr, "link shader failed");
        printLog(program);
        return -1;
    }

    return program;
}

int initResources()
{
    view1_program = create_program("triangle.1.v.glsl", "triangle.1.f.glsl");
    view1_attribute_coord2d = get_attrib(view1_program, "coord2d");

    view2_program = create_program("triangle.2.v.glsl", "triangle.2.f.glsl");
    view2_attribute_coord2d = get_attrib(view2_program, "coord2d");

    return 0;
}

void freeResources()
{
    // TODO: no need to free content?
    if (view1_program != -1){
        glDeleteProgram(view1_program);
    }

    if (view2_program != -1){
        glDeleteProgram(view2_program);
    }

    // NOTE: let the os handle shader
    // if (triangle_vertex_shader != 0){
    //     glDeleteShader(triangle_vertex_shader);
    // }

    // if (triangle_fragment_shader != 0){
    //     glDeleteShader(triangle_fragment_shader);
    // }
}

void mainDisplay()
{
    glClearColor(1.0, 1.0, 1.0, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    glutSwapBuffers();
}

void view1TriangleDisplay()
{
    glClearColor(1.0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(view1_program);
    glEnableVertexAttribArray(view1_attribute_coord2d);

    // attach attribute
    GLfloat triangle_vertices[6] = {
        0.0,  0.8,
        -0.8, -0.8,
        0.8, -0.8
    };

    glVertexAttribPointer(view1_attribute_coord2d, 2, GL_FLOAT,
                          GL_FALSE, 0, triangle_vertices);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    glDisableVertexAttribArray(view1_attribute_coord2d);

    glutSwapBuffers();
}

void view2TriangleDisplay()
{
    glClearColor(0, 1.0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glUseProgram(view2_program);
    glEnableVertexAttribArray(view2_attribute_coord2d);

    // attach attribute
    GLfloat triangle_vertices[6] = {
        0.0,  0.8,
        -0.8, -0.8,
        0.8, -0.8
    };

    glVertexAttribPointer(view2_attribute_coord2d, 2, GL_FLOAT,
                          GL_FALSE, 0, triangle_vertices);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    glDisableVertexAttribArray(view2_attribute_coord2d);

    glutSwapBuffers();
}

int main(int argc, char *argv[])
{
    if (initWindow(argc, argv) != 0){
        return 0;
    }

    if (initResources() == 0){
        // glutDisplayFunc(onDisplay);
        glutMainLoop();
    }

    freeResources();

    return 0;
}

triangle.1.v.glsl

attribute vec2 coord2d;

void main()
{
    gl_Position = vec4(coord2d, 0.0, 1.0);
}

triangle.1.f.glsl

void main()
{
    gl_FragColor[0] = 0.0;
    gl_FragColor[1] = 0.0;
    gl_FragColor[2] = 1.0;
    // gl_FragColor[3] = 0.4;
}

triangle.2.v.glsl

attribute vec2 coord2d;

void main()
{
    gl_Position = vec4(coord2d, 0.0, 1.0);
}

triangle.2.f.glsl

void main()
{
    gl_FragColor[0] = gl_FragCoord.x/256;
    gl_FragColor[1] = gl_FragCoord.y/256;
    gl_FragColor[2] = 0.5;

    if (mod(gl_FragCoord.y, 30.0) > 15){
        gl_FragColor[3] = 1;
    } else {
        gl_FragColor[3] = 0.4;
    }
}

0 个答案:

没有答案