Java OpenGL屏幕大小的纹理映射四边形 [英] Java OpenGL screen sized texture mapped quad

查看:123
本文介绍了Java OpenGL屏幕大小的纹理映射四边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java OpenGL(JOGL)应用程序,我正在尝试创建一个覆盖整个屏幕的纹理映射的四边形.在绘制一些像素到缓冲区后,我想将这些像素读入纹理并在屏幕上重画它们(应用片段着色器).我将纹理映射到视口的代码是:

I have a Java OpenGL (JOGL) app, and I'm trying to create a texture mapped quad that covers the entire screen. In draw some pixels to a buffer and then I want to read those pixels into a texture and redraw them on screen (with a fragment shader applied). My code for mapping the texture to the viewport is:

        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();

最终结果是一个四边形没有覆盖整个视口(部分打开),并且不包含缓冲区中的像素.我在这里做错了什么?

The end result is a quad that is not covering the whole viewport (it's partially on) and that does not contain the pixels from the buffer. What am I doing incorrectly here?

谢谢, 杰夫

推荐答案

首先,您只应在初始化代码中创建纹理.您不应该每帧都调用glTexImage2D.如果纹理的大小发生变化,则仅再次调用glTexImage2D;否则,将重新调用. glTexSubImage2D可用于将数据上传到纹理.将glTexImage2D视为新",而将glTexSubImage2D视为内存副本.

First, you should only create the texture in your initialization code. You should not be calling glTexImage2D every frame. Only call glTexImage2D again if the size of the texture changes; glTexSubImage2D can be used to upload data to the texture. Think of glTexImage2D as "new", while glTexSubImage2D as a memory copy.

在初始化OpenGL之后执行一次.

Do this once, after initializing 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,它就可以正常工作.

By using identity for projection and modelview, we are able to supply vertex coordinates directly in clip-space. The [-1, 1] range in clip-space maps to [0, width/height] in window space. So we don't have to know or care about how big the window is; as long as the glViewport was set up correctly, this should work.

这篇关于Java OpenGL屏幕大小的纹理映射四边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