Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Opengl帧缓冲区渲染看起来非常逼真_Java_Opengl_Framebuffer_Tile - Fatal编程技术网

Java Opengl帧缓冲区渲染看起来非常逼真

Java Opengl帧缓冲区渲染看起来非常逼真,java,opengl,framebuffer,tile,Java,Opengl,Framebuffer,Tile,原始问题: 我正在用OpenGL制作一个2d游戏,它使用瓷砖绘制地图。目前,每个瓷砖都单独绘制在四边形上。平铺渲染的代码为: @Override public void render() { if (parentTileSet.getTexture() == null) return; float alpha = parentLayer.getOpacity(); if (alpha < 0) alpha = 0; glCo

原始问题:

我正在用OpenGL制作一个2d游戏,它使用瓷砖绘制地图。目前,每个瓷砖都单独绘制在四边形上。平铺渲染的代码为:

@Override
public void render() {
    if (parentTileSet.getTexture() == null)
        return;

    float alpha = parentLayer.getOpacity();
    if (alpha < 0)
        alpha = 0;
    glColor4f(1.0f, 1.0f, 1.0f, alpha); //Set alpha to parent layer's alpha

    parentTileSet.getTexture().bind(); //Bind texture

    float bx = parentTileSet.getTileWidth() / 2; //Half the width
    float by = parentTileSet.getTileHeight() / 2; //Half the height
    float x = getX(), y = getY();
    float z = 0f;

    glPushMatrix(); //Save the current view matrix
    glTranslatef(x, y, 0f); //Translate to the tile's position

    glRotatef(rotate, 0f, 0f, 1f); //Rotate the tile if it has a rotation
    if ((flipType & 1) > 0) //Are we flipping horizontally?
        glScalef(-1f, 1f, 1f);
    if ((flipType & 2) > 0) //Are we flipping vertically?
        glScalef(1f, -1f, 1f);

    //Draw the tile
    glBegin(GL_QUADS);
    glTexCoord2f(tex_cords.bottom_left.x, tex_cords.bottom_left.y); //bottom left
    glVertex3f(-bx, -by, z);
    glTexCoord2f(tex_cords.bottom_right.x, tex_cords.bottom_right.y); //bottom right
    glVertex3f(bx, -by, z);
    glTexCoord2f(tex_cords.top_right.x, tex_cords.top_right.y); //top right
    glVertex3f(bx, by, z);
    glTexCoord2f(tex_cords.top_left.x, tex_cords.top_left.y); //top left
    glVertex3f(-bx, by, z);
    glEnd();
    glPopMatrix(); //Reload the view matrix to original state
    parentTileSet.getTexture().unbind(); //Unbind the texture

}
然后使用以下代码生成帧缓冲区,并将平铺渲染到纹理:

System.out.println("Attempting to generate frame buffer..");

                    try {
                        Framebuffer frame = new Framebuffer(tiledData.getPixelWidth(), tiledData.getPixelHeight());
                        frame.generate();
                        frame.begin();
                        glScalef(0.5f, 0.5f, 1f); //The game is scaled up by 2, so I'm just unscalling here.
                        Iterator<Drawable> drawableIterator = getSortedDrawables();
                        while (drawableIterator.hasNext()) {
                            Drawable d = drawableIterator.next();
                            if (d instanceof TileObject) {
                                TileObject t = (TileObject)d;
                                if (t.isGroundLayer() && !t.isParallaxLayer() && !t.isAnimated()) {
                                    t.render(); //This render method is the one from above
                                    drawableIterator.remove();
                                }
                            }
                        }
                        frame.end();
                        System.out.println("Success!");
                        addDrawable(frame);
                    } catch (RuntimeException e) {
                        System.out.println("Framebuffers are not supported!");
                    }

这里的重点是begin()和end()方法,在这里我设置一个新的投影矩阵并保存旧的投影矩阵,然后在end()方法中恢复它。

我怀疑你的问题与你的矩阵有关
glViewport(…)
不会更改投影的剪裁特征(例如,最小/最大x、y、z坐标),仅更改几何体投影到的帧缓冲区区域(在窗口空间坐标中)。如果你在画瓷砖的时候,使用了恰好在周围的投影矩阵,而不是设置一个合适的矩阵,你可能会遇到一些奇怪的事情,像这样。啊,这是有道理的。那么,我该如何着手解决这个问题呢。。?我会调用glLoadIdentity()还是需要执行其他操作。。?正如我在OP中所说,我对帧缓冲区非常陌生,所以我不知道我在做什么。不,身份矩阵肯定不会在这里帮助你,除非你的瓷砖都有宽度/高度,你可能需要
glOrtho(-width/2.0,width/2.0,-height/2.0,height/2.0,-1,1)
,因为你的瓷砖的原点似乎是(-width/2,-height/2)。是的!非常感谢。我已经更新了我的OP以显示我的答案,因为StackOverflow不允许我回答我自己的问题。
System.out.println("Attempting to generate frame buffer..");

                    try {
                        Framebuffer frame = new Framebuffer(tiledData.getPixelWidth(), tiledData.getPixelHeight());
                        frame.generate();
                        frame.begin();
                        glScalef(0.5f, 0.5f, 1f); //The game is scaled up by 2, so I'm just unscalling here.
                        Iterator<Drawable> drawableIterator = getSortedDrawables();
                        while (drawableIterator.hasNext()) {
                            Drawable d = drawableIterator.next();
                            if (d instanceof TileObject) {
                                TileObject t = (TileObject)d;
                                if (t.isGroundLayer() && !t.isParallaxLayer() && !t.isAnimated()) {
                                    t.render(); //This render method is the one from above
                                    drawableIterator.remove();
                                }
                            }
                        }
                        frame.end();
                        System.out.println("Success!");
                        addDrawable(frame);
                    } catch (RuntimeException e) {
                        System.out.println("Framebuffers are not supported!");
                    }
private int fID, tID;

protected int width, height;

public Framebuffer(int width, int height) {
    this.width = width;
    this.height = height;
}

public void generate() {
    fID = glGenFramebuffers();
    tID = glGenTextures();

    glBindFramebuffer(GL_FRAMEBUFFER, fID);
    glBindTexture(GL_TEXTURE_2D, tID);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_INT, (ByteBuffer) null);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tID, 0);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        throw new RuntimeException("Framebuffer configuration error.");
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

public void begin() {
    glBindFramebuffer(GL_FRAMEBUFFER, fID);

    glPushAttrib(GL_VIEWPORT_BIT);
    glViewport(0, 0, width, height);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(0, width, 0, height, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
}

public void end() {
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glPopAttrib();
}

@Override
public void render() {
    float x = this.width / 2f;
    float y = this.height / 2f;
    float z = 0f;
    float bx = (this.width)/2f;
    float by = (this.height)/2f;

    glPushMatrix();

    glBindTexture(GL_TEXTURE_2D, tID);
    glBegin(GL_QUADS);
    glTexCoord2f(0f, 0f); //bottom left
    glVertex3f(x - bx, y - by, z);
    glTexCoord2f(1f, 0f); //bottom right
    glVertex3f(x + bx, y - by, z);
    glTexCoord2f(1f, 1f); //top right
    glVertex3f(x + bx, y + by, z);
    glTexCoord2f(0f, 1f); //top left
    glVertex3f(x - bx, y + by, z);
    glEnd();
    glBindTexture(GL_TEXTURE_2D, 0);

    glPopMatrix();
}