macOS 上的 LWJGL:尝试使用着色器但未呈现任何内容
LWJGL on macOS : trying to have shader but nothing is rendered
我正在按照教程学习 LWJGL,但是 window 上什么也没有出现。
我是 Java 编程新手,我使用的是 macOS
这是我的主要内容 class:
package main;
import org.lwjgl.glfw.GLFW;
import engine.graphics.Mesh;
import engine.graphics.Renderer;
import engine.graphics.Shader;
import engine.graphics.Vertex;
import engine.io.Input;
import engine.io.Window;
import engine.maths.Vector3f;
public class Main implements Runnable{
public Window window;
public Renderer renderer;
public Shader shader;
public final int WIDHT = 1280, HEIGHT = 760;
public final String TITLE = "Window";
public Mesh mesh = new Mesh(new Vertex[] {
new Vertex(new Vector3f(-0.5f, 0.5f, 0.0f)),
new Vertex(new Vector3f(-0.5f, -0.5f, 0.0f)),
new Vertex(new Vector3f( 0.5f, -0.5f, 0.0f)),
new Vertex(new Vector3f( 0.5f, 0.5f, 0.0f))
}, new int[] {
0, 1, 2,
0, 3, 2
});
public void init() {
window = new Window(WIDHT, HEIGHT, TITLE);
shader = new Shader("/shaders/mainVertex.glsl", "/shaders/mainFragment.glsl");
renderer = new Renderer(shader);
window.setBackgroundColor(1.0f, 0.0f, 0.0f);
window.create();
mesh.create();
shader.create();
}
private void update() {
window.update();
if(Input.isButtonDown(GLFW.GLFW_MOUSE_BUTTON_LEFT)) {
System.out.println("x:" + Input.getMouseX() + " /y:" + Input.getMouseY());
}
}
private void render() {
renderer.renderMesh(mesh);
window.swapBuffers();
}
public void run() {
init();
while(!window.shouldClose() && !Input.isKeyDown(GLFW.GLFW_KEY_ESCAPE)) {
update();
render();
}
window.destroy();
}
public static void main(String[] args) {
new Main().run();
}
}
我的Windowclass:
package engine.io;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.glfw.GLFWWindowSizeCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import engine.maths.Vector3f;
public class Window {
private int width, height;
private String title;
private long window;
private int[] windowPosX = new int[1], windowPosY = new int[1];
private int frames;
private long time;
private Input input;
private Vector3f background = new Vector3f(0, 0, 0);
private GLFWWindowSizeCallback sizeCallback;
private boolean isResized;
public Window(int width, int height, String title) {
this.width = width;
this.height = height;
this.title = title;
}
public void create() {
if(!GLFW.glfwInit()) {
System.err.println("ERROR: GLFW wasn't initialize");
return;
}
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GL11.GL_TRUE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
input = new Input();
window = GLFW.glfwCreateWindow(width, height, title, 0, 0);
if(window == 0) {
System.err.println("ERROR: window wasn't created");
return;
}
GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
windowPosX[0] = (videoMode.width() - width) / 2;
windowPosY[0] = 0;
GLFW.glfwSetWindowPos(window, windowPosX[0], windowPosY[0]);
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities();
GL11.glEnable(GL11.GL_DEPTH_TEST);
createCallback();
GLFW.glfwShowWindow(window);
GLFW.glfwSwapInterval(1);
time = System.currentTimeMillis();
}
private void createCallback() {
sizeCallback = new GLFWWindowSizeCallback() {
public void invoke(long window, int w, int h) {
width = w;
height = h;
isResized = true;
}
};
GLFW.glfwSetKeyCallback(window, input.getKeyboardCallBack());
GLFW.glfwSetCursorPosCallback(window, input.getMouseMoveCallBack());
GLFW.glfwSetMouseButtonCallback(window, input.getMouseButtonsCallBack());
GLFW.glfwSetScrollCallback(window, input.getMouseScrollCallBack());
GLFW.glfwSetWindowSizeCallback(window, sizeCallback);
}
public void update() {
if(isResized){
GL11.glViewport(0, 0, width, height);
isResized = false;
}
GL11.glClearColor(background.getX(), background.getY(), background.getZ(), 1.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GLFW.glfwPollEvents();
frames ++;
if(System.currentTimeMillis() > time + 1000) {
GLFW.glfwSetWindowTitle(window, title + " | FPS:" + frames);
time = System.currentTimeMillis();
frames = 0;
}
}
public void swapBuffers() {
GLFW.glfwSwapBuffers(window);
}
public void setBackgroundColor(float r, float g, float b) {
background.setX(r);
background.setY(g);;
background.setZ(b);;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public String getTitle() {
return title;
}
public long getWindow() {
return window;
}
public boolean shouldClose() {
return GLFW.glfwWindowShouldClose(window);
}
public void destroy() {
input.destroy();
sizeCallback.free();
GLFW.glfwWindowShouldClose(window);
GLFW.glfwDestroyWindow(window);
GLFW.glfwTerminate();
}
}
我的着色器和渲染器class:
package engine.graphics;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import engine.utils.FileUtils;
public class Shader {
private String vertexFile, fragmentFile;
private int vertexID, fragmentID, programID;
public Shader(String vertexPath, String fragmentPath) {
vertexFile = FileUtils.loadAsString(vertexPath);
fragmentFile = FileUtils.loadAsString(fragmentPath);
}
public void create() {
programID = GL20.glCreateProgram();
vertexID = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vertexID, vertexFile);
GL20.glCompileShader(vertexID);
if(GL20.glGetShaderi(vertexID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.println("Vertex Shader: " + GL20.glGetShaderInfoLog(vertexID));
return;
}
fragmentID = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(fragmentID, fragmentFile);
GL20.glCompileShader(fragmentID);
if(GL20.glGetShaderi(fragmentID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.println("Fragment Shader: " + GL20.glGetShaderInfoLog(fragmentID));
return;
}
GL20.glAttachShader(programID, vertexID);
GL20.glAttachShader(programID, fragmentID);
GL20.glLinkProgram(programID);
if(GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS) == GL11.GL_FALSE) {
System.err.println("Program Linking: " + GL20.glGetProgramInfoLog(programID));
return;
}
GL20.glValidateProgram(programID);
if(GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS) == GL11.GL_FALSE) {
System.err.println("Program Validation: " + GL20.glGetProgramInfoLog(programID));
return;
}
GL20.glDeleteShader(vertexID);
GL20.glDeleteShader(fragmentID);
}
public void bind() {
GL20.glUseProgram(programID);
}
public void unbind() {
GL20.glUseProgram(0);
}
public void destroy() {
GL20.glDeleteProgram(programID);
}
}
package engine.graphics;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL30;
public class Renderer {
private Shader shader;
public Renderer(Shader shader) {
this.shader = shader;
}
public void renderMesh(Mesh mesh) {
GL30.glBindVertexArray(mesh.getVAO());
GL30.glEnableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, mesh.getIBO());
shader.bind();
GL11.glDrawElements(GL11.GL_TRIANGLES, mesh.getIndices().length, GL11.GL_FLOAT, 0);
shader.unbind();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL30.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}
顶点、网格、输入、Vetor3f 和 FileUtils class:
package engine.graphics;
import engine.maths.Vector3f;
public class Vertex {
private Vector3f position;
public Vertex(Vector3f position) {
this.position = position;
}
public Vector3f getPosition() {
return position;
}
}
package engine.graphics;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.system.MemoryUtil;
public class Mesh {
private Vertex[] vertices;
private int[] indices;
private int vao, pbo, ibo;
public Mesh(Vertex[] vertices, int[] indices) {
this.vertices = vertices;
this.indices = indices;
}
public void create() {
vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
FloatBuffer positionBuffer = MemoryUtil.memAllocFloat(vertices.length * 3);
float[] positionData = new float[vertices.length * 3];
for (int i = 0; i < vertices.length; i++) {
positionData[i * 3] = vertices[i].getPosition().getX();
positionData[i * 3 + 1] = vertices[i].getPosition().getY();
positionData[i * 3 + 2] = vertices[i].getPosition().getZ();
}
positionBuffer.put(positionData).flip();
pbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, pbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, positionBuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, ibo, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
IntBuffer indicesBuffer = MemoryUtil.memAllocInt(indices.length);
indicesBuffer.put(indices).flip();
ibo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ibo);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
}
public Vertex[] getVertices() {
return vertices;
}
public int[] getIndices() {
return indices;
}
public int getVAO() {
return vao;
}
public int getPBO() {
return pbo;
}
public int getIBO() {
return ibo;
}
}
package engine.io;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWCursorPosCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWMouseButtonCallback;
import org.lwjgl.glfw.GLFWScrollCallback;
public class Input {
private static boolean[] keys = new boolean[GLFW.GLFW_KEY_LAST];
private static boolean[] buttons = new boolean[GLFW.GLFW_MOUSE_BUTTON_LAST];
private static double mouseX, mouseY;
private static double scrollX, scrollY;
private GLFWKeyCallback keyboard;
private GLFWCursorPosCallback mouseMove;
private GLFWMouseButtonCallback mouseButtons;
private GLFWScrollCallback mouseScroll;
public Input() {
keyboard = new GLFWKeyCallback() {
public void invoke(long window, int key, int scancode, int action, int mods) {
if(key == -1) {
return;
}
keys[key] = (action != GLFW.GLFW_RELEASE);
}
};
mouseMove = new GLFWCursorPosCallback() {
public void invoke(long window, double xpos, double ypos) {
mouseX = xpos;
mouseY = ypos;
}
};
mouseButtons = new GLFWMouseButtonCallback() {
public void invoke(long window, int button, int action, int mods) {
buttons[button] = (action != GLFW.GLFW_RELEASE);
}
};
mouseScroll = new GLFWScrollCallback() {
public void invoke(long window, double offsetx, double offsety) {
scrollX += offsetx;
scrollY += offsety;
}
};
}
public static boolean isKeyDown(int key) {
return keys[key];
}
public static boolean isButtonDown(int button) {
return buttons[button];
}
public void destroy() {
keyboard.free();
mouseMove.free();
mouseButtons.free();
mouseScroll.free();
}
public static double getMouseX() {
return mouseX;
}
public static double getMouseY() {
return mouseY;
}
public static double getScrollX() {
return scrollX;
}
public static double getScrollY() {
return scrollY;
}
public GLFWKeyCallback getKeyboardCallBack() {
return keyboard;
}
public GLFWCursorPosCallback getMouseMoveCallBack() {
return mouseMove;
}
public GLFWMouseButtonCallback getMouseButtonsCallBack() {
return mouseButtons;
}
public GLFWScrollCallback getMouseScrollCallBack() {
return mouseScroll;
}
}
package engine.maths;
public class Vector3f {
private float x, y, z;
public Vector3f(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
public void set(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public float getZ() {
return z;
}
public void setZ(float z) {
this.z = z;
}
}
package engine.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class FileUtils {
public static String loadAsString(String path) {
StringBuilder result = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(FileUtils.class.getResourceAsStream(path)))) {
String line = "";
while ((line = reader.readLine()) != null) {
result.append(line).append("\n");
}
} catch (IOException e) {
System.err.println("Couldn't find the file at " + path);
}
return result.toString();
}
}
以及 mainVertex.glsl 和 mainFragment.glsl 文件:
#version 330 core
layout(location = 0) in vec3 position;
out vec3 color;
void main() {
gl_Position = vec4(position, 1.0);
color = position;
}
#version 330 core
in vec3 color;
out vec4 outColor;
void main() {
outColor = vec4(color, 1.0);
}
代码很多,不知道看懂了有什么用
在您调用的 Renderer.renderMesh(Mesh)
方法中
GL11.glDrawElements(GL11.GL_TRIANGLES, mesh.getIndices().length, GL11.GL_FLOAT, 0);
GL_FLOAT
是该方法的 type
参数的无效值,因为索引不能是浮点数,而你的不是。你使用整数。
因此,将 GL_FLOAT
更改为 GL_UNSIGNED_INT
。
我正在按照教程学习 LWJGL,但是 window 上什么也没有出现。 我是 Java 编程新手,我使用的是 macOS
这是我的主要内容 class:
package main;
import org.lwjgl.glfw.GLFW;
import engine.graphics.Mesh;
import engine.graphics.Renderer;
import engine.graphics.Shader;
import engine.graphics.Vertex;
import engine.io.Input;
import engine.io.Window;
import engine.maths.Vector3f;
public class Main implements Runnable{
public Window window;
public Renderer renderer;
public Shader shader;
public final int WIDHT = 1280, HEIGHT = 760;
public final String TITLE = "Window";
public Mesh mesh = new Mesh(new Vertex[] {
new Vertex(new Vector3f(-0.5f, 0.5f, 0.0f)),
new Vertex(new Vector3f(-0.5f, -0.5f, 0.0f)),
new Vertex(new Vector3f( 0.5f, -0.5f, 0.0f)),
new Vertex(new Vector3f( 0.5f, 0.5f, 0.0f))
}, new int[] {
0, 1, 2,
0, 3, 2
});
public void init() {
window = new Window(WIDHT, HEIGHT, TITLE);
shader = new Shader("/shaders/mainVertex.glsl", "/shaders/mainFragment.glsl");
renderer = new Renderer(shader);
window.setBackgroundColor(1.0f, 0.0f, 0.0f);
window.create();
mesh.create();
shader.create();
}
private void update() {
window.update();
if(Input.isButtonDown(GLFW.GLFW_MOUSE_BUTTON_LEFT)) {
System.out.println("x:" + Input.getMouseX() + " /y:" + Input.getMouseY());
}
}
private void render() {
renderer.renderMesh(mesh);
window.swapBuffers();
}
public void run() {
init();
while(!window.shouldClose() && !Input.isKeyDown(GLFW.GLFW_KEY_ESCAPE)) {
update();
render();
}
window.destroy();
}
public static void main(String[] args) {
new Main().run();
}
}
我的Windowclass:
package engine.io;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.glfw.GLFWWindowSizeCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import engine.maths.Vector3f;
public class Window {
private int width, height;
private String title;
private long window;
private int[] windowPosX = new int[1], windowPosY = new int[1];
private int frames;
private long time;
private Input input;
private Vector3f background = new Vector3f(0, 0, 0);
private GLFWWindowSizeCallback sizeCallback;
private boolean isResized;
public Window(int width, int height, String title) {
this.width = width;
this.height = height;
this.title = title;
}
public void create() {
if(!GLFW.glfwInit()) {
System.err.println("ERROR: GLFW wasn't initialize");
return;
}
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GL11.GL_TRUE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
input = new Input();
window = GLFW.glfwCreateWindow(width, height, title, 0, 0);
if(window == 0) {
System.err.println("ERROR: window wasn't created");
return;
}
GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
windowPosX[0] = (videoMode.width() - width) / 2;
windowPosY[0] = 0;
GLFW.glfwSetWindowPos(window, windowPosX[0], windowPosY[0]);
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities();
GL11.glEnable(GL11.GL_DEPTH_TEST);
createCallback();
GLFW.glfwShowWindow(window);
GLFW.glfwSwapInterval(1);
time = System.currentTimeMillis();
}
private void createCallback() {
sizeCallback = new GLFWWindowSizeCallback() {
public void invoke(long window, int w, int h) {
width = w;
height = h;
isResized = true;
}
};
GLFW.glfwSetKeyCallback(window, input.getKeyboardCallBack());
GLFW.glfwSetCursorPosCallback(window, input.getMouseMoveCallBack());
GLFW.glfwSetMouseButtonCallback(window, input.getMouseButtonsCallBack());
GLFW.glfwSetScrollCallback(window, input.getMouseScrollCallBack());
GLFW.glfwSetWindowSizeCallback(window, sizeCallback);
}
public void update() {
if(isResized){
GL11.glViewport(0, 0, width, height);
isResized = false;
}
GL11.glClearColor(background.getX(), background.getY(), background.getZ(), 1.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GLFW.glfwPollEvents();
frames ++;
if(System.currentTimeMillis() > time + 1000) {
GLFW.glfwSetWindowTitle(window, title + " | FPS:" + frames);
time = System.currentTimeMillis();
frames = 0;
}
}
public void swapBuffers() {
GLFW.glfwSwapBuffers(window);
}
public void setBackgroundColor(float r, float g, float b) {
background.setX(r);
background.setY(g);;
background.setZ(b);;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public String getTitle() {
return title;
}
public long getWindow() {
return window;
}
public boolean shouldClose() {
return GLFW.glfwWindowShouldClose(window);
}
public void destroy() {
input.destroy();
sizeCallback.free();
GLFW.glfwWindowShouldClose(window);
GLFW.glfwDestroyWindow(window);
GLFW.glfwTerminate();
}
}
我的着色器和渲染器class:
package engine.graphics;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import engine.utils.FileUtils;
public class Shader {
private String vertexFile, fragmentFile;
private int vertexID, fragmentID, programID;
public Shader(String vertexPath, String fragmentPath) {
vertexFile = FileUtils.loadAsString(vertexPath);
fragmentFile = FileUtils.loadAsString(fragmentPath);
}
public void create() {
programID = GL20.glCreateProgram();
vertexID = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vertexID, vertexFile);
GL20.glCompileShader(vertexID);
if(GL20.glGetShaderi(vertexID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.println("Vertex Shader: " + GL20.glGetShaderInfoLog(vertexID));
return;
}
fragmentID = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(fragmentID, fragmentFile);
GL20.glCompileShader(fragmentID);
if(GL20.glGetShaderi(fragmentID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.println("Fragment Shader: " + GL20.glGetShaderInfoLog(fragmentID));
return;
}
GL20.glAttachShader(programID, vertexID);
GL20.glAttachShader(programID, fragmentID);
GL20.glLinkProgram(programID);
if(GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS) == GL11.GL_FALSE) {
System.err.println("Program Linking: " + GL20.glGetProgramInfoLog(programID));
return;
}
GL20.glValidateProgram(programID);
if(GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS) == GL11.GL_FALSE) {
System.err.println("Program Validation: " + GL20.glGetProgramInfoLog(programID));
return;
}
GL20.glDeleteShader(vertexID);
GL20.glDeleteShader(fragmentID);
}
public void bind() {
GL20.glUseProgram(programID);
}
public void unbind() {
GL20.glUseProgram(0);
}
public void destroy() {
GL20.glDeleteProgram(programID);
}
}
package engine.graphics;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL30;
public class Renderer {
private Shader shader;
public Renderer(Shader shader) {
this.shader = shader;
}
public void renderMesh(Mesh mesh) {
GL30.glBindVertexArray(mesh.getVAO());
GL30.glEnableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, mesh.getIBO());
shader.bind();
GL11.glDrawElements(GL11.GL_TRIANGLES, mesh.getIndices().length, GL11.GL_FLOAT, 0);
shader.unbind();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL30.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}
顶点、网格、输入、Vetor3f 和 FileUtils class:
package engine.graphics;
import engine.maths.Vector3f;
public class Vertex {
private Vector3f position;
public Vertex(Vector3f position) {
this.position = position;
}
public Vector3f getPosition() {
return position;
}
}
package engine.graphics;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.system.MemoryUtil;
public class Mesh {
private Vertex[] vertices;
private int[] indices;
private int vao, pbo, ibo;
public Mesh(Vertex[] vertices, int[] indices) {
this.vertices = vertices;
this.indices = indices;
}
public void create() {
vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
FloatBuffer positionBuffer = MemoryUtil.memAllocFloat(vertices.length * 3);
float[] positionData = new float[vertices.length * 3];
for (int i = 0; i < vertices.length; i++) {
positionData[i * 3] = vertices[i].getPosition().getX();
positionData[i * 3 + 1] = vertices[i].getPosition().getY();
positionData[i * 3 + 2] = vertices[i].getPosition().getZ();
}
positionBuffer.put(positionData).flip();
pbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, pbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, positionBuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, ibo, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
IntBuffer indicesBuffer = MemoryUtil.memAllocInt(indices.length);
indicesBuffer.put(indices).flip();
ibo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ibo);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
}
public Vertex[] getVertices() {
return vertices;
}
public int[] getIndices() {
return indices;
}
public int getVAO() {
return vao;
}
public int getPBO() {
return pbo;
}
public int getIBO() {
return ibo;
}
}
package engine.io;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWCursorPosCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWMouseButtonCallback;
import org.lwjgl.glfw.GLFWScrollCallback;
public class Input {
private static boolean[] keys = new boolean[GLFW.GLFW_KEY_LAST];
private static boolean[] buttons = new boolean[GLFW.GLFW_MOUSE_BUTTON_LAST];
private static double mouseX, mouseY;
private static double scrollX, scrollY;
private GLFWKeyCallback keyboard;
private GLFWCursorPosCallback mouseMove;
private GLFWMouseButtonCallback mouseButtons;
private GLFWScrollCallback mouseScroll;
public Input() {
keyboard = new GLFWKeyCallback() {
public void invoke(long window, int key, int scancode, int action, int mods) {
if(key == -1) {
return;
}
keys[key] = (action != GLFW.GLFW_RELEASE);
}
};
mouseMove = new GLFWCursorPosCallback() {
public void invoke(long window, double xpos, double ypos) {
mouseX = xpos;
mouseY = ypos;
}
};
mouseButtons = new GLFWMouseButtonCallback() {
public void invoke(long window, int button, int action, int mods) {
buttons[button] = (action != GLFW.GLFW_RELEASE);
}
};
mouseScroll = new GLFWScrollCallback() {
public void invoke(long window, double offsetx, double offsety) {
scrollX += offsetx;
scrollY += offsety;
}
};
}
public static boolean isKeyDown(int key) {
return keys[key];
}
public static boolean isButtonDown(int button) {
return buttons[button];
}
public void destroy() {
keyboard.free();
mouseMove.free();
mouseButtons.free();
mouseScroll.free();
}
public static double getMouseX() {
return mouseX;
}
public static double getMouseY() {
return mouseY;
}
public static double getScrollX() {
return scrollX;
}
public static double getScrollY() {
return scrollY;
}
public GLFWKeyCallback getKeyboardCallBack() {
return keyboard;
}
public GLFWCursorPosCallback getMouseMoveCallBack() {
return mouseMove;
}
public GLFWMouseButtonCallback getMouseButtonsCallBack() {
return mouseButtons;
}
public GLFWScrollCallback getMouseScrollCallBack() {
return mouseScroll;
}
}
package engine.maths;
public class Vector3f {
private float x, y, z;
public Vector3f(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
public void set(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public float getZ() {
return z;
}
public void setZ(float z) {
this.z = z;
}
}
package engine.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class FileUtils {
public static String loadAsString(String path) {
StringBuilder result = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(FileUtils.class.getResourceAsStream(path)))) {
String line = "";
while ((line = reader.readLine()) != null) {
result.append(line).append("\n");
}
} catch (IOException e) {
System.err.println("Couldn't find the file at " + path);
}
return result.toString();
}
}
以及 mainVertex.glsl 和 mainFragment.glsl 文件:
#version 330 core
layout(location = 0) in vec3 position;
out vec3 color;
void main() {
gl_Position = vec4(position, 1.0);
color = position;
}
#version 330 core
in vec3 color;
out vec4 outColor;
void main() {
outColor = vec4(color, 1.0);
}
代码很多,不知道看懂了有什么用
在您调用的 Renderer.renderMesh(Mesh)
方法中
GL11.glDrawElements(GL11.GL_TRIANGLES, mesh.getIndices().length, GL11.GL_FLOAT, 0);
GL_FLOAT
是该方法的 type
参数的无效值,因为索引不能是浮点数,而你的不是。你使用整数。
因此,将 GL_FLOAT
更改为 GL_UNSIGNED_INT
。