Java I';我在使用OpenGL和glfw(LWJGL)将模型渲染到窗口时遇到问题
我正在努力熟悉用于java的LWJGL库,我一直在网上学习一些教程,但似乎无法渲染模型Java I';我在使用OpenGL和glfw(LWJGL)将模型渲染到窗口时遇到问题,java,opengl,lwjgl,glfw,Java,Opengl,Lwjgl,Glfw,我正在努力熟悉用于java的LWJGL库,我一直在网上学习一些教程,但似乎无法渲染模型 public class Main { private long window; private int width = 1280, height = 720; public void run() { System.out.println("LWJGL " + Version.getVersion() + "!"); init(); loop(); gl
public class Main {
private long window;
private int width = 1280, height = 720;
public void run() {
System.out.println("LWJGL " + Version.getVersion() + "!");
init();
loop();
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
glfwTerminate();
glfwSetErrorCallback(null).free();
}
private void init() {
GLFWErrorCallback.createPrint(System.err).set();
if (!glfwInit()) throw new IllegalStateException("Unable to initialize GLFW");
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
window = glfwCreateWindow(width, height, "TESTING", NULL, NULL);
if (window == NULL) throw new RuntimeException("Failed to create the GLFW window");
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) glfwSetWindowShouldClose(window, true); /
});
try (MemoryStack stack = stackPush()) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*
glfwGetWindowSize(window, pWidth, pHeight);
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
}
private void loop() {
GL.createCapabilities();
GL11.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
Renderer renderer = new Renderer();
Loader loader = new Loader();
StaticShader shader = new StaticShader();
float[] vertices = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
};
int[] indicies = {
0,1,3,
3,1,2
};
RawModel model = loader.loadToVAO(vertices, indicies);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwSwapBuffers(window);
renderer.prepare();
shader.start();
renderer.render(model);
shader.stop();
glfwPollEvents();
}
loader.cleanUp();
shader.cleanUp();
}
public static void main(String[] args) {
new Main().run();
}
}
public class RawModel {
private int vaoID;
private int vertexCount;
public RawModel(int vaoID, int vertexCount) {
this.vaoID = vaoID;
this.vertexCount = vertexCount;
}
public int getVaoID() {
return vaoID;
}
public int getVertexCount() {
return vertexCount;
}
}
public class Renderer {
public void prepare() {
GL11.glClearColor(1, 0, 0, 1);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
}
public void render(RawModel model){
GL30.glBindVertexArray(model.getVaoID());
GL20.glEnableVertexAttribArray(0);
//System.out.println(model.getVertexCount());
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}
public class Loader {
private List<Integer> vaos = new ArrayList<Integer>();
private List<Integer> vbos = new ArrayList<Integer>();
public RawModel loadToVAO(float[] positions,int[] indicies) {
int vaoID = createVAO();
bindIndecesBuffer(indicies);
storeDataInAttributeList(0, positions);
unbindVAO();
return new RawModel(vaoID, indicies.length);
}
private void bindIndecesBuffer(int[] indices) {
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID);
IntBuffer buffer = storeDatainIntBuffer(indices);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}
private IntBuffer storeDatainIntBuffer(int[] data) {
IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
public void cleanUp() {
for (int vao : vaos) {
GL30.glDeleteVertexArrays(vao);
}
for (int vbo : vbos) {
GL15.glDeleteBuffers(vbo);
}
}
private int createVAO() {
int vaoID = GL30.glGenVertexArrays();
vaos.add(vaoID);
GL30.glBindVertexArray(vaoID);
return vaoID;
}
private void storeDataInAttributeList(int attributeNumber, float[] data) {
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
FloatBuffer buffer = storeDataInFloatBuffer(data);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
private void unbindVAO() {
GL30.glBindVertexArray(0);
}
private FloatBuffer storeDataInFloatBuffer(float[] data) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}
public abstract class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
public ShaderProgram(String vertexFile,String fragmentFile){
vertexShaderID = loadShader(vertexFile,GL20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader(fragmentFile,GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
GL20.glAttachShader(programID, vertexShaderID);
GL20.glAttachShader(programID, fragmentShaderID);
bindAttributes();
GL20.glLinkProgram(programID);
GL20.glValidateProgram(programID);
}
public void start(){
GL20.glUseProgram(programID);
}
public void stop(){
GL20.glUseProgram(0);
}
public void cleanUp(){
stop();
GL20.glDetachShader(programID, vertexShaderID);
GL20.glDetachShader(programID, fragmentShaderID);
GL20.glDeleteShader(vertexShaderID);
GL20.glDeleteShader(fragmentShaderID);
GL20.glDeleteProgram(programID);
}
protected abstract void bindAttributes();
protected void bindAttribute(int attribute, String variableName){
GL20.glBindAttribLocation(programID, attribute, variableName);
}
private static int loadShader(String file, int type){
StringBuilder shaderSource = new StringBuilder();
try{
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while((line = reader.readLine())!=null){
shaderSource.append(line).append("//\n");
}
reader.close();
}catch(IOException e){
e.printStackTrace();
System.exit(-1);
}
int shaderID = GL20.glCreateShader(type);
GL20.glShaderSource(shaderID, shaderSource);
GL20.glCompileShader(shaderID);
if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS )== GL11.GL_FALSE){
System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
System.err.println("Could not compile shader!");
System.exit(-1);
}
return shaderID;
}
}
public class StaticShader extends ShaderProgram {
private static final String VERTEX_FILE = "src/shaderEngine/vertexShader.txt";
private static final String FRAGMENT_FILE = "src/shaderEngine/fragmentShader.txt";
public StaticShader() {
super(VERTEX_FILE, FRAGMENT_FILE);
}
@Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
}
}
//VERTEX SHADER
#version 120
attribute vec3 position;
varying vec3 colour;
void main(void){
gl_Position = vec4(position,1.0);
colour = vec3(position.x+0.5,0.0,position.y+0.5);
}
//FRAGMENT SHADER
#version 120
varying vec3 colour;
void main(void){
gl_FragColor = vec4(colour,1.0);
}
我使用的是OpenGL 2.1(这似乎非常过时,但我不确定如何更新,我知道它与您的硬件有关,如果有人对我的规格感兴趣,我使用的是MacBook Pro 2017型号)
如果有人能看看我的代码,告诉我我做错了什么,我会非常感激!(现在正在渲染的只是一个红色窗口)
从我研究过的源代码来看,这段代码应该会生成一个正方形,由两个三角形组成,使用顶点和片段着色器在渐变中着色,但不会渲染任何内容
public class Main {
private long window;
private int width = 1280, height = 720;
public void run() {
System.out.println("LWJGL " + Version.getVersion() + "!");
init();
loop();
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
glfwTerminate();
glfwSetErrorCallback(null).free();
}
private void init() {
GLFWErrorCallback.createPrint(System.err).set();
if (!glfwInit()) throw new IllegalStateException("Unable to initialize GLFW");
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
window = glfwCreateWindow(width, height, "TESTING", NULL, NULL);
if (window == NULL) throw new RuntimeException("Failed to create the GLFW window");
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) glfwSetWindowShouldClose(window, true); /
});
try (MemoryStack stack = stackPush()) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*
glfwGetWindowSize(window, pWidth, pHeight);
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
}
private void loop() {
GL.createCapabilities();
GL11.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
Renderer renderer = new Renderer();
Loader loader = new Loader();
StaticShader shader = new StaticShader();
float[] vertices = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
};
int[] indicies = {
0,1,3,
3,1,2
};
RawModel model = loader.loadToVAO(vertices, indicies);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwSwapBuffers(window);
renderer.prepare();
shader.start();
renderer.render(model);
shader.stop();
glfwPollEvents();
}
loader.cleanUp();
shader.cleanUp();
}
public static void main(String[] args) {
new Main().run();
}
}
public class RawModel {
private int vaoID;
private int vertexCount;
public RawModel(int vaoID, int vertexCount) {
this.vaoID = vaoID;
this.vertexCount = vertexCount;
}
public int getVaoID() {
return vaoID;
}
public int getVertexCount() {
return vertexCount;
}
}
public class Renderer {
public void prepare() {
GL11.glClearColor(1, 0, 0, 1);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
}
public void render(RawModel model){
GL30.glBindVertexArray(model.getVaoID());
GL20.glEnableVertexAttribArray(0);
//System.out.println(model.getVertexCount());
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
}
public class Loader {
private List<Integer> vaos = new ArrayList<Integer>();
private List<Integer> vbos = new ArrayList<Integer>();
public RawModel loadToVAO(float[] positions,int[] indicies) {
int vaoID = createVAO();
bindIndecesBuffer(indicies);
storeDataInAttributeList(0, positions);
unbindVAO();
return new RawModel(vaoID, indicies.length);
}
private void bindIndecesBuffer(int[] indices) {
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID);
IntBuffer buffer = storeDatainIntBuffer(indices);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}
private IntBuffer storeDatainIntBuffer(int[] data) {
IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
public void cleanUp() {
for (int vao : vaos) {
GL30.glDeleteVertexArrays(vao);
}
for (int vbo : vbos) {
GL15.glDeleteBuffers(vbo);
}
}
private int createVAO() {
int vaoID = GL30.glGenVertexArrays();
vaos.add(vaoID);
GL30.glBindVertexArray(vaoID);
return vaoID;
}
private void storeDataInAttributeList(int attributeNumber, float[] data) {
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
FloatBuffer buffer = storeDataInFloatBuffer(data);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
private void unbindVAO() {
GL30.glBindVertexArray(0);
}
private FloatBuffer storeDataInFloatBuffer(float[] data) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
}
public abstract class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
public ShaderProgram(String vertexFile,String fragmentFile){
vertexShaderID = loadShader(vertexFile,GL20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader(fragmentFile,GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
GL20.glAttachShader(programID, vertexShaderID);
GL20.glAttachShader(programID, fragmentShaderID);
bindAttributes();
GL20.glLinkProgram(programID);
GL20.glValidateProgram(programID);
}
public void start(){
GL20.glUseProgram(programID);
}
public void stop(){
GL20.glUseProgram(0);
}
public void cleanUp(){
stop();
GL20.glDetachShader(programID, vertexShaderID);
GL20.glDetachShader(programID, fragmentShaderID);
GL20.glDeleteShader(vertexShaderID);
GL20.glDeleteShader(fragmentShaderID);
GL20.glDeleteProgram(programID);
}
protected abstract void bindAttributes();
protected void bindAttribute(int attribute, String variableName){
GL20.glBindAttribLocation(programID, attribute, variableName);
}
private static int loadShader(String file, int type){
StringBuilder shaderSource = new StringBuilder();
try{
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while((line = reader.readLine())!=null){
shaderSource.append(line).append("//\n");
}
reader.close();
}catch(IOException e){
e.printStackTrace();
System.exit(-1);
}
int shaderID = GL20.glCreateShader(type);
GL20.glShaderSource(shaderID, shaderSource);
GL20.glCompileShader(shaderID);
if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS )== GL11.GL_FALSE){
System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
System.err.println("Could not compile shader!");
System.exit(-1);
}
return shaderID;
}
}
public class StaticShader extends ShaderProgram {
private static final String VERTEX_FILE = "src/shaderEngine/vertexShader.txt";
private static final String FRAGMENT_FILE = "src/shaderEngine/fragmentShader.txt";
public StaticShader() {
super(VERTEX_FILE, FRAGMENT_FILE);
}
@Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
}
}
//VERTEX SHADER
#version 120
attribute vec3 position;
varying vec3 colour;
void main(void){
gl_Position = vec4(position,1.0);
colour = vec3(position.x+0.5,0.0,position.y+0.5);
}
//FRAGMENT SHADER
#version 120
varying vec3 colour;
void main(void){
gl_FragColor = vec4(colour,1.0);
}
公共类主{
私人长窗;
私有整数宽度=1280,高度=720;
公开募捐{
System.out.println(“LWJGL”+Version.getVersion()+”!”;
init();
loop();
glfwFreeCallbacks(窗口);
GLFW窗口(窗口);
glfwTerminate();
glfwSetErrorCallback(null).free();
}
私有void init(){
GLFWErrorCallback.createPrint(System.err.set();
如果(!glfwInit())抛出新的IllegalStateException(“无法初始化GLFW”);
glfwDefaultWindowHits();
glfwWindowHint(GLFW_可见,GLFW_假);
glfwWindowHint(GLFW_可调整大小,GLFW_为真);
window=glfwCreateWindow(宽度、高度、“测试”、NULL、NULL);
if(window==NULL)抛出新的RuntimeException(“未能创建GLFW窗口”);
glfwSetKeyCallback(窗口,(窗口,键,扫描码,操作,mods)->{
如果(key==GLFW\u key\u ESCAPE&action==GLFW\u RELEASE)glfwsetwindowshouldlclose(window,true)/
});
try(MemoryStack stack=stackPush()){
IntBuffer pWidth=stack.mallocInt(1);//int*
IntBuffer pHeight=stack.mallocInt(1);//int*
GLFWGetWindowsSize(窗口、宽度、高度);
GLFWVidMode vidmode=glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window,(vidmode.width()-pWidth.get(0))/2,(vidmode.height()-pHeight.get(0))/2);
}
glfwMakeContextCurrent(窗口);
glfwSwapInterval(1);
glfwShowWindow(窗口);
}
私有void循环(){
GL.createCapabilities();
GL11.glClearColor(1.0f、0.0f、0.0f、0.0f);
渲染器=新渲染器();
加载器=新加载器();
StaticShader=新的StaticShader();
浮点[]顶点={
-0.5f,0.5f,0f,
-0.5f,-0.5f,0f,
0.5f,-0.5f,0f,
0.5f,0.5f,0f,
};
int[]标记={
0,1,3,
3,1,2
};
RawModel model=loader.loadToVAO(顶点、标记);
而(!glfwWindowShouldClose(窗口)){
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glfwSwapBuffers(窗口);
prepare();
shader.start();
渲染器。渲染(模型);
shader.stop();
glfwPollEvents();
}
loader.cleanUp();
shader.cleanUp();
}
公共静态void main(字符串[]args){
新建Main().run();
}
}
公共类模型{
私有内网;
私人帐户;
公共RawModel(int vaoID,int vertexCount){
this.vaoID=vaoID;
this.vertexCount=vertexCount;
}
公共int getVaoID(){
回流阀;
}
公共整数getVertexCount(){
返回顶点计数;
}
}
公共类渲染器{
公众假期准备(){
GL11.glClearColor(1,0,0,1);
GL11.glClear(GL11.GL\u颜色\u缓冲\u位);
}
公共无效渲染(RawModel模型){
GL30.glBindVertexArray(model.getVaoID());
GL20.GlenableVertexAttributeArray(0);
//System.out.println(model.getVertexCount());
GL11.glpaurements(GL11.GL_三角形,model.getVertexCount(),GL11.GL_无符号_INT,0);
GL20.glDisableVertexAttributeArray(0);
GL30.glBindVertexArray(0);
}
}
公共类加载器{
private List vaos=new ArrayList();
私有列表vbos=新建ArrayList();
公共RawModel loadToVAO(浮动[]位置,整数[]标记){
int-vaoID=createVAO();
BindIndexBuffer(标记);
StoreDataInAttribute列表(0,位置);
unbindVAO();
返回新的RAWMODLE(vaoID、标识、长度);
}
私有void bindIndecesBuffer(int[]索引){
int vboID=GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_元素_数组_缓冲区,vboID);
IntBuffer buffer=storeDatainIntBuffer(索引);
GL15.glBufferData(GL15.GL\u元素\u数组\u缓冲区,缓冲区,GL15.GL\u静态\u绘图);
}
私有IntBuffer storeDatainIntBuffer(int[]数据){
IntBuffer buffer=BufferUtils.createIntBuffer(data.length);
buffer.put(数据);
flip();
返回缓冲区;
}
公共空间清理(){
用于(内部vao:vaos){
GL30.glDeleteVertexArrays(vao);
}
用于(int vbo:vbos){
GL15.glDeleteBuffers(vbo);
}
}
私有int createVAO(){
int vaoID=GL30.glgenvertexarray();
添加(vaoID);
GL30.glBindVertexArray(vaoID);
回流阀;
}
私有void storeDataInAttributeList(int AttributeEnumber,float[]数据){
int vboID=GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_数组_BUFFER,vboID);
FloatBuffer=storedatainflotbuffer(数据);
GL15.glBufferData(GL15.GL_数组_BUFFER,BUFFER,GL15.GL_STATIC_DRAW);
GL20.glVertexAttributePointer(attributeEnumber,3,GL11.GL_FLOAT,false,0,0);
GL15.glBindBuffer(GL15.GL_数组_BUFFER,0);
}
私有无效解除绑定(){
GL30.glBindVertexArray(0);
}
私有FloatBuffer存储数据inflotbuffer(float[]数据){
FloatBuffer=BufferUtils.createFloatBuffer