Рендеринг в текстуру, текстура не отображается полностью - PullRequest
3 голосов
/ 20 февраля 2012

В основном, когда я рендеринг на текстуру, похоже, что какая-то часть текстуры потерялась.

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 голосов
/ 20 февраля 2012

Я не знаком с этой конкретной оболочкой OpenGL, но что я заметил в вашем коде, так это то, что в renderShadowsToTexture вы не настраиваете две вещи: область просмотра и матрицу проекции.Оба из них будут влиять на масштабирование результирующего изображения.

Матрица проекции, вероятно, будет идентичной матрицей (так как вы еще не запускали gluPerspective), что является разумным для ваших координатповторное использование.Но все же это хорошая практика - явно указывать то, что вы хотите, для ясности и надежности (возможно, с помощью pushMatrix / popMatrix).

Но я не вижу, где ваш код настраивает область просмотра ввсе?Возможно, JOGL сделает это для вас?Если это так, это будет размер вашего окна, а не размер текстуры.Этот слишком большой видовой экран приведет к обрезанию частей вашей сцены в конце с высокими координатами, что согласуется с текстурой, которую вы видите (обратите внимание, что вторая синяя точка должна быть очень близка к первой, но обнаруживается далекодалеко).Итак, вам нужно добавить к renderShadowsToTexture:

glViewport(0, 0, floorWidth, floorHeight)

и, возможно, восстановить его позже (или использовать glPushAttrib / glPopAttrib из GL_VIEWPORT_BIT).

Также, цветкомпоненты имеют красно-зелено-синий цвет, поэтому точка пропуска будет зеленым, а не красным.

1 голос
/ 25 декабря 2014

Согласно ответу Кевина Рейда (спасибо ему) я пересмотрел 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);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...