I'm stuck trying to figure out why this code is wrong. Its suposed to show a square on the screen. With GL_FRONT_AND_BACK to GL_LINE i see a single line. With GL_FRONT_AND_BACK to GL_FILL a get nothing.
Fragment shader:
#version 330 core
out vec4 oColor;
void main() {
oColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
Vertex Shader:
#version 330 core
layout (location = 0) in vec3 iPosition;
void main() {
gl_Position = vec4(iPosition, 1.0);
}
All this code is basicaly copied from the learn opengl site https://learnopengl.com/Getting-started/Hello-Triangle
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.system.MemoryUtil;
import java.nio.file.Files;
import java.nio.file.Paths;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.glfw.GLFW.*;
public class HelloTriangle {
public static void main(String[] args) {
if (!glfwInit()) {
System.out.println("GLFW failed to initialize");
System.exit(9);
}
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
final var window = glfwCreateWindow(800, 600, "LearnOpenGL", MemoryUtil.NULL, MemoryUtil.NULL);
if (window == 0) {
System.out.println("GLFW failed to create window");
glfwTerminate();
System.exit(9);
}
{
glfwMakeContextCurrent(window);
GL.createCapabilities();
glfwSetFramebufferSizeCallback(window, (long w, int width, int height) -> GL11.glViewport(0,0, width, height));
}
final var program = glCreateProgram();
{
final var vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, getResourceAsString("basic.vert"));
glCompileShader(vertex);
if(glGetShaderi(vertex, GL_COMPILE_STATUS) != GL_TRUE) {
System.out.printf("Failed to compile VERTEX Shader: %s%n", glGetShaderInfoLog(vertex, Integer.MAX_VALUE));
GL.destroy();
glfwTerminate();
System.exit(9);
}
glAttachShader(program, vertex);
final var fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, getResourceAsString("basic.frag"));
glCompileShader(fragment);
if(glGetShaderi(vertex, GL_COMPILE_STATUS) != GL_TRUE) {
System.out.printf("Failed to compile FRAGMENT Shader: %s%n", glGetShaderInfoLog(vertex, Integer.MAX_VALUE));
GL.destroy();
glfwTerminate();
System.exit(9);
}
glAttachShader(program, fragment);
glLinkProgram(program);
glDeleteShader(vertex);
glDeleteShader(fragment);
}
final var VAO = glGenVertexArrays();
final var VBO = glGenBuffers();
final var EBO = glGenBuffers();
{
glBindVertexArray(VAO);
float[] vertices = {
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left
};
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
int[] indices = { // note that we start from 0!
0, 1, 3, // first Triangle
1, 2, 3 // second Triangle
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.SIZE, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glfwShowWindow(window);
while (!glfwWindowShouldClose(window))
{
// input
// -----
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
// render
// ------
glClear(GL_COLOR_BUFFER_BIT);
// draw our first triangle
glUseProgram(program);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
glDeleteVertexArrays(VAO);
glDeleteBuffers(VBO);
glDeleteBuffers(EBO);
glDeleteProgram(program);
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
GL.destroy();
glfwTerminate();
}
private static String getResourceAsString(String name) {
try {
final var resource = Thread.currentThread().getContextClassLoader().getResource(name);
if (resource == null) return null;
final var path = Paths.get(resource.toURI());
return Files.readString(path);
} catch (Exception ex) {
return null;
}
}
}
The SIZE
constant represents the size in bits, but not in bytes. However, the stride argument of glVertexAttribPointer
specifies the byte offset between consecutive generic vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.SIZE, 0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.SIZE / 8, 0);
or
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.BYTES, 0);