[SOLVED] VBO and Shaders

Wow, if enabling CULL_FACE actually solves your problem instead of making it worse than something is really messed up there.
It would be a big help if you could post the latest version of your shaders so we can see what’s going on with them.
Is there any reason by the way why you’re not using VAOs? They would make your life so much easier, especially if you would like to use multiple VBOs at the same time.
Also you should comment out everything from your rendering method that isn’t related to the VBO cube to prevent accidents like rendering something in front of the cube.

Here’s a code sample from LWJGL on how to do rendering with VBOs and VAOs correctly, it should be easy to port to JOGL:


FloatBuffer yourVerticesInABuffer = BufferUtils.createFloatBuffer(50);
IntBuffer yourIndicesInABuffer = BufferUtils.createIntBuffer(50);
// Fill up the buffers with your vertices and indices...
// Flip the buffers when you're done
yourVerticesInABuffer.flip();
yourIndicesInABuffer.flip();
		
int vao = GL30.glGenVertexArrays();
int vbo = GL15.glGenBuffers();
int ibo = GL15.glGenBuffers();
GL30.glBindVertexArray(vao);
	GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
	GL15.glBufferData(GL15.GL_ARRAY_BUFFER, yourVerticesInABuffer, GL15.GL_STATIC_DRAW);
	GL20.glEnableVertexAttribArray(0);
	GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0L);
	GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ibo);
	GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, yourIndicesInABuffer, GL15.GL_STATIC_DRAW);
GL30.glBindVertexArray(0);

^That was the code for setting up the VAO and VBOs. You should only do this once.

And here the code the you should run every frame in your render method:


GL30.glBindVertexArray(vao);
	GL11.glDrawElements(GL11.GL_TRIANGLES, indexCount, GL11.GL_UNSIGNED_INT, 0L);
GL30.glBindVertexArray(0);

Your shader should look something like this (of course if you need something extra in there add it, this just the basics for rendering):


#version 330 core
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
layout(location=0) in vec3 in_Position;
void main(){
	gl_Position = projectionMatrix*modelViewMatrix*vec4(in_Position, 1.0);
}

Note: In the above example I’m using custom made matrices that are being sent to the shader as uniforms. You can also use the built-in matrices using older versions of GLSL or using it in compatibility mode instead of core, however the built-in matrices has been marked as deprecated in OGL3.0+.

Finally the fragment shader:


#version 330 core
layout(location=0) out vec4 out_Color;
void main(){
	out_Color = vec4(1.0, 0.0, 0.0, 1.0);
}

Because I set the [icode]out_Color[/icode] to [icode]vec4(1.0, 0.0, 0.0, 1.0)[/icode] everything will be red but you can change that by sending your own color data to the fragment shader and using that.

Hopefully that cleared up a few things for you, or provided some sort of a help. :slight_smile:

@PandaMoniumHUN: He’s given his shader code in the first post, and he’s not using VAOs.

@OP: What is happening here, I believe, is that you’ve got a large cube with your other two cubes inside. When you’re not culling the front face, the front face of the large cube sits between the camera and your other cubes, whereas the back side of the cube sits behind them. This means that when the front face is culled, you see the inside of the back face, and seeing the inside of the back face means the colours are the wrong way around.

Another diagnosis is that you’re not calling [icode]glEnable()[/icode] for your depth buffer, meaning that despite the large cube being closer to the camera, the cube drawn first gets drawn behind it, and the last drawn cube gets drawn at the front. Therefore when you move forward, the cube stands behind the camera and therefore draws both small cubes, despite you not being able to see the large cube.

I believe the reason this is happening is due to your mixing deprecated OpenGL with Modern OpenGL. It would seem that [icode]glTranslatef[/icode], [icode]glRotatef[/icode] and [icode]glScalef[/icode] (deprecated OpenGL) do not affect the model matrix of your cube being drawn through modern methods. This would explain why camera movement does not affect the large cube.

I think the solution to your problem is to entirely get rid of your deprecated code and stick with one version of OpenGL. This would probably entail learning about making your own matrices, although I don’t know how that is done in JOGL. Almost everyone on this forum, barring gouessej, uses LWJGL and there are many more resources about for using it. If I were you, I’d make the switch before it becomes too much of a pain.

I know that he gave us the shader code in the first post, I was asking for the current version of his shaders because he changed them.
And yes, I know that he isn’t using VAOs, if you read my post I was asking him why isn’t he. I provided an example with VAOs because they’re always good to use (unless you must stick to OGL ES or OGL 2.0 because of hardware limitations).

