到目前为止,我已经创建了一个窗口和一个将图像绘制到窗口的方法。但是,当我在渲染功能中调用它来绘制到屏幕时;它没有做任何事情只是显示黑屏。
这是我的代码:
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();
}
}
我的所有导入都工作,图像肯定存在,否则会抛出错误。
答案 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
如果您希望将来引用它,我的整个项目都位于此处。致力于更好地获取文档,对此抱歉。