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()而右边的最后一个四边形和下面的一个分别是渲染有纹理的四边形和显示纹理本身内部的四边形。

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

在此处输入图像描述

4

2 回答 2

4

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

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

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

glViewport(0, 0, floorWidth, floorHeight)

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

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

于 2012-02-20T14:09:24.073 回答
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);

}
于 2014-12-25T07:31:59.793 回答