渲染到纹理,纹理没有完全显示

3
基本上,当我渲染到纹理时,似乎有一部分纹理丢失了。
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()正常渲染,而右侧的最后一个四边形和下面的四边形分别是贴有纹理映射的四边形和显示纹理本身内容的四边形。

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

enter image description here

2个回答

4
我不熟悉这个特定的OpenGL包装器,但我注意到你的代码中,在renderShadowsToTexture中没有配置两件事:视口和投影矩阵。这两者都会影响结果图像的缩放。
投影矩阵可能是单位矩阵(因为你还没有运行gluPerspective),对于你使用的坐标是合理的。但出于清晰和鲁棒性的考虑,将其显式设置为所需的内容仍然是一个好习惯(可以在周围使用pushMatrix / popMatrix)。
但我没有看到你的代码在哪里配置视口?也许JOGL会为你完成这项工作?如果是这样,它将是窗口的大小,而不是纹理的大小。这个太大的视口会导致你场景的某些部分被切掉在高坐标端,这与你看到的纹理一致(请注意第二个蓝点应该非常靠近第一个点,但显示得很远)。因此,你需要添加到renderShadowsToTexture中:
glViewport(0, 0, floorWidth, floorHeight)

并且可能之后需要恢复它(或使用glPushAttrib/glPopAttribGL_VIEWPORT_BIT)。

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


每当您要呈现独立视图时,请重置整个矩阵堆栈。这包括主场景、HUD、渲染到纹理等。这也是为什么在窗口调整大小的处理程序中设置视口和投影没有意义的原因。顺便说一下:不调用gluPerspective意味着仍然使用先前使用的投影。 - datenwolf

1
根据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);

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接