【问题标题】:Render to texture, the texture is not shown completely渲染到纹理,纹理没有完整显示
【发布时间】:2012-02-20 13:53:16
【问题描述】:

基本上,当我渲染到纹理时,看起来纹理的某些部分丢失了。

package org.yourorghere;

import com.jogamp.opengl.util.GLBuffers;
import java.awt.Component;
import java.nio.ByteBuffer;
import javax.media.opengl.*;
import javax.media.opengl.glu.GLU;


public class GLRenderer implements GLEventListener {

int[] textureID = new int[1];
private int floorWidth=48, floorHeight=48;
int[] frameBufferID = new int[1];
int[] depthRenderBufferID = new int[1];
ByteBuffer pixels;
GLU glu;

public void init(GLAutoDrawable drawable) {
    glu = new GLU();

    System.out.println("init");

    GL2 gl = drawable.getGL().getGL2();
    System.err.println("INIT GL IS: " + gl.getClass().getName());

    // Setup the drawing area and shading mode
    gl.glShadeModel(GL2.GL_SMOOTH); // try setting this to GL_FLAT and see what happens.

    renderShadowsToTexture(gl);

    gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
}

public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
}

public void display(GLAutoDrawable drawable) {
    GL2 gl = drawable.getGL().getGL2();

    System.out.println("display");

    float a = 1.0f;

    gl.glMatrixMode(GL2.GL_PROJECTION);
    // Reset the current matrix to the "identity"
    gl.glLoadIdentity();
    glu.gluPerspective(60.0f, (((Component)drawable).getWidth()/
            ((Component)drawable).getHeight()), 1.0f, 50.0f);

    gl.glMatrixMode(GL2.GL_MODELVIEW);
    gl.glLoadIdentity();
    glu.gluLookAt(0.0f, 0.0f, 0.0f, 
                  0.0f, 0.0f, 1.0f, 
                  0.0f, 1.0f, 0.0f);

    // Clear the drawing area
    gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

    gl.glTranslatef(-2.5f, 0.0f, 0.0f);

    gl.glEnable(GL2.GL_TEXTURE_2D);

    gl.glBindTexture(GL2.GL_TEXTURE_2D, textureID[0]);

        gl.glColor3f(1.0f, 1.0f, 1.0f);
        gl.glBegin(GL2.GL_QUADS);
            gl.glTexCoord2f(0, 0);
            gl.glVertex3f(-1.0f,-1.0f, 0.0f);
            gl.glTexCoord2f(0, a);
            gl.glVertex3f(-1.0f, 1.0f, 0.0f);
            gl.glTexCoord2f(1.0f, 1.0f);
            gl.glVertex3f( 1.0f, 1.0f, 0.0f);
            gl.glTexCoord2f(a, 0);
            gl.glVertex3f( 1.0f,-1.0f, 0.0f);
        gl.glEnd();
    gl.glDisable(GL2.GL_TEXTURE_2D);

    gl.glRasterPos2d(3, -2);
    gl.glDrawPixels(floorWidth, floorHeight, GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE, pixels);

}

private void renderShadowsToTexture(GL2 gl) {
    gl.glGenTextures(1, textureID, 0);
    gl.glBindTexture(GL2.GL_TEXTURE_2D, textureID[0]);

    gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
    gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);

    // null means reserve texture memory, but texels are undefined
    gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGB, floorWidth, floorHeight,
                                                0, GL2.GL_RGB, GL2.GL_FLOAT, null);

    gl.glGenFramebuffers(1, frameBufferID, 0);
    gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBufferID[0]);

    //Attach 2D texture to this FBO
    gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, GL2.GL_COLOR_ATTACHMENT0, 
                                    GL2.GL_TEXTURE_2D, textureID[0], 0);

    // depth buffer
    gl.glGenRenderbuffers(1, depthRenderBufferID, 0);
    gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, depthRenderBufferID[0]);
    gl.glRenderbufferStorage(GL2.GL_RENDERBUFFER, GL2.GL_DEPTH_COMPONENT, 
                                            floorWidth, floorHeight);
    gl.glFramebufferRenderbuffer(GL2.GL_FRAMEBUFFER, GL2.GL_DEPTH_ATTACHMENT,
                                        GL2.GL_RENDERBUFFER, depthRenderBufferID[0]);

    if(gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER) == GL2.GL_FRAMEBUFFER_COMPLETE)
        System.out.println("[Viewer] GL_FRAMEBUFFER_COMPLETE!!");
    else
        System.out.println("..cazzo ^^");

    gl.glMatrixMode(GL2.GL_MODELVIEW);
    gl.glPushMatrix();
    gl.glLoadIdentity();

    gl.glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
    gl.glClear(GL2.GL_COLOR_BUFFER_BIT);

    gl.glPointSize(10.0f);
    gl.glBegin(GL2.GL_POINTS);
        gl.glColor3f(0.0f, 1.0f, 0.0f);
        gl.glVertex2d(1.0f, 1.0f);        // THIS IS NOT SHOWN
        gl.glColor3f(0.0f, 0.0f, 1.0f);
        gl.glVertex2d(-1.0f, -1.0f);
        gl.glVertex2d(-0.9f, -0.9f);
    gl.glEnd();

    gl.glPopMatrix();

    pixels = GLBuffers.newDirectByteBuffer(floorWidth*floorHeight*4);

    gl.glReadPixels(0, 0, floorWidth, floorHeight, GL2.GL_RGBA, 
                                                GL2.GL_UNSIGNED_BYTE, pixels);


    System.out.println("glIsTexture: "+gl.glIsTexture(textureID[0]));

    //  bind the back buffer for rendering
    gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
}