@OP: NegativeZero is right, do not mix legacy and modern OpenGL. Choose one and stick with it. Also for 3D applications always make sure that you enable [icode]GL_DEPTH_TEST[/icode] and you clear the [icode]GL_DEPTH_BUFFER_BIT[/icode] every frame.

I haven’t changed my shader code a lot, but I’ll post it anyway. I know that I shouldn’t be mixing legacy and modern, but I figured that I could slowly make changes, is this not the case?

@Panda, enabling CULL_FACE does not “fix” my problem. The small box is rendered in a different manner than the large cube that takes up the entire frustum. Also, what makes VAOs better than VBOs, other than updating the info? These are static meshes as this code will be for terrain.

Aren’t VAOs older than VBOs?

So now for another question. Since the “larger” box is using the same buffer to draw why would it take up the frustum? Even if I remove the multiplication on my vertices in the shader it still renders on the borders of the frustum.

What would cause this?
Shouldn’t it render the box around the camera when there aren’t any transformations?

I’m willing to bet that because the old transformation methods are used to move the camera around it is messing up the vertices, anyone think I’m right?

Anyway here’s the final shader code,

Frag:


in vec3 pass_color;
out vec4 out_color;

void main(void)
{
   out_color = vec4(pass_color.x, pass_color.y, pass_color.z, 1.0);
}

Vert:


in vec3 vert_pos;
in vec3 color;
out vec3 pass_color;

void main(void)
{
   gl_Position = gl_ModelViewProjectionMatrix * vec4(vert_pos.x, vert_pos.y, vert_pos.z, 1.0);
   pass_color = color;
}

VAO’s are different. nice to have, they shrink the code. but not really needed, they will not speed up much in small scenes. also, some ppl recommend to not use them - then again, maybe drivers are better now.

take a look at https://github.com/Groovounet/ogl-samples/blob/master/samples/gl-420-draw-base-instance.cpp … line 149 - 160. not a sample related directly to VAO’s, they use them on most of them.

how do you setup your modelview and projection matrices ? bet there is a bug lurking :slight_smile: i think, use opengl in any way that is possible. mixing “old” and “new” way does not have to be a problem.

Impossible. Your fragment shader must return a color.

What about in larger scenes? How many polys before they’d make a difference? Does it make a difference if the meshes are all static?

So that drawMesh method I posted is how I set up the modelview matrix for the two boxes, here’s the projection matrix setup in my camera class.


	public void draw(GL2 gl, GLU glu, int window_width, int window_height)
	{
		//Make sure the camera is set to perspective so we can draw 3D stuff
		gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
		gl.glLoadIdentity();
		glu.gluPerspective(m_fov, (float)(window_width) / (float)(window_height), m_z_near, m_z_far);
		
		gl.glRotatef(-m_pitch, 1.0f, 0.0f, 0.0f);
		gl.glRotatef(-m_yaw, 0.0f, 1.0f, 0.0f);
		gl.glTranslatef(-m_transform.getTranslate().m_x, -m_transform.getTranslate().m_y, -m_transform.getTranslate().m_z);
	}

Here’s my main draw method:


	public synchronized void display(GLAutoDrawable gld)
	{	
		camera.draw(g_gl, g_glu, g_window_width, g_window_height, camera.getPosition());

		bbox.m_mesh.drawMesh(g_gl, bbox.m_mesh, engine, tga.m_tex_id[0]);
		
		g_gl.glFlush();
	}

Preemptively here’s how I init openGL:


public void init(GLAutoDrawable gld)
	{	
		//Make a new glu and point to the gl for using OpenGL
		g_gl = gld.getGL().getGL2();
		g_glu = new GLU();

		g_gl.glClearColor(0.7f, 0.7f, 0.7f, 1.0f);//Set the default background color

		g_gl.glEnable(GL.GL_DEPTH_TEST);//Turn on z-buffer
		g_gl.glEnable(GL.GL_CULL_FACE);//Culls back faces, by default
		g_gl.glDepthFunc(GL.GL_LEQUAL);//Determines how to draw the face, if it's less-than or equal to, meaning draws back to front

	    int sample_buffers[] = new int[1];//storage for sample buffers
	    int samples_for_buffer[] = new int[1];//storage for samples on the buffer

	    g_gl.glGetIntegerv(GL.GL_SAMPLE_BUFFERS, sample_buffers, 0);//Gives us 1 Sample Buffer
	    g_gl.glGetIntegerv(GL.GL_SAMPLES, samples_for_buffer, 0);//Gives us Two Samples
	    g_gl.glEnable(GL.GL_MULTISAMPLE);//Enable Anti-Aliasing

		//give us nice perspective deformation
	    g_gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);

		//Clears the color buffer and the depth buffer for 3d
		g_gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		
		createVBO(g_gl);
		engine.initialize(g_gl, g_window_width, g_window_height);
}

