渲染到纹理,纹理未完全显示
基本上,当我渲染纹理时,看起来纹理的某些部分丢失了。
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()
进行渲染,而右侧的最后一个四边形和下面的四边形分别是使用映射到其上的纹理渲染的四边形和四边形显示纹理本身内部的内容。
基本上我看不到红点,只看到蓝色点。为什么?
Basically when I am rendering to texture, it looks like some part of the texture got lost.
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");
}
}
Starting from the left, the triangle and the first quad are rendered normally using the display()
while the last quad on the right and the one below are respectively the quad rendered with the texture mapped on it and the quad showing what is inside the texture itself.
Basically I do not see the red point, only the blue ones. Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不熟悉这个特定的 OpenGL 包装器,但我注意到您的代码是在 renderShadowsToTexture 中您没有配置两件事:视口和投影矩阵。这两者都会影响生成图像的缩放比例。
投影矩阵可能是单位矩阵(因为您还没有运行 gluPerspective ),这对于您使用的坐标来说是合理的。但为了清晰和稳健起见,将其明确设置为您想要的值仍然是一个很好的做法(可能带有pushMatrix/popMatrix)。
但我根本看不到你的代码在哪里配置视口?也许 JOGL 可以为您做到这一点?如果是这样,它将是窗口的大小,而不是纹理的大小。这个太大的视口将导致场景的部分在高坐标端被切断,这与您看到的纹理一致(请注意,第二个蓝点应该非常接近第一个蓝点,但显示得很远离开)。因此,您需要添加到
renderShadowsToTexture
:并可能随后恢复它(或使用
GL_VIEWPORT_BIT
的glPushAttrib
/glPopAttrib
)。另外,颜色分量是红-绿-蓝,所以你的缺失点将是绿色,而不是红色。
I'm not familiar with this particular OpenGL wrapper, but what I notice about your code is that in
renderShadowsToTexture
you do not configure two things: the viewport and the projection matrix. Both of these will affect the scaling of the resulting image.The projection matrix will probably be the identity matrix (since you haven't run
gluPerspective
at all yet), which is reasonable for the coordinates you're using. But it is still good practice to set it explicitly to what you want for the sake of clarity and robustness (possibly with a pushMatrix/popMatrix around).But I don't see where your code configures the viewport at all? Perhaps JOGL does that for you? If so, it will be the size of your window, not the size of the texture. This too-large viewport will cause portions of your scene to be cut off at the high-coordinate end, which is consistent with the texture you are seeing (note that the second blue point should be very close to the first one but shows up far away). So, you need to add to
renderShadowsToTexture
:and probably restore it afterward (or use
glPushAttrib
/glPopAttrib
ofGL_VIEWPORT_BIT
).Also, color components are red-green-blue, so your missing point will be green, not red.
根据 Kevin Reid 的回答(感谢他)我修改了 renderShadowsToTexture(GL2 gl) ,它对我来说非常有用。下面我只是想分享给新人。
According to Kevin Reid's answer (thanks to him) I revised
renderShadowsToTexture(GL2 gl)
and it worked great for me. I just wanted to share it below for newcomers.