为什么我的图像不会画到窗户上?

时间:2016-03-28 10:19:13

标签: java image lwjgl

到目前为止,我已经创建了一个窗口和一个将图像绘制到窗口的方法。但是,当我在渲染功能中调用它来绘制到屏幕时;它没有做任何事情只是显示黑屏。

这是我的代码:

package io.rkshah;

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.NULL;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFWVidMode; // again used for primary monitor stuff.
import org.lwjgl.opengl.GL;

public class PixelGame implements Runnable
{
    public static final String TITLE = "PixelGame";

    private Thread mainThread;
    private boolean isRunning = true;
    private long window;
    private int width = 600, height = 400;

    public void start() {
        isRunning = true;
        mainThread = new Thread(this, TITLE);
        mainThread.start();
    }

    public void init() {
        if(glfwInit() != GL_TRUE)
            System.err.println("GLFW initialization failed!");

        glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);

        window = glfwCreateWindow(width, height, TITLE, NULL, NULL);
        if(window == NULL)
            System.err.println("Could not create our Window!");

        GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());

        glfwSetWindowPos(window, (vidMode.width() / 2) - (width / 2), (vidMode.height() / 2) - (height / 2));
        glfwMakeContextCurrent(window);
        glfwShowWindow(window);
        GL.createCapabilities();
    }

    public void update() {
        glfwPollEvents(); // Polls for window events such as closing
    }

    public void render() {
        drawBackgroundLayer();
        glfwSwapBuffers(window); // Swaps out our buffers
    }

    @Override
    public void run() {
        init();
        while(isRunning) {
            update();
            render();

            if(glfwWindowShouldClose(window) == GL_TRUE)
                isRunning = false;
        }
    }

    public void drawBackgroundLayer() {
        BufferedImage img = null;
        try {
            img = ImageIO.read(new File("res/bg.png"));
            drawImage(img);
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    public void drawImage(BufferedImage image) {
        int[] pixels = new int[image.getWidth() * image.getHeight()];
        image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());

        ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4); // 4 bytes per pixel for rgba

        for(int y = 0; y < image.getHeight(); y++) {
            for(int x = 0; x < image.getWidth(); x++) {
                int pixel = pixels[y * image.getWidth() + x];
                buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component
                buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component
                buffer.put((byte) (pixel & 0xFF)); // Blue component
                buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component
            }
        }

        buffer.flip(); // Flip the byte buffer for OpenGL

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
    }

    public static void main(String args[]) {
        PixelGame pg = new PixelGame();
        pg.start();
    }
}

我的所有导入都工作,图像肯定存在,否则会抛出错误。

1 个答案:

答案 0 :(得分:0)

您是否尝试创建四边形,将图像纹理化,然后渲染图像?我会先创建一个空白四边形。接下来,我将图像绑定到四边形。这是我用于渲染GUI的代码,它的概念大致相同:

public class GuiRenderer {

private final RawModel quad;
private GuiShader shader;

/**
 * @param loader    Loader to use in rendering
 * 
 * Constructor of GuiRenderer
 */
public GuiRenderer(Loader loader){
    float[] positions = {-1, 1, -1, -1, 1, 1, 1, -1};
    quad = loader.loadToVAO(positions, 2);
    shader = new GuiShader();
}

/**
 * @param guis      List GuiTextures to be rendered
 * 
 * Renders GuiTextures to screen
 */
public void render(List<GuiTexture> guis){

    if(!guis.isEmpty()) {
        shader.start();
        GL30.glBindVertexArray(quad.getVaoID());
        GL20.glEnableVertexAttribArray(0);
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
        GL11.glDisable(GL11.GL_DEPTH_TEST);
        for(GuiTexture gui: guis){
            GL13.glActiveTexture(GL13.GL_TEXTURE0);
            GL11.glBindTexture(GL11.GL_TEXTURE_2D, gui.getTexture());
            Matrix4f matrix = Maths.createTransformationMatrix(gui.getPosition(), gui.getScale());
            shader.loadTransformation(matrix);
            GL11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, quad.getVertexCount());
        }
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glDisable(GL11.GL_BLEND);
        GL20.glDisableVertexAttribArray(0);
        GL30.glBindVertexArray(0);
        shader.stop();
    }

}

