所以这就是我想要做的。我正在尝试使用LWJGL进行2D游戏,LWJGL具有动态生成的地形,使用图像作为图块。它工作正常,但是当我尝试进行缩放时,瓷砖的边缘会变暗,我会在瓷砖之间得到一个额外的像素。这是缩放前后的屏幕截图:
缩放之前和之后屏幕截图:http://postimage.org/image/rhuc9744/
我看了看,从我在互联网上收集到的一点点来看,我认为要点是变焦导致像素精度问题,混合后会变得更糟。我看到一篇博客说我可以在瓷砖之间重叠一些像素,但它看起来太复杂了。我已经尝试了所有混合选项,但它们都没有奏效。所以我想,我应该将所有的瓷砖渲染成一个缓冲区,一个FBO,然后将它作为一个大的纹理应用,所以即使我缩放,我也不会看到黑暗的边缘,因为它只是一个巨大的图片。所以我已经阅读了很多关于FBO的教程,但是大多数(如果不是全部)都是针对3D的,我实际上已经开始工作了。问题是当我将它应用于2d ortho时。代码中断,我得到的只是一个白色的盒子。我已经坚持这个问题好几天了,我似乎无法使用谷歌找到答案。这是我试图开始工作的示例代码:
package com.helgravis;
import static org.lwjgl.opengl.EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT;
import static org.lwjgl.opengl.EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT;
import static org.lwjgl.opengl.EXTFramebufferObject.GL_FRAMEBUFFER_EXT;
import static org.lwjgl.opengl.EXTFramebufferObject.GL_RENDERBUFFER_EXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glBindFramebufferEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glBindRenderbufferEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glFramebufferRenderbufferEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glFramebufferTexture2DEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glGenFramebuffersEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glGenRenderbuffersEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glRenderbufferStorageEXT;
import static org.lwjgl.opengl.GL11.GL_INT;
import static org.lwjgl.opengl.GL11.GL_RGBA;
import static org.lwjgl.opengl.GL11.GL_RGBA8;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.glBindTexture;
import static org.lwjgl.opengl.GL11.glGenTextures;
import static org.lwjgl.opengl.GL11.glTexImage2D;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.Hashtable;
import javax.swing.JPanel;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
public class AnFBOExample
{
private int width, height, canvasWidth = 800, canvasHeight = 600;
private String title;
private boolean bFullscreen;
public int FRAMERATE = 60;
public int framebufferID;
public int framebufferTextureID, spriteTextureID;
public int depthRenderBufferID;
public int fboWidth = 100, fboHeight = 100;
public AnFBOExample()
{
bFullscreen = false;
}
public AnFBOExample(boolean bFullscreen)
{
this.bFullscreen = bFullscreen;
}
public void setTitle(String title)
{
this.title = title;
if(Display.isCreated())
Display.setTitle(title);
}
public String getTitle()
{
return title;
}
public void setResolution(int x, int y)
{
width = x;
height = y;
}
public void setCanvasSize(int x, int y)
{
canvasWidth = x;
canvasHeight = y;
}
private boolean initDisplayMode() throws Exception
{
if(bFullscreen)
Display.setFullscreen(true);
try
{
DisplayMode[] dm = org.lwjgl.util.Display.getAvailableDisplayModes(width, height, -1, -1, -1, -1, 60, 60);
org.lwjgl.util.Display.setDisplayMode(dm, new String[] {
"width=" + width,
"height=" + height,
"freq=" + FRAMERATE,
"bpp="+ org.lwjgl.opengl.Display.getDisplayMode().getBitsPerPixel()
}
);
return true;
}
catch(Exception e)
{
e.printStackTrace();
System.out.println("Unable to enter fullscreen, continuing in windowed mode");
}
return false;
}
public void init() throws Exception
{
try
{
initDisplayMode();
Display.create();
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glAlphaFunc(GL11.GL_GREATER, 0.5f);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, canvasWidth, canvasHeight, 0, -1, 1);
int framebufferID = glGenFramebuffersEXT();
int colorTextureID = glGenTextures();
int depthRenderBufferID = glGenRenderbuffersEXT();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID);
glBindTexture(GL_TEXTURE_2D, colorTextureID);
GL11.glTexParameteri(GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, fboWidth, fboHeight, 0, GL_RGBA, GL_INT, (java.nio.ByteBuffer) null);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, colorTextureID, 0);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthRenderBufferID);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL14.GL_DEPTH_COMPONENT24, fboWidth, fboHeight);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, depthRenderBufferID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
BufferedImage image = loadImage("resources/lamp.png");
spriteTextureID = getTexture(image);
}
catch(LWJGLException le)
{
le.printStackTrace();
}
}
public void draw()
{
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, spriteTextureID);
GL11.glBegin(GL11.GL_QUADS);
{
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(0, 1f);
GL11.glVertex2f(0, 50f);
GL11.glTexCoord2f(1f, 1f);
GL11.glVertex2f(50f, 50f);
GL11.glTexCoord2f(1f, 0);
GL11.glVertex2f(50f, 0);
}
GL11.glEnd();
GL11.glPopMatrix();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, framebufferTextureID);
GL11.glTranslatef(100f, 100f, 0);
GL11.glBegin(GL11.GL_QUADS);
{
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(0, 1f);
GL11.glVertex2f(0, 100f);
GL11.glTexCoord2f(1f, 1f);
GL11.glVertex2f(100f, 100f);
GL11.glTexCoord2f(1f, 0);
GL11.glVertex2f(100f, 0);
}
GL11.glEnd();
GL11.glPopMatrix();
Display.update();
Display.sync(FRAMERATE);
}
public void draw2()
{
// glBindTexture(GL_TEXTURE_2D, 0);
// glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, spriteTextureID);
GL11.glBegin(GL11.GL_QUADS);
{
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(0, 1f);
GL11.glVertex2f(0, 50f);
GL11.glTexCoord2f(1f, 1f);
GL11.glVertex2f(50f, 50f);
GL11.glTexCoord2f(1f, 0);
GL11.glVertex2f(50f, 0);
}
GL11.glEnd();
GL11.glPopMatrix();
// glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
// GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// GL11.glPushMatrix();
// GL11.glEnable(GL11.GL_TEXTURE_2D);
// GL11.glBindTexture(GL11.GL_TEXTURE_2D, framebufferTextureID);
// GL11.glTranslatef(100f, 100f, 0);
// GL11.glBegin(GL11.GL_QUADS);
// {
// GL11.glTexCoord2f(0, 0);
// GL11.glVertex2f(0, 0);
// GL11.glTexCoord2f(0, 1f);
// GL11.glVertex2f(0, 100f);
// GL11.glTexCoord2f(1f, 1f);
// GL11.glVertex2f(100f, 100f);
// GL11.glTexCoord2f(1f, 0);
// GL11.glVertex2f(100f, 0);
// }
// GL11.glEnd();
// GL11.glPopMatrix();
//
// Display.update();
// Display.sync(FRAMERATE);
}
public void cleanup()
{
Display.destroy();
}
public void run()
{
while(!Thread.interrupted())
{
progress();
handleEvents();
draw();
//draw2();
}
}
public void handleEvents()
{
while(Keyboard.next())
if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE)
quit();
if(Display.isCloseRequested())
quit();
}
public void quit()
{
System.exit(0);
}
public void progress()
{
//Add game logic here
}
protected static boolean waitForImage(Image image, Component c)
{
Image[] images = new Image[1];
images[0] = image;
return waitForImages(images, c);
}
protected static boolean waitForImages(Image[] images, Component c)
{
MediaTracker tracker = new MediaTracker(c);
for(int i=0; i<images.length; i++)
tracker.addImage(images[i], 0);
try
{
tracker.waitForAll();
}
catch(InterruptedException ie) {}
return !tracker.isErrorAny();
}
public static BufferedImage loadImage(String imageFile) throws Exception
{
Image image = null;
JPanel buffer = new JPanel();
image = buffer.getToolkit().getImage(imageFile);
waitForImage(image, buffer);
int width = image.getWidth(null);
int height = image.getHeight(null);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.drawImage(image, 0, 0, width, height, buffer);
g2d.dispose();
return bufferedImage;
}
public int getTexture(BufferedImage image) throws Exception
{
return getTexture(image,
GL11.GL_TEXTURE_2D,
GL11.GL_RGBA,
GL11.GL_LINEAR,
GL11.GL_LINEAR);
}
public int getTexture(String resourceName,
int target,
int dstPixelFormat,
int minFilter,
int magFilter) throws Exception
{
BufferedImage bufferedImage = loadImage(resourceName);
return getTexture(bufferedImage, target, dstPixelFormat, minFilter, magFilter);
}
private int createTextureID()
{
ByteBuffer temp = ByteBuffer.allocateDirect(4 * 1);
temp.order(ByteOrder.nativeOrder());
IntBuffer tmp = temp.asIntBuffer();
GL11.glGenTextures(tmp);
return tmp.get(0);
}
public int getTexture(BufferedImage bufferedImage,
int target,
int dstPixelFormat,
int minFilter,
int magFilter) throws Exception
{
int srcPixelFormat = 0;
int textureID = createTextureID();
GL11.glBindTexture(target, textureID);
if(bufferedImage.getColorModel().hasAlpha())
srcPixelFormat = GL11.GL_RGBA;
else
srcPixelFormat = GL11.GL_RGB;
ByteBuffer textureBuffer = convertImageData(bufferedImage);
if(target == GL11.GL_TEXTURE_2D)
{
GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, minFilter);
GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, magFilter);
}
GL11.glTexImage2D(target,
0,
dstPixelFormat,
get2Fold(bufferedImage.getWidth()),
get2Fold(bufferedImage.getHeight()),
0,
srcPixelFormat,
GL11.GL_UNSIGNED_BYTE,
textureBuffer);
return textureID;
}
private int get2Fold(int fold)
{
int ret = 2;
while (ret < fold)
ret *= 2;
return ret;
}
@SuppressWarnings("rawtypes")
private ByteBuffer convertImageData(BufferedImage bufferedImage)
{
ComponentColorModel glAlphaColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[] {8,8,8,8},
true,
false,
ComponentColorModel.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
ComponentColorModel glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[] {8,8,8,0},
false,
false,
ComponentColorModel.OPAQUE,
DataBuffer.TYPE_BYTE);
ByteBuffer imageBuffer = null;
WritableRaster raster;
BufferedImage texImage;
int texWidth = 2;
int texHeight = 2;
while (texWidth < bufferedImage.getWidth())
texWidth *= 2;
while (texHeight < bufferedImage.getHeight())
texHeight *= 2;
if(bufferedImage.getColorModel().hasAlpha())
{
raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texWidth, texHeight, 4, null);
texImage = new BufferedImage(glAlphaColorModel, raster, false, new Hashtable());
}
else
{
raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texWidth, texHeight, 3, null);
texImage = new BufferedImage(glColorModel, raster, false, new Hashtable());
}
Graphics g = texImage.getGraphics();
g.setColor(new Color(0f,0f,0f,0f));
g.fillRect(0,0,texWidth,texHeight);
g.drawImage(bufferedImage,0,0,null);
byte[] data = ((DataBufferByte) texImage.getRaster().getDataBuffer()).getData();
imageBuffer = ByteBuffer.allocateDirect(data.length);
imageBuffer.order(ByteOrder.nativeOrder());
imageBuffer.put(data, 0, data.length);
imageBuffer.flip();
return imageBuffer;
}
public static void main(String args[]) throws Exception
{
AnFBOExample window = new AnFBOExample(false);
window.setResolution(800, 600);
window.setCanvasSize(800, 600);
window.init();
window.setTitle("FBO Test");
window.run();
}
}
代码加载resource / lamp.png中的图像,该图像可以是任何.png文件,并尝试将其渲染到FBO,然后将其作为纹理应用于2d四边形。出于某种原因,当我尝试将FBO绑定为纹理时,我只得到一个白色空白四边形。我不确定我是不是正确渲染FBO,或者我没有正确绑定它。你可以检查方法draw(),这样你就知道我在说什么。就像我说的那样,我一直坚持这个问题,所以任何帮助都会非常感激。
resources / lamp.png:http://s3.postimage.org/rhpdn5ms/lamp.png?noCache=1315464566
答案 0 :(得分:0)
framebufferTextureID,不应该是colourTextureID吗?