Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OpenGL屏幕大小的纹理映射四元组_Java_Opengl_Jogl_Texture2d - Fatal编程技术网

Java OpenGL屏幕大小的纹理映射四元组

Java OpenGL屏幕大小的纹理映射四元组,java,opengl,jogl,texture2d,Java,Opengl,Jogl,Texture2d,我有一个Java OpenGL(JOGL)应用程序,我正在尝试创建一个覆盖整个屏幕的纹理贴图四元体。在“将一些像素绘制到缓冲区”中,然后我想将这些像素读入纹理并在屏幕上重新绘制(应用片段着色器)。我将纹理映射到视口的代码是: gl.glMatrixMode(GL.GL_PROJECTION); gl.glPushMatrix();

我有一个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();
最终结果是一个不覆盖整个视口(部分打开)且不包含缓冲区中像素的四边形。我在这里做错了什么

谢谢,
Jeff

我将从使用如下代码检查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并在以后绑定它。

我将首先使用如下代码检查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并在以后绑定它。

这可能不是问题,但不会有帮助:一次推送会弹出两次modelview矩阵。您根本没有弹出投影矩阵


我建议在启动时设置投影矩阵一次,而不进行任何推送或弹出操作。您实际上也不需要推送和弹出modelview矩阵。(您也可以在启动时进行一次纹理设置。)

这可能不是问题,但不会有帮助:一次推送会弹出两次modelview矩阵。您根本没有弹出投影矩阵


我建议在启动时设置投影矩阵一次,而不进行任何推送或弹出操作。您实际上也不需要推送和弹出modelview矩阵。(您也可以在启动时进行一次纹理设置。)

首先,您应该只在初始化代码中创建纹理。您不应该在每一帧调用glTexImage2D。仅当纹理大小发生变化时才再次调用GLTEXAGE2D;glTexSubImage2D可用于将数据上载到纹理。将glTexImage2D视为“新”,而将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);                                  

通过使用identity for projection和modelview,我们可以直接在剪辑空间中提供顶点坐标。剪辑空间中的[-1,1]范围映射到窗口空间中的[0,宽度/高度]。因此,我们不必知道或关心窗口有多大;只要正确设置了glViewport,这应该可以工作。

首先,您应该只在初始化代码中创建纹理。您不应该在每一帧调用glTexImage2D。仅当纹理大小发生变化时才再次调用GLTEXAGE2D;glTexSubImage2D可用于将数据上载到纹理。将glTexImage2D视为“新”,而将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);                                  

通过使用identity for projection和modelview,我们可以直接在剪辑空间中提供顶点坐标。剪辑空间中的[-1,1]范围映射到窗口空间中的[0,宽度/高度]。因此,我们不必知道或关心窗口有多大;只要glViewport设置正确,就可以正常工作。

GL错误代码返回0,因此此时没有错误。GL错误代码返回0,因此此时没有错误。这不是问题,但这些仍然是很好的建议和更正,因此+1。这不是问题,但是这些仍然是很好的建议和更正,所以+1。你还应该记住,垂直翻转屏幕(在
glOrtho
通话中)会有效地反转你的脸部方向。但是,既然你至少看到了一些东西,那就不会是你的问题,就像剔除一样,你根本看不到任何东西。你还应该记住,垂直翻转屏幕(在你的
glOrtho
调用中)会有效地反转你的脸的方向。但既然你至少看到了一些东西,那就不会是你的问题,就像扑杀一样,你根本看不到任何东西。