Related
I tried to make a cube in openGL and render a default texture on each side. I've been messing around with it for days but I cant get it to work. I really don't know what the problem is as I am convinced that my vertices and texture coordinates are right. What am I doing wrong?
These are my vertices, uv's and indices:
vertices = {
// front face
0.0f, 0.0f, 0.0f,
length, 0.0f, 0.0f,
length, height, 0.0f,
0.0f, height, 0.0f,
// back face
0.0f, 0.0f, width,
length, 0.0f, width,
length, height, width,
0.0f, height, width,
// left face
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, width,
0.0f, height, width,
0.0f, height, 0.0f,
// right face
length, 0.0f, 0.0f,
length, 0.0f, width,
length, height, width,
length, height, 0.0f,
// top face
0.0f, height, 0.0f,
length, height, 0.0f,
length, height, width,
0.0f, height, width,
// bottom face
0.0f, 0.0f, 0.0f,
length, 0.0f, 0.0f,
length, 0.0f, width,
0.0f, 0.0f, width
};
uvs = {
// front face
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
// back face
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
// left face
0.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 1.0f,
// right face
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
// top face
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
// bottom face
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f
};
indices = {
// front face
0, 1, 2,
2, 3, 0,
// right face
1, 5, 6,
6, 2, 1,
// back face
7, 6, 5,
5, 4, 7,
// left face
4, 0, 3,
3, 7, 4,
// bottom face
4, 5, 1,
1, 0, 4,
// top face
3, 2, 6,
6, 7, 3
};
This is my render method:
void Mesh::render() {
// Render the pyramid using OpenGL
view = glm::lookAt(Camera::getInstance().cameraPos, Camera::getInstance().cameraPos + Camera::getInstance().cameraFront, Camera::getInstance().cameraUp);
mvp = projection * view * model;
// Attach to program_id
glUseProgram(programId);
// Send mvp
glUniformMatrix4fv(uniformMvp, 1, GL_FALSE, glm::value_ptr(mvp));
// Send vao
glBindVertexArray(vao);
glBindTexture(GL_TEXTURE_2D, textureId);
glDrawElements(GL_TRIANGLES, indices.size() * sizeof(GLushort),
GL_UNSIGNED_SHORT, 0);
glBindVertexArray(0);
}
Vertexshader:
#version 430 core
in vec2 UV;
uniform sampler2D texsampler;
layout(location = 0) out vec4 gl_FragColor;
void main()
{
// Compute the diffuse and specular components for each fragment
vec3 test = texture2D(texsampler, UV).rgb;
// Write final color to the framebuffer
gl_FragColor = vec4(test, 1.0);
}
and the fragmentshader:
#version 430 core
// Uniform matrices
uniform mat4 mv;
uniform mat4 projection;
// Per-vertex inputs
in vec3 position;
// UV
in vec2 uv;
out vec2 UV;
void main()
{
// Calculate view-space coordinate
vec4 P = mv * vec4(position, 1.0);
// Calculate the clip-space position of each vertex
gl_Position = projection * P;
UV = uv;
}
Image of the cube:
I think this is enough information. Only the front and the back are textured normally and the rest is just like on the image.
Your texture coordinates are wrong, as commented:
// left face
0.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 1.0f,
// right face
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
This tells the computer to take a single line of pixels and stretch them across the entire face. The U coordinate is the same for the whole face. It does not advance from left to right across the texture.
Same for the top and bottom faces:
// top face
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
// bottom face
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f
the V does not advance, so the computer keeps reading the first or last row of the texture over and over. If you want to use the entire texture, then V should be 0 on one side of the texture, and 1 on the other side. Also note the direction where U changes must be different than the direction V changes - i.e. they can't change together - or else the compute only reads the diagonal pixels where U and V are equal.
Looking at OPs vertices, I noticed that there are 24 of them although a cube has 8 corners only. That's not surprising as coordinates for the same corner may correspond to distinct vertex coordinates depending on which face it belongs to.
Hence, it makes sense to define coordinates and corresponding texture coordinates per face, i.e. 6 faces with 4 corners each face -> 24 coordinates.
I enriched OPs code with enumeration:
vertices = {
// front face
0.0f, 0.0f, 0.0f, // 0
length, 0.0f, 0.0f, // 1
length, height, 0.0f, // 2
0.0f, height, 0.0f, // 3
// back face
0.0f, 0.0f, width, // 4
length, 0.0f, width, // 5
length, height, width, // 6
0.0f, height, width, // 7
// left face
0.0f, 0.0f, 0.0f, // 8
0.0f, 0.0f, width, // 9
0.0f, height, width, // 10
0.0f, height, 0.0f, // 11
// right face
length, 0.0f, 0.0f, // 12
length, 0.0f, width, // 13
length, height, width, // 14
length, height, 0.0f, // 15
// top face
0.0f, height, 0.0f, // 16
length, height, 0.0f, // 17
length, height, width, // 18
0.0f, height, width, // 29
// bottom face
0.0f, 0.0f, 0.0f, // 20
length, 0.0f, 0.0f, // 21
length, 0.0f, width, // 22
0.0f, 0.0f, width // 23
};
uvs = {
// front face
0.0f, 0.0f, // 0
1.0f, 0.0f, // 1
1.0f, 1.0f, // 2
0.0f, 1.0f, // 3
// back face
0.0f, 0.0f, // 4
1.0f, 0.0f, // 5
1.0f, 1.0f, // 6
0.0f, 1.0f, // 7
// left face
0.0f, 0.0f, // 8
0.0f, 0.0f, // 9
0.0f, 1.0f, // 10
0.0f, 1.0f, // 11
// right face
1.0f, 0.0f, // 12
1.0f, 0.0f, // 13
1.0f, 1.0f, // 14
1.0f, 1.0f, // 15
// top face
0.0f, 1.0f, // 16
1.0f, 1.0f, // 17
1.0f, 1.0f, // 18
0.0f, 1.0f, // 29
// bottom face
0.0f, 0.0f, // 20
1.0f, 0.0f, // 21
1.0f, 0.0f, // 22
0.0f, 0.0f // 23
};
But then I took a closer look what the indices look-up:
indices = {
// ...
// right face
1, 5, 6, // -> UV: { 1.0f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }
6, 2, 1, // -> UV: { 1.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f }
// ...
}
There are only two distinct values of texture coordinates but there should be four of them. Hence, it's not a surprise if the texture projection of that right face looks strange.
OP noted the wrong indices. This doesn't manifest in the geometry as the wrong indices address coordinates (vertices) with identical values. However, concerning the texture coordinates (uvs) these indices are just wrong.
According to the added index values, I corrected the indices for the right face:
indices = {
// ...
// right face
12, 13, 14,
14, 15, 12,
// ...
}
The indices of the top face are defined correctly but the other faces have to be checked as well. (I leave this as "homework" to OP. Or, like a colleague of mine used to say: Not to punish just to practice.) ;-)
On the second glance, I realized that OP's texture coordinates are wrong as well.
To understand how texture coordinates work:
There is a uv coordinate system applied to the image with
(0, 0) … the lower left corner
(1, 0) … the lower right corner
(0, 1) … the upper left corner
of the image.
taken from opengl-tutorial – Tutorial 5: A Textured Cube
Hence, using my
uvs = {
// ...
// right face
1.0f, 0.0f, // 12
1.0f, 0.0f, // 13
1.0f, 1.0f, // 14
1.0f, 1.0f, // 15
// ...
};
provides two times the lower right corner and two times the upper right corner. The result of such texture projection are stripes instead of bricks.
A better result should be achieved by repeating the texture coordinates of the front face 6 times:
uvs = {
// ...
// right face
0.0f, 0.0f, // 12
1.0f, 0.0f, // 13
1.0f, 1.0f, // 14
0.0f, 1.0f, // 15
// ...
};
I tried rendering a cube.
These are the vertices:
unsigned int indices[] = {
0, 1, 2,
3, 1, 2,
0, 1, 5,
0, 4, 5,
2, 3, 7,
2, 7, 6,
4, 5, 6,
6, 7, 5,
2, 0, 6,
0, 4, 6,
3, 1, 7,
1, 7, 5
};
float vertices[] = {
1.0f, 1.0f, 0.0f, //0
1.0f, -1.0f, 0.0f, //1
-1.0f, 1.0f, 0.0f, //2
-1.0f, -1.0f, 0.0f, //3
1.0f, 1.0f, 2.0f, //4
1.0f, -1.0f, 2.0f, //5
-1.0f, 1.0f, 2.0f, //6
-1.0f, -1.0f, 2.0f //7
};
When I added color to my cube, I only had to define the colors 8 times:
float colors[] = {
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f
};
My first question is, does that mean that each color in my array is for a different vertex?
My second question is that I read somewhere and I saw this: "So the fragment shader itself doesn't actually operate on each fragment, it appears to operate on 3 "vertices" and then some other part of the pipeline interpolates whatever the pixel is." Is this text correct?
I'm creating a voxel game and want to highlight the block that the camera is pointing at with a wireframe model. However, I can't for the life of me figure out why this isn't showing up. I've set the position of the model to a static location.
renderer:
constexpr std::array<float, 72> VERTICES =
{
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f
};
constexpr std::array<int, 24> INDICES =
{
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23
};
SelectedBlockRenderer::SelectedBlockRenderer():
should_render(false),
shader("shader/selectedBlockVertexShader.txt", "shader/selectedBlockFragmentShader.txt")
{
shader.set_uniforms({"position", "projectionView"});
glGenVertexArrays(1, &vao_id);
glGenBuffers(1, &v_buffer_id);
glGenBuffers(1, &i_buffer_id);
glBindVertexArray(vao_id);
glBindBuffer(GL_ARRAY_BUFFER, v_buffer_id);
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), &VERTICES[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, nullptr);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), &INDICES[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
SelectedBlockRenderer::~SelectedBlockRenderer()
{
}
void SelectedBlockRenderer::render(const Display& display, const Camera& camera)
{
if (!should_render) return;
glDisable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glLineWidth(10.0f);
glm::mat4 projection_view = display.get_projection_matrix() * camera.get_view();
shader.activate();
shader.load_uniform("projectionView", projection_view);
shader.load_uniform("position", glm::vec3(x, y, z));
glBindVertexArray(vao_id);
glEnableVertexAttribArray(0);
glDrawElements(GL_QUADS, INDICES.size(), GL_UNSIGNED_INT, nullptr);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
shader.deactivate();
glEnable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
void SelectedBlockRenderer::free()
{
shader.free();
glDeleteBuffers(1, &v_buffer_id);
glDeleteBuffers(1, &i_buffer_id);
glDeleteVertexArrays(1, &vao_id);
}
Shader code:
#version 400 core
layout(location = 0) in vec3 vertex;
uniform mat4 projectionView;
uniform vec3 position;
void main () {
gl_Position = projectionView * vec4(position, 1.0);
}
Fragment shader:
#version 400 core
out vec4 fragment;
void main () {
fragment = vec4(0.0, 0.0, 0.0, 1.0);
}
I know that the Shader class works because I've used it in all of the other renderers. Here's the relevant main.cpp code:
void main () {
SelectedBlockRenderer sb_renderer;
while(!display.closed) {
if (timer.update_requested) {
//update display and camera
sb_renderer.render(display, camera);
}
}
sb_renderer.free();
}
If any other code is required I'd be happy to share it.
I must be missing something really obvious. If anyone has any idea I'd love to hear it.
position is a uniform variable. The name of the vertex coordinate attribute is vertex.
The position of the current vertex (gl_Position) should be set by a function of the vertex coordinate. e.g.:
gl_Position = projectionView * vec4(vertex, 1.0);
or
gl_Position = projectionView * vec4(vertex + position, 1.0);
So by default, libgdx renders both sides of a face. When you make a cube using a mesh (supplying vertices and indices), it renders the faces inside the cube (wasting render time).
I want to stop this because it wastes render time when I have x amount of voxels on the screen.
I have tried face culling but it's completely broken. It removes the sides and everything.
Here's my code:
public void setup() {
String vertexShader = "attribute vec4 a_position; \n" + "attribute vec4 a_color;\n" + "attribute vec2 a_texCoord0;\n" + "uniform mat4 u_projTrans;\n" + "varying vec4 v_color;" + "varying vec2 v_texCoords;" + "void main() \n" + "{ \n" + " v_color = vec4(1, 1, 1, 1); \n" + " v_texCoords = a_texCoord0; \n" + " gl_Position = u_projTrans * a_position; \n" + "} \n";
String fragmentShader = "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "varying vec4 v_color;\n" + "varying vec2 v_texCoords;\n" + "uniform sampler2D u_texture;\n" + "void main() \n" + "{ \n" + " gl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n" + "}";
shader = new ShaderProgram(vertexShader, fragmentShader);
float[] vertices = { -0.5f, 0.5f, -0.5f, 0, 0, -0.5f, -0.5f, -0.5f, 0, 1, 0.5f, -0.5f, -0.5f, 1, 1, 0.5f, 0.5f, -0.5f, 1, 0, -0.5f, 0.5f, 0.5f, 0, 0, -0.5f, -0.5f, 0.5f, 0, 1, 0.5f, -0.5f, 0.5f, 1, 1, 0.5f, 0.5f, 0.5f, 1, 0, 0.5f, 0.5f, -0.5f, 0, 0, 0.5f, -0.5f, -0.5f, 0, 1, 0.5f, -0.5f, 0.5f, 1, 1, 0.5f, 0.5f, 0.5f, 1, 0, -0.5f, 0.5f, -0.5f, 0, 0, -0.5f, -0.5f, -0.5f, 0, 1, -0.5f, -0.5f, 0.5f, 1, 1, -0.5f, 0.5f, 0.5f, 1, 0, -0.5f, 0.5f, 0.5f, 0, 0, -0.5f, 0.5f, -0.5f, 0, 1, 0.5f, 0.5f, -0.5f, 1, 1, 0.5f, 0.5f, 0.5f, 1, 0, -0.5f, -0.5f, 0.5f, 0, 0, -0.5f, -0.5f, -0.5f, 0, 1, 0.5f, -0.5f, -0.5f, 1, 1, 0.5f, -0.5f, 0.5f, 1, 0
};
short[] indices = { 0, 1, 3, 3, 1, 2, 4, 5, 7, 7, 5, 6, 8, 9, 11, 11, 9, 10, 12, 13, 15, 15, 13, 14, 16, 17, 19, 19, 17, 18, 20, 21, 23, 23, 21, 22
};
texture = new Texture("texture.png");
Gdx.input.setCursorCatched(false);
mesh = new Mesh(true, vertices.length / 3, indices.length, VertexAttribute.Position(), VertexAttribute.TexCoords(0));
mesh.setVertices(vertices);
mesh.setIndices(indices);
GL40.glEnable(GL40.GL_DEPTH_TEST);
//GL40.glEnable(GL40.GL_CULL_FACE);
//GL40.glCullFace(GL40.GL_BACK);
}
public void render() {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
cameraController.update();
texture.bind();
shader.begin();
shader.setUniformMatrix("u_projTrans", camera.combined);
shader.setUniformi("u_texture", 0);
mesh.render(shader, GL46.GL_TRIANGLES);
shader.end();
}
When Face Culling is enabled then then primitives are discarded, dependent on the winding order of the vertex coordinates, as seen from the point of view.
For this a winding order for the front faces is defined, by glFrontFace. By default this is counter clockwise.
If back faces sculling is enabled:
GL40.glEnable(GL40.GL_CULL_FACE);
GL40.glCullFace(GL40.GL_BACK);
then the polygons which have the opposite winding order (clockwise) are discarded.
According to your vertex coordinates
float[] vertices = {
-0.5f, 0.5f, -0.5f, 0, 0,
-0.5f, -0.5f, -0.5f, 0, 1,
0.5f, -0.5f, -0.5f, 1, 1,
0.5f, 0.5f, -0.5f, 1, 0,
-0.5f, 0.5f, 0.5f, 0, 0,
-0.5f, -0.5f, 0.5f, 0, 1,
0.5f, -0.5f, 0.5f, 1, 1,
0.5f, 0.5f, 0.5f, 1, 0,
0.5f, 0.5f, -0.5f, 0, 0,
0.5f, -0.5f, -0.5f, 0, 1,
0.5f, -0.5f, 0.5f, 1, 1,
0.5f, 0.5f, 0.5f, 1, 0,
-0.5f, 0.5f, -0.5f, 0, 0,
-0.5f, -0.5f, -0.5f, 0, 1,
-0.5f, -0.5f, 0.5f, 1, 1,
-0.5f, 0.5f, 0.5f, 1, 0,
-0.5f, 0.5f, 0.5f, 0, 0,
-0.5f, 0.5f, -0.5f, 0, 1,
0.5f, 0.5f, -0.5f, 1, 1,
0.5f, 0.5f, 0.5f, 1, 0,
-0.5f, -0.5f, 0.5f, 0, 0,
-0.5f, -0.5f, -0.5f, 0, 1,
0.5f, -0.5f, -0.5f, 1, 1,
0.5f, -0.5f, 0.5f, 1, 0
};
and indices
short[] indices = {
0, 1, 3, 3, 1, 2,
4, 5, 7, 7, 5, 6,
8, 9, 11, 11, 9, 10,
12, 13, 15, 15, 13, 14,
16, 17, 19, 19, 17, 18,
20, 21, 23, 23, 21, 22
};
This means that the 1st, 3rd and 5th row of indices have the wrong winding order. It has to be:
short[] indices = {
0, 3, 1, 3, 2, 1,
4, 5, 7, 7, 5, 6,
8, 11, 9, 11, 10, 9,
12, 13, 15, 15, 13, 14,
16, 19, 17, 19, 18, 17,
20, 21, 23, 23, 21, 22
};
I just want to do a simple Gouraud Shading with some different colors on my objects. Basically my problem is, that I can't get the color values into the shaders, it just renders black. If I define a vector in the shader as a color for the whole object it works fine.
Main program:
protected void initOpenGL() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
startTime = Sys.getTime();
m = new Matrix4f();
m.m00 = 1;
m.m11 = 1;
m.m22 = -(101.0f / 99);
m.m32 = -(200.0f / 99);
m.m23 = -1;
m.m33 = 0;
makeCube();
sp = new ShaderProgram("gouraud");
glBindAttribLocation(sp.getId(), 0, "corners");
glBindAttribLocation(sp.getId(), 1, "colors");
}
#Override
protected void render() {
gamma = gamma + 1;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Matrix4f newMat = new Matrix4f(m);
Matrix4f.translate(new Vector3f(0, 0, -5), newMat, newMat);
newMat.rotate(gamma/100, new Vector3f(0, 1, 0));
newMat.rotate(gamma/200, new Vector3f(1, 0, 0));
FloatBuffer fb = BufferUtils.createFloatBuffer(16);
newMat.store(fb);
fb.flip();
GL20.glUniformMatrix4(GL20.glGetUniformLocation(sp.getId(), "matrix"),
false, fb);
GL20.glUseProgram(sp.getId());
glBindVertexArray(vaoId);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawArrays(GL_QUADS, 0, corners.length/3);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
}
private void makeCube(){
corners = new float[] {
// cube
// front
-1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1,
// left
-1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1,
// bottom
-1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1,
// right
1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1,
// top
-1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1,
// back
-1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1,
};
FloatBuffer eckenBuffer = BufferUtils.createFloatBuffer(corners.length);
eckenBuffer.put(corners);
eckenBuffer.flip();
vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
int vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, eckenBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
colors = new float[] {
// front
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// right
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// back
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
// left
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// top
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
// bottom
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f };
FloatBuffer colorBuffer = BufferUtils.createFloatBuffer(colors.length);
colorBuffer.put(colors);
colorBuffer.flip();
int vboIdB = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboIdB);
glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
Shader:
Vertex
#version 150
in vec4 corners;
in vec4 colors;
vec4 colorTest = vec4(1.0,0.0,0.0,1.0);
out vec4 colorToFrag;
uniform mat4 matrix;
void main(void) {
colorToFrag = colors ;
gl_Position = matrix * corners;
}
Fragment
#version 150
in vec4 colorToFrag;
out vec4 colorOut;
void main(void) {
colorOut = colorToFrag;
}
You didn't post the code for your shader compilation/linking, but since you call glBindAttribLocation but do not call glLinkProgram in the rest of the code, I make the educated guess that the linking takes place only in the ShaderProgram constructor.
The glBindAttribLocation calls will only affect any linking operations that come after it (obviously). So your location bindings are not effective at all - the GL assigns them.
Now if you don't use the colors attribute in the shader, it will be optimized out and the attribute will not be active - so it will get no location at all, and corners is likely to get index 0, as you expect it. Note that the GL is not required to assing attribute locations sequentially, beginning from zero, but most do.
If you actually use 'colors', it might end up with location 0, breaking your rendering completely.
As another side note: on nvidia, I observed that attribute locations assigned by the GL seem to actually be lexicographically ordered by the variable names in the shader - so 'colors' would come before 'corners'. I'm not sure if that was just a coincidence or how other implementations handle that.