Java OpenGL屏幕大小的纹理映射四边形

| 我有一个Java OpenGL(JOGL)应用程序,我正在尝试创建一个覆盖整个屏幕的纹理映射的四边形。在绘制一些像素到缓冲区后,我想将这些像素读入纹理并在屏幕上重画它们(应用片段着色器)。我将纹理映射到视口的代码是:
        gl.glMatrixMode(GL.GL_PROJECTION);                                        
        gl.glPushMatrix();                                                 
        gl.glLoadIdentity();                                               
        gl.glOrtho( 0, width, height, 0, -1, 1 );                          
        gl.glMatrixMode(GL.GL_MODELVIEW);                                  
        gl.glPushMatrix();                                                 
        gl.glLoadIdentity();
        IntBuffer ib = IntBuffer.allocate(1);
        gl.glEnable(GL.GL_TEXTURE_2D);
        gl.glGenTextures(1, ib);
        gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
        //buff contains pixels read from glReadPixels
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buff);
        gl.glBindTexture(GL.GL_TEXTURE_2D, ib.get(0));
        gl.glBegin(GL.GL_QUADS);
        gl.glTexCoord2f(0,1);
        gl.glVertex2f(0,0); 
        gl.glTexCoord2f(0,0);
        gl.glVertex2f(0,height);
        gl.glTexCoord2f(1,0);   
        gl.glVertex2f(width,height);
        gl.glTexCoord2f(1,1);      
        gl.glVertex2f(width,0);
        gl.glEnd();
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
        gl.glPopMatrix();
        gl.glPopMatrix();
最终结果是一个四边形没有覆盖整个视口(部分打开),并且不包含缓冲区中的像素。我在这里做错了什么? 谢谢, 杰夫     
已邀请:
        首先,您只应在初始化代码中创建纹理。您不应该每帧都调用glTexImage2D。如果纹理的大小更改,则仅再次调用glTexImage2D;否则,将重新调用。 glTexSubImage2D可用于将数据上传到纹理。将glTexImage2D视为\“ new \”,而将glTexSubImage2D视为内存副本。 在初始化OpenGL之后执行一次。
IntBuffer ib = IntBuffer.allocate(1);  //Store this in your object
gl.glGenTextures(1, ib);
gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
//buff contains pixels read from glReadPixels
gl.glBindTexture(GL.GL_TEXTURE_2D, ib.get(0));
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, 0);
gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
然后,在每个框架中执行以下操作:
gl.glMatrixMode(GL.GL_PROJECTION);                                        
gl.glPushMatrix();                                                 
gl.glLoadIdentity();                                               
gl.glMatrixMode(GL.GL_MODELVIEW);                                  
gl.glPushMatrix();                                                 
gl.glLoadIdentity();

gl.glBindTexture(GL.GL_TEXTURE_2D, ib.get(0));  //Retrieved from your object
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buff);

gl.glBegin(GL.GL_QUADS);
    gl.glTexCoord2f(0,1);
    gl.glVertex2f(-1, -1); 
    gl.glTexCoord2f(0, 0);
    gl.glVertex2f(-1, 1);
    gl.glTexCoord2f(1, 0);   
    gl.glVertex2f(1, 1);
    gl.glTexCoord2f(1, 1);      
    gl.glVertex2f(1, -1);
gl.glEnd();

gl.glMatrixMode(GL.GL_MODELVIEW);                                  
gl.glPopMatrix();   
gl.glMatrixMode(GL.GL_PROJECTION);                                        
gl.glPopMatrix();   
gl.glMatrixMode(GL.GL_MODELVIEW);                                  
通过将标识用于投影和模型视图,我们可以直接在剪辑空间中提供顶点坐标。剪辑空间中的[-1,1]范围映射到窗口空间中的[0,width / height]。因此,我们不必知道或不在乎窗户有多大;只要正确设置了glViewport,它就可以正常工作。     
        可能不是问题,但不会有任何帮助:您一次按下一次就会弹出两次模型视图矩阵。您根本不会弹出投影矩阵。 我建议在启动时一次设置投影矩阵,而不要进行任何推动或弹出操作。您实际上也不需要推送并弹出Modelview矩阵。 (您也可以在启动时进行一次纹理设置。)     
        我将从使用如下代码检查glError开始。注意我之所以使用GL2对象,是因为较旧的JOGL和GL对象存在一些问题,例如GL_QUADS之类的愚蠢的东西不在那儿。 如果您的着色器已启用上述代码,则需要通过阅读采样器进行纹理处理。如果是这样,请附加您与此渲染代码一起使用的着色器代码。
private static void checkForGLErrors(GL2 gl) {
    int errno = gl.glGetError();
    switch (errno) {
        case GL2.GL_INVALID_ENUM:
            System.err.println(\"OpenGL Error: Invalid ENUM\");
            break;
        case GL2.GL_INVALID_VALUE:
            System.err.println(\"OpenGL Error: Invalid Value\");
            break;
        case GL2.GL_INVALID_OPERATION:
            System.err.println(\"OpenGL Error: Invalid Operation\");
            break;
        case GL2.GL_STACK_OVERFLOW:
            System.err.println(\"OpenGL Error: Stack Overflow\");
            break;
        case GL2.GL_STACK_UNDERFLOW:
            System.err.println(\"OpenGL Error: Stack Underflow\");
            break;
        case GL2.GL_OUT_OF_MEMORY:
            System.err.println(\"OpenGL Error: Out of Memory\");
            break;
        default:
            return;
    }
}
如果它不变,我也将尝试避免在每一帧生成纹理。您可以保存textureId并在以后进行绑定。     

要回复问题请先登录注册