Рендеринг в текстуру, текстура не отображается полностью
В основном, когда я рендеринг на текстуру, похоже, что какая-то часть текстуры была потеряна.
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()
в то время как последний квад справа и нижний являются соответственно квадратом, отображенным с отображенной на нем текстурой, и квадом, показывающим, что находится внутри самой текстуры.
В основном я не вижу красной точки, только синие. Зачем?
2 ответа
Я не знаком с этой конкретной оболочкой OpenGL, но в вашем коде я заметил, что renderShadowsToTexture
Вы не настраиваете две вещи: область просмотра и матрицу проекции. Оба из них будут влиять на масштабирование результирующего изображения.
Матрица проекции, вероятно, будет матрицей идентичности (поскольку вы еще не gluPerspective
на все пока), что разумно для координат, которые вы используете. Но все же это хорошая практика - явно указывать то, что вы хотите, для ясности и надежности (возможно, с помощью pushMatrix/popMatrix).
Но я не вижу, где ваш код вообще настраивает область просмотра? Возможно, JOGL сделает это для вас? Если так, то это будет размер вашего окна, а не размер текстуры. Этот слишком большой видовой экран приведет к тому, что части вашей сцены будут обрезаны в конце с высокими координатами, что согласуется с текстурой, которую вы видите (обратите внимание, что вторая синяя точка должна быть очень близка к первой, но обнаруживается далеко далеко). Итак, вам нужно добавить в renderShadowsToTexture
:
glViewport(0, 0, floorWidth, floorHeight)
и, возможно, восстановить его позже (или использовать glPushAttrib
/glPopAttrib
из GL_VIEWPORT_BIT
).
Кроме того, цветовые компоненты являются красно-зелено-синими, поэтому пропущенная точка будет зеленой, а не красной.
Согласно ответу Кевина Рейда (спасибо ему) я пересмотрел 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);
}