/**
 * Cleans up shader
 */
public void cleanUp(){
    shader.cleanUp();
}
}

这是我引用的加载器:

public RawModel loadToVAO(float[] positions, int dimensions) {
    int vaoID = createVAO();
    this.storeDataInAttributeList(0, dimensions, positions);
    unbindVAO();
    return new RawModel(vaoID, positions.length / dimensions);
}
private FloatBuffer storeDataInFloatBuffer(float[] data) {
    FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
    buffer.put(data);
    buffer.flip();
    return buffer;
}

public int loadTexture(String fileName) {
    BufferedImage image = null;

    try {
        image = ImageIO.read(new File(fileName));
    } catch (IOException e) {
        Debug.addData(Loader.class + " File not found: " + fileName);
        Debug.addData(e.getMessage());
    }

    int[] pixels = new int[image.getWidth() * image.getHeight()];
    image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());

    ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4); //4 for RGBA, 3 for RGB

    for(int y = 0; y < image.getHeight(); y++){
        for(int x = 0; x < image.getWidth(); x++){
            int pixel = pixels[y * image.getWidth() + x];
            buffer.put((byte) ((pixel >> 16) & 0xFF));
            buffer.put((byte) ((pixel >> 8) & 0xFF));
            buffer.put((byte) (pixel & 0xFF));
            buffer.put((byte) ((pixel >> 24) & 0xFF));
        }
    }

    buffer.flip();

    int textureID = GL11.glGenTextures();

    GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
    GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, -1f);

    if(GL.getCapabilities().GL_EXT_texture_filter_anisotropic) {
        float amount = Math.min(4f, GL11.glGetFloat(EXTTextureFilterAnisotropic.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT));
        GL11.glTexParameterf(GL11.GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, amount);
    }

    GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);

    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);


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

    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);

    textures.add(textureID);
    return textureID;
}

包装所有必要渲染信息的GUITexture是:

public class GuiTexture {

private int texture;
private Vector2f position;
private Vector2f scale;

/**
 * @param texture   GPU texture ID
 * @param position  Position of GUI
 * @param scale     Scale of Entity
 * 
 * Constructor
 */
public GuiTexture(int texture, Vector2f position, Vector2f scale) {
    this.texture = texture;
    this.position = position;
    this.scale = scale;
}

/**
 * @return int GPU Texture ID
 * 
 * Gets texture ID of GUI Texture
 */
public int getTexture() {
    return texture;
}

/**
 * @return Vector2f Position of GUI Texture
 * 
 * Gets position of GUI Texture
 */
public Vector2f getPosition() {
    return position;
}

/**
 * @return Vector2f Scale of GUI Texture
 * 
 * Gets scale of GUI Texture
 */
public Vector2f getScale() {
    return scale;
}

}

为了让它呈现,我使用方法:

Loader loader = new Loader();
GuiTexture texture = new GuiTexture(loader.loadTexture("some/file/here.png", new Vector2f(0, 0), new Vector2f(1, 1));
List<GuiTexture> guis = new ArrayList<GuiTexture>();
guis.add(texture);

GuiRenderer renderer = new GuiRenderer(loader);

while(Frame is open) {
    renderer.render(guis);
}

renderer.cleanUp();

我会在这里附上我的着色器的链接: 顶点:https://github.com/dragonslayer0531/Luminos/blob/master/res/shaders/gui.vert 片段:https://github.com/dragonslayer0531/Luminos/blob/master/res/shaders/gui.frag

如果您希望将来引用它,我的整个项目都位于此处。致力于更好地获取文档,对此抱歉。

https://github.com/dragonslayer0531/Luminos