public void dispose(GLAutoDrawable glad) {
//        throw new UnsupportedOperationException("Not supported yet.");
        System.out.println("dispose");
    }

}

从左边开始,三角形和第一个四边形通常使用display() 进行渲染,而右边的最后一个四边形和下面的四边形分别是贴有纹理的四边形和显示内容的四边形在纹理本身内部。

基本上我看不到红点,只有蓝点。为什么?

【问题讨论】:

    标签: opengl jogl render-to-texture


    【解决方案1】:

    我不熟悉这个特殊的 OpenGL 包装器,但我注意到您的代码是在 renderShadowsToTexture 中您没有配置两件事:视口和投影矩阵。这两者都会影响结果图像的缩放比例。

    投影矩阵可能是单位矩阵(因为您还没有运行gluPerspective),这对于您使用的坐标是合理的。但是,为了清晰和稳健起见,将其明确设置为您想要的仍然是一种好习惯(可能与 pushMatrix/popMatrix 一起使用)。

    但我根本看不到您的代码在哪里配置视口?也许 JOGL 会为您做到这一点?如果是这样,它将是窗口的大小,而不是纹理的大小。这个太大的视口会导致你的场景的一部分在高坐标端被切断,这与你看到的纹理一致(注意第二个蓝点应该非常接近第一个但显示得很远离开)。所以,你需要添加到renderShadowsToTexture

    glViewport(0, 0, floorWidth, floorHeight)
    

    并可能在之后恢复它(或使用GL_VIEWPORT_BIT 中的glPushAttrib/glPopAttrib)。

    此外,颜色分量是红-绿-蓝,因此您的缺失点将是绿色,而不是红色。

    【讨论】:

    • 当你要渲染一个独立的视图时,只需重置整个矩阵堆栈。这包括主场景、HUD、渲染到纹理等。这也是为什么在窗口的调整大小处理程序中设置视口和投影没有意义的原因。顺便说一句:不调用 gluPerspective 的意思是,仍然使用之前使用的投影。
    【解决方案2】:

    根据 Kevin Reid 的回答(感谢他),我修改了 renderShadowsToTexture(GL2 gl),它对我很有用。我只是想在下面分享给新人。

    private void renderShadowsToTexture(GL2 gl) {
    
        gl.glGenTextures(1, textureID, 0);
        gl.glBindTexture(GL2.GL_TEXTURE_2D, textureID[0]);
    
        gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER,
                GL2.GL_NEAREST);
        gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER,
                GL2.GL_NEAREST);
    
        // null means reserve texture memory, but texels are undefined
        gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGB, floorWidth,
                floorHeight, 0, GL2.GL_RGB, GL2.GL_FLOAT, null);
    
        gl.glGenFramebuffers(1, frameBufferID, 0);
        gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBufferID[0]);
    
        // Attach 2D texture to this FBO
        gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, GL2.GL_COLOR_ATTACHMENT0,
                GL2.GL_TEXTURE_2D, textureID[0], 0);
    
        // depth buffer
        gl.glGenRenderbuffers(1, depthRenderBufferID, 0);
        gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, depthRenderBufferID[0]);
        gl.glRenderbufferStorage(GL2.GL_RENDERBUFFER, GL2.GL_DEPTH_COMPONENT,
                floorWidth, floorHeight);
        gl.glFramebufferRenderbuffer(GL2.GL_FRAMEBUFFER,
                GL2.GL_DEPTH_ATTACHMENT, GL2.GL_RENDERBUFFER,
                depthRenderBufferID[0]);
    
        if (gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER) == GL2.GL_FRAMEBUFFER_COMPLETE)
            System.out.println("[Viewer] GL_FRAMEBUFFER_COMPLETE!!");
        else
            System.out.println("..cazzo ^^");
    
        gl.glViewport(0, 0, floorWidth, floorHeight);
    
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrthof(0, floorWidth, 0, floorHeight, -10, 10);
    
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glPushMatrix();
        gl.glLoadIdentity();
    
        gl.glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT);
    
        gl.glPointSize(10.0f);
        gl.glBegin(GL2.GL_POINTS);
        gl.glColor3f(0.0f, 1.0f, 0.0f);
        gl.glVertex2d(20.0f, 32.0f); // THIS IS NOT SHOWN
    
        gl.glColor3f(0.0f, 0.0f, 1.0f);
        gl.glVertex2d(20.0f, 10.0f);
        gl.glVertex2d(0.9f, 0.9f);
    
        gl.glEnd();
    
        gl.glPopMatrix();
    
        pixels = GLBuffers.newDirectByteBuffer(floorWidth * floorHeight * 4);
    
        gl.glReadPixels(0, 0, floorWidth, floorHeight, GL2.GL_RGBA,
                GL2.GL_UNSIGNED_BYTE, pixels);
    
        System.out.println("glIsTexture: " + gl.glIsTexture(textureID[0]));
    
        // bind the back buffer for rendering
        gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多