Related
I have been learning OpenGL recently and I have got bit confused about shaders and the VBOs.
Basically, I am confused on how my vertex shader knows about the colour and position data in my VBOs.
To my knowledge glBindAttribLocation(program, attribute, variable); is what sets the attribute in the shader but when I comment out that code, the triangle still renders fine with it's colours.
Here is my code:
public static void main(String[] args) {
String vertexSource = "#version 400 core\n"
+ "in vec3 position;\n"
+ "in vec3 colour;\n"
+ "out vec3 vertexColour;\n"
+ "uniform mat4 model;\n"
+ "uniform mat4 view;\n"
+ "uniform mat4 projection;\n"
+ "void main() {\n"
+ "vertexColour = colour;\n"
+ "mat4 mvp = projection * view * model;\n"
+ "gl_Position = vec4(position, 1.0);\n"
+ "}\n";
String fragmentSource = "#version 400 core\n"
+ "in vec3 vertexColour;\n"
+ "out vec4 colours;\n"
+ "void main()\n"
+ "{\n"
+ " colours = vec4(vertexColour, 1);\n"
+ "}";
glfwSetErrorCallback(errorCallBack);
if (!glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
glfwWindowHint(GLFW_VISIBLE, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
long window = glfwCreateWindow(640, 480, "my window!", 0, 0);
glfwSetKeyCallback(window, keyCallback);
if (window == 0) {
glfwTerminate();
throw new RuntimeException("Failed to create the GLFW window");
}
glfwMakeContextCurrent(window);
GL.createCapabilities();
float[] vertexPoints = {
0f,0.5f,0f,
-0.5f,-0.5f,0f,
0.5f,-0.5f,0f
};
float[] colours = {
0.1f,0.5f,0.5f,
0.3f,0.7f,0.9f,
0.4f,0.9f,0.1f
};
ArrayList<Integer> vaos = new ArrayList<Integer>();
ArrayList<Integer> vbos = new ArrayList<Integer>();
int vaoID = glGenVertexArrays();
vaos.add(vaoID);
glBindVertexArray(vaoID);
FloatBuffer vertices = BufferUtils.createFloatBuffer(vertexPoints.length);
vertices.put(vertexPoints);
vertices.flip();
int vboID = GL33.glGenBuffers();
vbos.add(vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
//add it to the vao at position 0, size 3, with data types of float, normalised = false,
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
//unbind currently bound vbo
glBindBuffer(GL_ARRAY_BUFFER, 0);
//and one for the colour data
vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, colours, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//finished with vao now unbind it
glBindVertexArray(0);
//vao and vbo stuff is now finished with
//now for the shader stuff
int vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderID, vertexSource);
glCompileShader(vertexShaderID);
if (!checkForSuccess(vertexShaderID)) {
glfwTerminate();
throw new IllegalStateException("vertex shader failed: " + glGetShaderInfoLog(vertexShaderID));
}
int fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderID, fragmentSource);
glCompileShader(fragmentShaderID);
if (!checkForSuccess(vertexShaderID)) {
glGetShaderInfoLog(vertexShaderID);
glfwTerminate();
throw new IllegalStateException("fragment shader failed");
}
//shader program
int shaderProgramID = glCreateProgram();
glAttachShader(shaderProgramID, vertexShaderID);
glAttachShader(shaderProgramID, fragmentShaderID);
glLinkProgram(shaderProgramID);
//error test
int status = glGetProgrami(shaderProgramID, GL_LINK_STATUS);
if (status != GL_TRUE) {
glfwTerminate();
throw new RuntimeException(glGetProgramInfoLog(shaderProgramID));
}
glUseProgram(shaderProgramID);
//setting position attribute in the shader:
int positionAttribute = glGetAttribLocation(shaderProgramID, "position");
glEnableVertexAttribArray(positionAttribute);
glBindAttribLocation(shaderProgramID, positionAttribute, "position");
//setting colour attribute in the shader:
int colourAttribute = glGetAttribLocation(shaderProgramID, "colour");
glEnableVertexAttribArray(colourAttribute);
glBindAttribLocation(shaderProgramID, colourAttribute, "colour");
glClearColor(0.5f,0.5f,0.5f,1f);
//this will create a wire frame view
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glfwShowWindow(window); //optional
while (!glfwWindowShouldClose(window)) {
double time = glfwGetTime();
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vaoID);
//enables the position attribute in the vertex shader
glEnableVertexAttribArray(0);
//enables the colour attribute in the vertex shader
glEnableVertexAttribArray(1);
glDrawArrays(GL_TRIANGLES, 0, vertexPoints.length);
//disables the position and colour attribute in the vertex shader
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers(window);
}
//clear vaos and vbos
for (int vao : vaos) {
glDeleteVertexArrays(vao);
}
for (int vbo : vbos) {
glDeleteBuffers(vbo);
}
//delete shaders
glDetachShader(shaderProgramID, vertexShaderID);
glDetachShader(shaderProgramID, fragmentShaderID);
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
glDeleteProgram(shaderProgramID);
Callbacks.glfwFreeCallbacks(window);
glfwDestroyWindow(window);
glfwTerminate();
}
I have provided my full code file on github (250 lines) here: https://github.com/OneEgg42/opengl
Would someone be so kind and explain to me how this works?
Thanks in advance!
The relation between a VBO and a shader is not established by glBindAttribLocation.
The relevant lines are actually
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
where you tell OpenGL that the attribute with location 0 (the first parameter in the first glVertexAttribPointer call) should read the first three floats from vboID.
glBindAttribLocation is responsible for binding a certain attribute to a specific location. Since this has to be done before linking the shader, they aren't doing anything in your code. Even more so, because this code tells the attribute to use the location that it already has:
int positionAttribute = glGetAttribLocation(shaderProgramID, "position");
glEnableVertexAttribArray(positionAttribute);
glBindAttribLocation(shaderProgramID, positionAttribute, "position");
You basically query the location, and then assign the location again to the attribute.
Two side notes:
At the moment your code works by pure luck. You assume in the glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0); line that the "position" attribute is at location 0, which it probably is as long as it is the first attribute written in the shader. Same for colors. It is very likely that your code breaks when you exchange the order of the two attribute definitions in your shader.
Either query the attribute location with glGetAttribLocation and use the result instead of 0 and 1, or use glBindAttribLocation before linking to make sure that the attributes are at the location you expect them.
The calls to glEnableVertexAttribArray should be in the VAO setup code and not in the render loop.
Setup:
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
Render:
glBindVertexArray(vaoID);
glDrawArrays(GL_TRIANGLES, 0, vertexPoints.length);
I am relatively new to OpenGL, so this question might seem a bit trivial. I have this code in my Main.java, which is supposed to output a rectangle with the texture of the image on it:
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
int VBO = glGenBuffers(), VAO = glGenVertexArrays(), EBO = glGenBuffers();
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, false, 8, 0);
glEnableVertexAttribArray(0);
// color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, false, 8, 2);
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_FLOAT, false, 8, 5);
glEnableVertexAttribArray(2);
Texture texture = null;
try {
log.info("Loading texture");
texture = Texture.loadTexture("texture.png");
} catch (IOException e) {
log.severe("Texture loading failed due to IOException: " + e.getMessage());
e.printStackTrace();
}
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
if(mainProgram != null) {
mainProgram.use();
}
glBindTexture(GL_TEXTURE_2D, texture.getId());
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//...
}
My shaders are the following:
Vertex Shader:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout(location = 2) in vec2 aTexCoord;
out vec3 vertexColor;
out vec2 texCoord;
void main()
{
gl_Position = vec4(aPos , 1.0);
vertexColor = aColor;
texCoord = aTexCoord;
}
Fragment Shader:
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCoord;
// texture sampler
uniform sampler2D texture1;
void main()
{
FragColor = texture(texture1, TexCoord);
}
The Texture class referenced above is the following:
public class Texture {
public static Texture loadTexture(String fileName) throws IOException{
//load png file
PNGDecoder decoder = new PNGDecoder(new java.io.FileInputStream(new File("C:/Users/Using/Absolute/Paths/For/Demonstration/texture.png")));
//create a byte buffer big enough to store RGBA values
ByteBuffer buffer = BufferUtils.createByteBuffer(4 * decoder.getWidth() * decoder.getHeight());
//decode
decoder.decode(buffer, decoder.getWidth() * 4, PNGDecoder.Format.RGBA);
//flip the buffer so its ready to read
buffer.flip();
//create a texture
int id = glGenTextures();
//bind the texture
glBindTexture(GL_TEXTURE_2D, id);
//tell opengl how to unpack bytes
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//set the texture parameters, can be GL_LINEAR or GL_NEAREST
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//upload texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// Generate Mip Map
glGenerateMipmap(GL_TEXTURE_2D);
return new Texture(id);
}
private int id;
public Texture(int id){
this.id = id;
}
public int getId(){
return id;
}
}
Note that the path of the texture image is not the problem, as the code works without any Exceptions or Compiler errors. The PNGDecoder i used can be found here.
The stride and offset argument must be set in bytes when specifying the array of generic vertex attribute data by glVertexAttribPointer.
Furthermore, the uv coordinates are the 7th and 8th element in the attribute tuple:
glVertexAttribPointer(0, 3, GL_FLOAT, false, 8, 0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 8*4, 0);
glVertexAttribPointer(1, 3, GL_FLOAT, false, 8, 2);
glVertexAttribPointer(1, 3, GL_FLOAT, false, 8*4, 3*4);
glVertexAttribPointer(2, 2, GL_FLOAT, false, 8, 5);
glVertexAttribPointer(2, 2, GL_FLOAT, false, 8*4, 6*4);
My skybox is displayed, but does not display the textures that I load from the image. Instead, it shows the black color.
I am using a render with MultisampledFbo support.
My texture loading code looks like this:
private int loadSkyboxTextures(){
int texID = glGenTextures();
glBindTexture(GL_TEXTURE_CUBE_MAP, texID);
for(int i = 0; i < TEXTURE_FILES.length; i++){
InputStream file = getClass().getResourceAsStream(TEXTURE_FILES[i]);
byte[] pixelData = new byte[0];
try {
pixelData = new byte[file.available()];
file.read(pixelData);
} catch (IOException e) {
e.printStackTrace();
}
ByteBuffer byteBuffer = ByteBuffer.wrap(pixelData);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 512, 512, 0,
GL_RGB, GL_UNSIGNED_BYTE, byteBuffer);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
return texID;
}
Cube Render Code:
private void drawSkybox(){
glEnable(GL_TEXTURE_CUBE_MAP);
glDepthMask(false);
glGenBuffers(vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, POINTS, GL_STATIC_DRAW);
glGenVertexArrays(vao);
glBindVertexArray(vao[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.BYTES, NULL);
glEnableVertexAttribArray(0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
glDrawArrays(GL_TRIANGLES, 0, 36);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glDepthMask(true);
glBindBuffer (GL_ARRAY_BUFFER,0);
glDisable(GL_TEXTURE_CUBE_MAP);
}
The cube rendering call in the main render function:
glMatrixMode(GL_PROJECTION);
glOrtho(-max, max, -1, 1, 10, -10);
glRotated(cameraX, 1f, 0f, 0);
glRotated(cameraY, 0f, 1f, 0);
glGetFloatv(GL_PROJECTION_MATRIX, pm);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawSkybox();
glLoadIdentity();
...
//render other objects
Legacy OpenGL's texturing has to be enabled. To perform cube-mapped texturing, GL_TEXTURE_CUBE_MAP has to be enabled (see glEnable):
glEnable(GL_TEXTURE_CUBE_MAP);
Note, for cube map textures, the texture coordinates are 3-dimensional and treated as a vector form the center of the cube map.
I've got some code that's supposed to render text to a texture so that I don't have to render each character each draw step, and can instead use the rendered texture. However, my code does not as it's supposed to, and the texture is left blank. After a few hours of trying different things, I cannot figure it out, and so I bring the question to you.
I'm fairly certain the problem is somewhere in this code chunk below, but if you think it's not, I'll gladly post whatever other samples of code you would like. I just really want to get this done already. The exact problem is that the created texture is blank, and never is rendered to (it seems like). I've tried just drawing one massive quad on it, and that didn't seem to work either.
Edit: After flipping the buffer, I can get some color to be rendered to the texture, but it's all just one color (which makes me think it's only sampling one pixel), and I can't figure out how to get the actual image I want to render to show on it.
public Text(String text, int x, int y, Font font, float size, GUIComponent parent, Binding binding) {
super(null, x, y, font.getStringWidth(size, text), font.getStringHeight(size), parent, binding, false);
this.text = text;
this.font = font;
this.width = font.getStringWidth(size, text);
this.height = font.getStringHeight(size);
int fbo = glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
int tex = glGenTextures();
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);
IntBuffer intBuffer = BufferUtils.createIntBuffer(1);
intBuffer.put(GL_COLOR_ATTACHMENT0);
intBuffer.flip();
glDrawBuffers(intBuffer);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
throw new RuntimeException("Something really bad happened");
}
//RENDER
RenderUtil.recalibrate(width, height, 1.0f); //Does glViewport(width, height), and some matrix stuff
Camera.updateShader("textshader", "projection", false); //Update projection matrix
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
int width = 0;
float f = this.width / 1.0f;
int charWidth = 0;
for (char c : text.toCharArray()) {
font.bind(0, c % 256); // calls glBindTexture, this works, have tested
//ResourceManager.getTexture("grassroadedger1").bind(0, 0);
charWidth = font.getCharWidth(size, c);
//float[] verts = new float[] { -1f, 1f, 1f, 1f, 1f, -1f, -1f, -1f };
float[] verts = new float[] { -1.0f + (width / f), 1.0f, 1.0f + ((width + charWidth) / f), 1.0f, 1.0f + ((width + charWidth) / f), -1.0f, -1.0f + (width / f), -1.0f };
width += charWidth;
glBindBuffer(GL_ARRAY_BUFFER, vertexPointer);
glBufferSubData(GL_ARRAY_BUFFER, 0, RenderUtil.createBuffer(verts));
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, RenderUtil.getIndicesPointer());
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
//END
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
RenderUtil.recalibrate(Window.getWidth(), Window.getHeight(), LuminaEngine.getGlobalImageScale());
this.setTexture(new Texture(tex, "text_"+size+"_"+text));
}
FragmentShader
#version 330 core
in vec2 uv;
layout(location = 0) out vec4 color;
uniform sampler2D sampler;
void main(){
color = texture2D( sampler, uv );
}
Vertex Shader
#version 330 core
layout(location = 0) in vec3 vertices;
layout(location = 1) in vec2 textures;
out vec2 uv;
uniform mat4 projection;
void main(){
gl_Position = projection * vec4(vertices,1);
uv = textures;
}
Edit: After flipping the intBuffer for drawBuffers, I can get some things to appear, mostly just a big blue square. Progress nonetheless
You never defined an array of generic vertex attribute data for the texture coordinates (in vec2 textures;).
Add something like this to your code:
int texCoordBuffer;
glGenBuffers(1, texCoordBuffer);
float[] texCoord = new float[] { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer);
glBufferData(GL_ARRAY_BUFFER, RenderUtil.createBuffer(texCoord), GL_STATIC_DRAW);
int tax_attr_i = 1; // layout(location = 1) in vec2 textures;
glVertexAttribPointer(tax_attr_i, 2, GL_FLOAT, false, 0, 0);
In this code i try to render a simple triangle on the screen, but it only shows the red background, i have tried every thing i know to debug but i just can't understand why it doesn't work
Hope somebody can help me, thanks in advance.
public float vertices[] = new float[]
{
-0.5f,-0.5f,0.0f,1.0f,
0.0f,1.0f,0.0f,1.0f,
0.0f,0.5f,0.0f,1.0f,
0.0f,1.0f,0.0f,1.0f,
0.5f,-0.5f,0.0f,1.0f,
0.0f,1.0f,0.0f,1.0f
};
public TEST()
{
}
public int start() throws IOException
{
glfwInit();
long window = glfwCreateWindow(1000, 1000, "HAHA", NULL, NULL);
glfwMakeContextCurrent(window);
glfwShowWindow(window);
GLFWKeyCallback keycallback = new GLFWKeyCallback()
{
#Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
if(key==GLFW_KEY_ESCAPE&&action==GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
}
};
glfwSetKeyCallback(window,keycallback );
GLFWErrorCallback errorcallback = new GLFWErrorCallback()
{
#Override
public void invoke(int error, long description)
{
System.out.println("ERROR CODE: " + error + " ERROR DESCRITPION: "+description);
}
};
glfwSetErrorCallback(errorcallback);
GL.createCapabilities();
glViewport(0, 0, 1000, 1000);
//////////////////////////
int VAO = glGenVertexArrays();
int VBO = glGenBuffers();
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
FloatBuffer buffer = FloatBuffer.allocate(vertices.length);
buffer.clear();
buffer.put(vertices);
buffer.flip();
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, false, 8, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 8, 4);
glEnableVertexAttribArray(1);
buffer.clear();
buffer=null;
System.gc();
glBindVertexArray(0);
///////////////////////
///////////////////////
LoadFile loader = new LoadFile("res/shader.vs", "res/shader.frag");
int vertexshader = glCreateShader(GL_VERTEX_SHADER);
int fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vertexshader, loader.readVertex());
glShaderSource(fragmentshader, loader.readFragment());
glCompileShader(vertexshader);
glCompileShader(fragmentshader);
System.out.println(glGetShaderInfoLog(vertexshader));
System.out.println(glGetShaderInfoLog(fragmentshader));
int program = glCreateProgram();
glAttachShader(program, vertexshader);
glAttachShader(program, fragmentshader);
glLinkProgram(program);
glDeleteShader(vertexshader);
glDeleteShader(fragmentshader);
System.out.println(glGetProgramInfoLog(program));
///////////////////////////
boolean running=true;
while(running&&glfwWindowShouldClose(window)==GLFW_FALSE)
{
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glUseProgram(program);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
glfwSwapInterval(1);
glfwSwapBuffers(window);
}
System.out.println(glGetError());
glfwTerminate();
return 0;
}
My vertex shader
#version 330 core
layout (location = 0) in vec4 position;
layout (location = 1) in vec4 colorin;
out vec4 colorout;
void main()
{
gl_Position = position;
colorout=colorin;
}
My fragment shader
#version 330 core
out vec4 color;
in vec4 colorout;
void main()
{
color = colorout;
}
EDIT: I just saw that this was 1 day old question.. but oh well..
I have my suspicion here:
FloatBuffer buffer = FloatBuffer.allocate(vertices.length);
buffer.clear();
buffer.put(vertices);
buffer.flip();
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
Have you tried replacing this with BufferUtils from lwjgl library itself? It would turn out to be something like this:
FloatBuffer buff = BufferUtils.createFloatBuffer(vertices.length);
buff.put(vertices);
buff.flip();
Or, if you want the manual one..
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * Float.BYTES);
byteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
floatBuffer.put(vertices);
floatBuffer.flip();
Stride and offsets are specified in bytes, so the stride for 8 floats representing 2 vec4s should be 32, and the offset for the color should be 16.
glVertexAttribPointer(0, 4, GL_FLOAT, false, 32, 0);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 32, 16);