在GLSL中访问多个FBO纹理以创建另一个纹理

时间:2011-04-28 12:41:03

标签: opengl glsl textures fbo

我创建了4个纹理并将它们附加到FBO,名为fbo_texture0 - fbo_texture3。所有这些都已成功创建,如以下屏幕截图所示:

Textures in the FBO 图片1

现在,我想创建使用GLSL从先前纹理(fbo_texture0 - fbo_texture3)获得的第5个纹理。现在,我只想将第一个纹理复制到第五个纹理中。不幸的是,这就是我得到的:

texture fail image 2

问题是:

  1. 如何在GLSL中访问这些fbo纹理?
  2. 我如何创建第5个纹理? (或从第一个纹理复制到第五个纹理?)
  3. 这是程序的完整代码(如果需要):

        #include <windows.h>
    #include <GL/glew.h> // Include the GLEW header file
    #include <GL/glut.h> // Include the GLUT header file
    #include <iostream> // Allow us to print to the console
    
    using namespace std;
    
    bool* keyStates = new bool[256]; // Create an array of boolean values of length 256 (0-255)
    
    unsigned int fbo; // The frame buffer object
    unsigned int fbo_depth; // The depth buffer for the frame buffer object
    unsigned int fbo_texture0; // The texture object to write our frame buffer object to
    unsigned int fbo_texture1;
    unsigned int fbo_texture2;
    unsigned int fbo_texture3;
    unsigned int fbo_texture4;
    GLhandleARB shaderProgram;
    GLhandleARB vertexShader;
    GLhandleARB fragmentShader;
    
    int window_width = 500; // The width of our window
    int window_height = 500; // The height of our window
    
    void initFrameBufferDepthBuffer(void) {
        glGenRenderbuffers(1, &fbo_depth); // Generate one render buffer and store the ID in fbo_depth
        glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth); // Bind the fbo_depth render buffer
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, window_width, window_height); // Set the render buffer storage to be a depth component, with a width and height of the window
        glBindRenderbuffer(GL_RENDERBUFFER, 0); // Unbind the render buffer
    }
    
    void initFrameBufferTextures(void) {
        glGenTextures(1, &fbo_texture0); // Generate one ture
        glBindTexture(GL_TEXTURE_2D, fbo_texture0); // Bind the ture fbo_texture
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard ture with the width and height of our window
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glBindTexture(GL_TEXTURE_2D, 0);
    
    
        glGenTextures(1, &fbo_texture1); // Generate one ture
        glBindTexture(GL_TEXTURE_2D, fbo_texture1); // Bind the ture fbo_texture
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard ture with the width and height of our window
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glBindTexture(GL_TEXTURE_2D, 0);
    
        glGenTextures(1, &fbo_texture2); // Generate one ture
        glBindTexture(GL_TEXTURE_2D, fbo_texture2); // Bind the ture fbo_texture
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard ture with the width and height of our window
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glBindTexture(GL_TEXTURE_2D, 0);
    
    
        glGenTextures(1, &fbo_texture3); // Generate one ture
        glBindTexture(GL_TEXTURE_2D, fbo_texture3); // Bind the ture fbo_texture
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard ture with the width and height of our window
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glBindTexture(GL_TEXTURE_2D, 0);
    
        glGenTextures(1, &fbo_texture4); // Generate one ture
        glBindTexture(GL_TEXTURE_2D, fbo_texture4); // Bind the ture fbo_texture
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard ture with the width and height of our window
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glBindTexture(GL_TEXTURE_2D, 0);
    }
    
    void printInfoLog(GLhandleARB obj)
    {
        int infologLength = 0;
        int charsWritten  = 0;
        char* infoLog;
    
        glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength);
        if (infologLength > 0)
        {
            infoLog = (char*)malloc(infologLength);
            glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
            printf("%s\n",infoLog);
            free(infoLog);
        }
    }
    
    void initFrameBuffer(void) {
        initFrameBufferDepthBuffer(); // Initialize our frame buffer depth buffer
        initFrameBufferTextures(); // Initialize our frame buffer ture
        glGenFramebuffers(1, &fbo); // Generate one frame buffer and store the ID in fbo
        glBindFramebuffer(GL_FRAMEBUFFER, fbo); // Bind our frame buffer
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_texture0, 0);// Attach the ture fbo_texturen to the color buffer in our frame buffer
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, fbo_texture1, 0);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, fbo_texture2, 0); 
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, fbo_texture3, 0);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, fbo_texture4, 0);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth); // Attach the depth buffer fbo_depth to our frame buffer
            GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); // Check that status of our generated frame buffer
            if (status != GL_FRAMEBUFFER_COMPLETE) // If the frame buffer does not report back as complete
            {
                cout << "Couldn't create frame buffer" << endl; // Output an error to the console
                exit(0); // Exit the application
            }
        glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind our frame buffer
    }
    
    void init(void) {
        //glEnable(GL_TEXTURE_2D); // Enable turing so we can bind our frame buffer ture
        glEnable(GL_DEPTH_TEST); // Enable depth testing
        initFrameBuffer(); // Create our frame buffer object
    }
    
    void keyOperations (void) {
        if (keyStates['a']) { // If the a key has been pressed
            // Perform 'a' key operations
        }
    }
    
    void renderTextures(void) {
        glBindFramebuffer(GL_FRAMEBUFFER, fbo); // Bind our frame buffer for rendering
        glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states
        glViewport(0, 0, window_width, window_height); // Set the size of the frame buffer view port
    
        glDrawBuffer(GL_COLOR_ATTACHMENT0);
            glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set the clear colour
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear the depth and colour buffers
            glLoadIdentity();// Reset the modelview matrix
            glTranslatef(0.0f, 0.0f, -5.0f);
           //Add ambient light
            GLfloat ambientColor[] = {0.2f, 0.2f, 0.2f, 1.0f}; //Color(0.2, 0.2, 0.2)
            glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);
    
            //Add positioned light
            GLfloat lightColor0[] = {0.5f, 0.5f, 0.5f, 1.0f}; //Color (0.5, 0.5, 0.5)
            GLfloat lightPos0[] = {4.0f, 0.0f, 8.0f, 1.0f}; //Positioned at (4, 0, 8)
            glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
            glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
            //Add directed light
            GLfloat lightColor1[] = {0.5f, 0.2f, 0.2f, 1.0f}; //Color (0.5, 0.2, 0.2)
            //Coming from the direction (-1, 0.5, 0.5)
            GLfloat lightPos1[] = {-1.0f, 0.5f, 0.5f, 0.0f};
            glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1);
            glLightfv(GL_LIGHT1, GL_POSITION, lightPos1);
            glEnable(GL_LIGHTING);
            glEnable(GL_LIGHT0);
            glEnable(GL_LIGHT1);
            glEnable(GL_DEPTH_TEST);
    
            glutSolidTeapot(2.0);
            glColor3f(0.1,0.2,0.7);
    
        glDrawBuffer(GL_COLOR_ATTACHMENT1);
            glClearColor(0.5f, 0.5f, 0.0f, 1.0f); // Set the clear colour
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear the depth and colour buffers
            glLoadIdentity();// Reset the modelview matrix
            glTranslatef(0.0f, 0.0f, -5.0f);
            glutSolidTorus(0.80, 1.6, 50, 100);
            glColorMaterial ( GL_FRONT_AND_BACK, GL_EMISSION ) ;
            glEnable ( GL_COLOR_MATERIAL ) ;
    
        glDrawBuffer(GL_COLOR_ATTACHMENT2);
            glClearColor(0.5f, 0.0f, 0.0f, 1.0f); // Set the clear colour
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear the depth and colour buffers
            glLoadIdentity();// Reset the modelview matrix
            glTranslatef(0.0f, 0.0f, -2.0f);
            glutSolidTetrahedron();
            glColorMaterial ( GL_FRONT_AND_BACK, GL_EMISSION ) ;
            glEnable ( GL_COLOR_MATERIAL ) ;
    
        glDrawBuffer(GL_COLOR_ATTACHMENT3);
            glClearColor(0.5f, 0.0f, 0.3f, 1.0f); // Set the clear colour
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear the depth and colour buffers
            glLoadIdentity();// Reset the modelview matrix
            glTranslatef(0.0f, 0.0f, -2.0f);
            glutSolidOctahedron();
            glColorMaterial ( GL_FRONT_AND_BACK, GL_EMISSION ) ;
            glEnable ( GL_COLOR_MATERIAL ) ;
    
        glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind our ture
    
        glActiveTexture(GL_TEXTURE0);
        //glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, fbo_texture0);
        glUniform1i(glGetUniformLocation(shaderProgram, "tex0"), 0);
    
        glActiveTexture(GL_TEXTURE1);
        //glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, fbo_texture1);
        glUniform1i(glGetUniformLocation(shaderProgram, "tex1"), 1);
    
        glActiveTexture(GL_TEXTURE2);
        //glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, fbo_texture2);
        glUniform1i(glGetUniformLocation(shaderProgram, "tex2"), 2);
    
        glActiveTexture(GL_TEXTURE3);
        //glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, fbo_texture3);
        glUniform1i(glGetUniformLocation(shaderProgram, "tex3"), 3);
    
    glPopAttrib(); // Restore our glEnable and glViewport states
    glutSwapBuffers();
    }
    
    static char* textFileRead(const char *fileName) {
        char* text;
    
        if (fileName != NULL) {
            FILE *file = fopen(fileName, "rt");
    
            if (file != NULL) {
                fseek(file, 0, SEEK_END);
                int count = ftell(file);
                rewind(file);
    
                if (count > 0) {
                    text = (char*)malloc(sizeof(char) * (count + 1));
                    count = fread(text, sizeof(char), count, file);
                    text[count] = '\0';
                }
                fclose(file);
            }
        }
        return text;
    }
    
    void initShader(){
        char* vsSource = textFileRead("./shader/multitexture.vs");
        char* fsSource = textFileRead("./shader/multitexture.fs");
    
        printf("%s\n",fsSource);
    
        vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, (const GLchar **)(&vsSource), NULL);
        glCompileShader(vertexShader);
        printInfoLog(vertexShader);
    
        fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, (const GLchar **)(&fsSource), NULL);
        glCompileShader(fragmentShader);
        printInfoLog(fragmentShader);
    
        delete [] vsSource;
        delete [] fsSource;
    
        shaderProgram = glCreateProgram();
    
        glAttachShader(shaderProgram, vertexShader);
        glAttachShader(shaderProgram, fragmentShader);
        glLinkProgram(shaderProgram);
    }
    
    
    
    void display (void) {
        keyOperations(); // Perform any key presses
                glUseProgram(0);
        renderTextures(); // Render our teapot scene into our frame buffer
                GLsync s = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
                glUseProgram(shaderProgram);
        glClearColor(0.0f, 1.0f, 0.0f, 1.0f); // Clear the background of our window to red
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the colour buffer (more buffers later on)
        glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
        glTranslatef(-4.7f, 1.0f, -4.0f);
    
        glWaitSync(s, 0, GL_TIMEOUT_IGNORED); 
            glDeleteSync(s);
        glBindTexture(GL_TEXTURE_2D, fbo_texture0); // Bind our frame buffer ture
        glBegin(GL_QUADS);
            glColor4f(1, 1, 1, 1);
            glTexCoord2f(0.0f, 0.0f);
            glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
            glTexCoord2f(0.0f, 1.0f);
            glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
            glTexCoord2f(1.0f, 1.0f);
            glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
            glTexCoord2f(1.0f, 0.0f);
            glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
        glEnd();
        glBindTexture(GL_TEXTURE_2D, 0); // Unbind any tures
    
        glLoadIdentity();
        glTranslatef(-2.5f, 1.0f, -4.0f);
    
        glBindTexture(GL_TEXTURE_2D, fbo_texture1); // Bind our frame buffer ture
            glBegin(GL_QUADS);
                glColor4f(1, 1, 1, 1);
                glTexCoord2f(0.0f, 0.0f);
                glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
                glTexCoord2f(0.0f, 1.0f);
                glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
                glTexCoord2f(1.0f, 1.0f);
                glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
                glTexCoord2f(1.0f, 0.0f);
                glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
            glEnd();
        glBindTexture(GL_TEXTURE_2D, 0); // Unbind any tures
    
        glLoadIdentity();
        glTranslatef(-0.3f, 1.0f, -4.0f);
    
        glBindTexture(GL_TEXTURE_2D, fbo_texture2); // Bind our frame buffer ture
        glBegin(GL_QUADS);
            glColor4f(1, 1, 1, 1);
            glTexCoord2f(0.0f, 0.0f);
            glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
            glTexCoord2f(0.0f, 1.0f);
            glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
            glTexCoord2f(1.0f, 1.0f);
            glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
            glTexCoord2f(1.0f, 0.0f);
            glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
        glEnd();
        glBindTexture(GL_TEXTURE_2D, 0); // Unbind any tures
    
        glLoadIdentity();
        glTranslatef(1.9f, 1.0f, -4.0f);
    
        glBindTexture(GL_TEXTURE_2D, fbo_texture3); // Bind our frame buffer ture
        glBegin(GL_QUADS);
            glColor4f(1, 1, 1, 1);
            glTexCoord2f(0.0f, 0.0f);
            glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
            glTexCoord2f(0.0f, 1.0f);
            glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
            glTexCoord2f(1.0f, 1.0f);
            glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
            glTexCoord2f(1.0f, 0.0f);
            glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
        glEnd();
        glBindTexture(GL_TEXTURE_2D, 0); // Unbind any tures
    
        glLoadIdentity();
        glTranslatef(4.1f, 1.0f, -4.0f);
    
        glBindTexture(GL_TEXTURE_2D, fbo_texture4); // Bind our frame buffer ture
        glBegin(GL_QUADS);
            glColor4f(1, 1, 1, 1);
            glTexCoord2f(0.0f, 0.0f);
            glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
            glTexCoord2f(0.0f, 1.0f);
            glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
            glTexCoord2f(1.0f, 1.0f);
            glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
            glTexCoord2f(1.0f, 0.0f);
            glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
        glEnd();
        glBindTexture(GL_TEXTURE_2D, 0); // Unbind any tures
    
        glutSwapBuffers();
    }
    
    void reshape (int width, int height) {
        glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window
        glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed
        glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up)
        gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes
        glMatrixMode(GL_MODELVIEW); // Switch back to the model view matrix, so that we can start drawing shapes correctly
    }
    
    void keyPressed (unsigned char key, int x, int y) {
        keyStates[key] = true; // Set the state of the current key to pressed
    }
    
    void keyUp (unsigned char key, int x, int y) {
        keyStates[key] = false; // Set the state of the current key to not pressed
    }
    
    int main (int argc, char **argv) {
        glutInit(&argc, argv); // Initialize GLUT
        glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA); // Set up a basic display buffer (only single buffered for now)
        glutInitWindowSize (1280, 500); // Set the width and height of the window
        glutInitWindowPosition (100, 100); // Set the position of the window
        glutCreateWindow ("OpenGL FBO"); // Set the title for the window
    
        if (GLEW_OK != glewInit()) {
            std::cout << "Couldn't initialize GLEW" << std::endl;
            exit(0);
        }
        initShader();
        init();
    
        glutDisplayFunc(display); // Tell GLUT to use the method "display" for rendering
        glutIdleFunc(display); // Tell GLUT to use the method "display" for rendering
        glutReshapeFunc(reshape); // Tell GLUT to use the method "reshape" for reshaping
        glutKeyboardFunc(keyPressed); // Tell GLUT to use the method "keyPressed" for key presses
        glutKeyboardUpFunc(keyUp); // Tell GLUT to use the method "keyUp" for key up events
        glutMainLoop(); // Enter GLUT's main loop
    }
    

    这是顶点着色器:

    void main(void) 
    { 
        gl_TexCoord[0] = gl_MultiTexCoord0;
        gl_Position = ftransform();
    }
    

    这是片段着色器:

    uniform sampler2D tex0;
    uniform sampler2D tex1;
    uniform sampler2D tex2;
    uniform sampler2D tex3;
    
    void main(void) 
    { 
        gl_FragColor = texture2D(tex0, gl_TexCoord[0].st);
    }
    

    编辑#1

    根据@Damon的建议修改代码(代码也已经编辑过),这里是结果的截图:

    enter image description here image 3

    现在,我真的不知道问题究竟是什么。我试图更改片段着色器以访问另一个纹理,例如gl_FragColor = texture2D(tex2, gl_TexCoord[0].st);但我仍然得到与上面相同的显示。所以我认为这绝对不是模型视图/投影问题。

    编辑#2

    问题仍然不明朗。但是,我试图在程序中只给出一个glActiveTexture(GL_TEXTUREn);命令,并注释掉其他glActiveTexture命令(没有着色器修改),并得到以下结果:

    enter image description here image 4 仅激活了glActiveTexture(GL_TEXTURE0);

    enter image description here image 5 仅激活glActiveTexture(GL_TEXTURE1);

    enter image description here image 6 仅激活glActiveTexture(GL_TEXTURE2);

    enter image description here image 7 仅激活glActiveTexture(GL_TEXTURE3);

    当激活至少2 glActiveTexture(GL_TEXTUREn);时,我得到的结果与 image 5 相同。这让我想知道问题究竟是什么。

1 个答案:

答案 0 :(得分:3)

initShader编译并链接着色器。您似乎也以一种正常的方式将纹理绑定到renderTextures中的纹理单元(解除FBO绑定后,这对于同步非常重要)。到目前为止一直很好,但我在代码中的任何地方都找不到glUseProgram。这意味着渲染会回落到固定函数,当时没有任何纹理绑定。

片段着色器只能从tex0读取,所以当然你不会期望看到tex1-tex3(但我想这只是最小的工作示例代码)。

除此之外,通过在5分钟内阅读代码,我可以看到它看起来不错。

(作为旁注:init调用glEnable(GL_TEXTURE_2D),这并非严格错误,但只要您使用着色器就无用,请参阅this。)