it depends on calls in general. if you switch vertexPointers alot then it would be helping even when each mesh is just a small pack of vertices.

for fixed pipeline you need to seperate this into MODELVIEW and PROJECTION.

I use something like this for that …

public static void project(FloatBuffer projection,FloatBuffer modelview)
{
  GL11.glMatrixMode(GL11.GL_PROJECTION);
  GL11.glLoadMatrix(projection);
  GL11.glMatrixMode(GL11.GL_MODELVIEW);
  GL11.glLoadMatrix(modelview);
}

or

public static void project(FloatBuffer projection,FloatBuffer modelview)
{
  EXTDirectStateAccess.glMatrixLoadEXT(GL11.GL_PROJECTION,projection);
  EXTDirectStateAccess.glMatrixLoadEXT(GL11.GL_MODELVIEW,modelview);
}

looks good to me :slight_smile:

Why? I know I don’t load the Modelview matrix in here, but I load it in my subsequent drawMesh call and then push and pop the matrix on and off. So, essentially the camera would only have the Identity matrix every call. (I’m not saying this is good practice, just that I’m not seeing the difference)

Is that what my problem is?
Why does the other cube draw as expected?

[quote]I know I don’t load the Modelview matrix in here, but I load it in my subsequent drawMesh call and then push and pop the matrix on and off.
[/quote]
usually modelview gets all translations rotations and scaling + the lookat in 3D. values that relate to your screen/window go into projection.

are you actually switching into modelview matrix-mode when you draw the meshes ?

anyway, you’re right, you can get away with it, i mean using projection/modelview in whatever way - as long as it is consistent … from setting up the vertices all the way to the shaders. if you do all math by yourself it can work, but then you should not use any “fixed pipeline” functions.

[quote]Why?
[/quote]
that’s just what i have learned. if you use fixed functions … like fogging or pointsprite scaling for instance … without any shaders, opengl expects the matrices to be setup in a specific way so their multiplications and what not work as intended. there are more things that get screwed by that for sure :slight_smile:

anyway, back to the code. not 100% sure what is causing that psychedelic errors you get but i have the feeling that using gl_ModelViewProjectionMatrix in the vertex shader could be a source.

  • modelview matrix is not changed/set by, so it is probably identity … or worse, undefined.
  • with that, it is premultiplicated into gl_ModelViewProjectionMatrix … but it is not obvious in what way. (ab) (ba) (i guess mv*p)

maybe

  • in the shader - try using only gl_ProjectionMatrix and assume gl_ModelViewMatrix is identity.
  • or maybe … try reordering the multiplications. a bit try and error is always good :wink:

if you want to “emulate” fixed-pipleline behaviour then i think it should be :

gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;

i remember it did not work at some point … then i found out i swapped projection and modelview (by mistake) when i was writing the matrices. it worked fine up to some point, then some fixed-function kicked in. :cranky:

[quote]I’m not saying this is good practice
[/quote]
if it’s working it is good practice :wink:

[quote]Is that what my problem is?
[/quote]
i am not 100% sure, just remembering my own trouble with that back when. code looked similar to yours.

so, i hear : the “new” way is not using “fixed” and doint everything by yourself, not using any gl_* function in shaders. not sharing that opinion 100%, but if you want to try that, the way to go is basically …

  • use UBO’s to store matrices etc.
  • load things from UBO’s in any shader at any point you need.

i think that’s too much hassle to get stuff started and going … you know, when you draft some ideas. also the fixed pipeline has some nice things we can have for free. why not using it ?

i hope that helps you a bit :slight_smile:

OMG basil_! I never in a million years would’ve changed my gl_ModelView (mistakenly posted in the vert shader as gl_ModelViewProjection as I was playing with the code) to gl_Projection. It fixed the rendering issue! Whoa. K I really need to start using my own matrices, what an eye opener.

I’ve know this for a while, but haven’t ran into any problems until now. Cool.

Anyway thanks for everyone’s help on this, how can I mark this thread as solved?

You don’t need to do that, but you can put a [solved] in front of the title, either by modifing the first post and then modifying the title or by answering and editing the Subject line there, I don’t remember… I’ll try option 2 now, and if it didn’t work you need to modify the first post :slight_smile:

glad it works ;D