Advertisement

Minimum of 66 verts?

Started by November 12, 2019 11:15 PM
56 comments, last by Bozemoto 4 years, 10 months ago

Hi, so I've been experimenting with openGL in my spare time, I'm a mechanics programmer by day.
And I was getting a nullptr access crash in glDrawArrays, I couldn't figure out why as I had other things drawing fine. 
Then I tried increasing the number of triangles my cone code was generating and suddenly it worked.
Is there a minimum buffer size that you need to request when using vbos?
Seems like the minimum that will work on my computer is 66 vertices, with my current code at least.

If anyone has any insight into this I'd appreciate the clarity.

Video Game Programmer.
5 years in industry.

41 minutes ago, Net-Ninja said:

Is there a minimum buffer size that you need to request when using vbos?

Probably not since it would break every beginners first triangle program.

🙂🙂🙂🙂🙂<←The tone posse, ready for action.

Advertisement

Take a minimal triangle example for your platform/environment, add it to you project, make sure it works, then slowly, step-by-step, morph/grow it into what you need it to be (checking at every step to see if it still works; as soon as it breaks, you know where you screwed up).

One can perfectly draw a single point. There is likely something wrong with the vertex array or the parameters of the draw call, but without the code ...

When experimenting, suggestion to do so under a debug context. Here's a practical example with glfw. Scroll dwon to "debug output".

If I generate a big vertex array and then pass a smaller number to the glDrawArrays it also breaks. So must be something to do with that.
I'd assume I should be able to pass a count that is smaller than the size of the buffer.

Green_Barron; thanks, I'll try adding more debug information. Was already calling the glGetError method and that was clean but I'll see if the others will shed some light on this.

Video Game Programmer.
5 years in industry.

The docu does not state that the count and first parameter must match the array size, so it should be possible to draw less vertices than the buffer contains and start somewhere in the middle. Haven't tried that with drawarrays, but it does work with drawelements. I would even say it is a common technique, Just don't step beyond the end and have the right array bound for the draw call.

A debug context is rumoured to be the better method, because opengl generates more and the amount and kind of information is better configurable. You only provide a callback for the printing of debug information, you don't clutter your code with macros, loops and if...thens. All you need is a 4.3 or higher context, but that should be no problem these days. Even my old notebook with an intel hd4400 can do that.

Advertisement

Sadly turning on the debug context stops it from crashing. I can't see anything strange in the log

Log:

Spoiler

Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint
is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operati
ons.
Buffer detailed info: Buffer object 2 (bound to GL_ARRAY_BUFFER_ARB, usage hint
is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operati
ons.
Buffer detailed info: Buffer object 3 (bound to GL_ARRAY_BUFFER_ARB, usage hint
is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operati
ons.
Buffer detailed info: Buffer object 4 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, usa
ge hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object
 operations.
Buffer detailed info: Buffer object 6 (bound to GL_ARRAY_BUFFER_ARB, usage hint
is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operati
ons.
Buffer detailed info: Buffer object 7 (bound to GL_ARRAY_BUFFER_ARB, usage hint
is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operati
ons.
Buffer detailed info: Buffer object 8 (bound to GL_ARRAY_BUFFER_ARB, usage hint
is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operati
ons.
Buffer detailed info: Buffer object 9 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, usa
ge hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object
 operations.
Buffer detailed info: Buffer object 11 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 12 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 13 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 14 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, us
age hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer objec
t operations.
Buffer detailed info: Buffer object 16 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 17 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 18 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 19 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, us
age hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer objec
t operations.
Buffer detailed info: Buffer object 21 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 22 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 23 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 24 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, us
age hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer objec
t operations.
Buffer detailed info: Buffer object 26 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 27 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 28 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 29 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, us
age hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer objec
t operations.
Buffer detailed info: Buffer object 31 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 32 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 34 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 35 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 33 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 39 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 40 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 41 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 43 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 44 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 46 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 47 (bound to GL_ARRAY_BUFFER_ARB, usage hint
 is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operat
ions.
Buffer detailed info: Buffer object 48 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, us
age hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer objec
t operations.

Buffer detailed info: Buffer object 37 (bound to GL_VERTEX_ATTRIB_ARRAY_BUFFER_B
INDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1), GL_VERTEX_ATTRIB_
ARRAY_BUFFER_BINDING_ARB (2), and GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_D
RAW) will use VIDEO memory as the source for buffer object operations.

Buffer detailed info: Buffer object 38 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, us
age hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer objec
t operations.

Buffer detailed info: Based on the usage hint and actual usage, buffer object 37
 (bound to GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY
_BUFFER_BINDING_ARB (1), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (2), and GL_A
RRAY_BUFFER_ARB, usage hint is GL_STREAM_DRAW) will be configured as STREAM.

Buffer detailed info: Buffer object 37 (bound to GL_VERTEX_ATTRIB_ARRAY_BUFFER_B
INDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1), GL_VERTEX_ATTRIB_
ARRAY_BUFFER_BINDING_ARB (2), and GL_ARRAY_BUFFER_ARB, usage hint is GL_STREAM_D
RAW) will use VIDEO memory as the source for buffer object operations.

Buffer detailed info: Buffer object 37 (bound to GL_VERTEX_ATTRIB_ARRAY_BUFFER_B
INDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1), GL_VERTEX_ATTRIB_
ARRAY_BUFFER_BINDING_ARB (2), and GL_ARRAY_BUFFER_ARB, usage hint is GL_STREAM_D
RAW) will use VIDEO memory as the source for buffer object operations.

Buffer detailed info: Based on the usage hint and actual usage, buffer object 38
 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, usage hint is GL_STREAM_DRAW) will be co
nfigured as STREAM.

Buffer detailed info: Buffer object 38 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, us
age hint is GL_STREAM_DRAW) will use VIDEO memory as the source for buffer objec
t operations.

Buffer detailed info: Buffer object 38 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, us
age hint is GL_STREAM_DRAW) will use VIDEO memory as the source for buffer objec
t operations.

 

2019-11-13 17_54_01-CobbleStone.png

Video Game Programmer.
5 years in industry.

55 minutes ago, Net-Ninja said:

Sadly turning on the debug context stops it from crashing.

It's obviously a quantum mechanics problem.

🙂🙂🙂🙂🙂<←The tone posse, ready for action.

It probably just takes a little longer because of all the writes to screen ?

Do you allocate the buffer every frame ? End never release it ? Why ? It is a static buffer, they are usually allocated once ...

Edit: also, you bind an element buffer, but you said you issue an array draw call ... anyway, a lot of buffers bound and no code, can't say much.

Some of them are going to be the other models, got a few different ones. (In the picture you can see my procedural grass, landscape and a goblin loaded from an obj file). I can try and reduce the number of stuff being allocated and drawn. to narrow it down. Tried removing all the render code for everything else but I'll try commenting out the loading/generation code too.

I do an allocation once per buffer, then send it over once. I could probably delete the local copy of the buffers but I keep them around, at least for now. It's too much code to post in a forum, I'll just attach one of the methods

 

Spoiler


	void DrawMeshShaded(Mesh& mesh, cs::Color color, Shader& shader, AlphaMode alpha_mode, cs::Matrix* mat)
	{
		if (mesh.vbo == 0)
			return;

		switch (alpha_mode)
		{
		case AlphaMode::SOLID:
			break;
		case AlphaMode::BLEND:
			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			break;
		case AlphaMode::ADDATIVE:
			glEnable(GL_BLEND);
			glDepthMask(GL_FALSE);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE);
			break;
		}

		//Bind program
		shader.Use();

		//Set vertex data
		glBindVertexArray(mesh.vao);
		CheckForErrors();

		GLint cameraPositionLocation = glGetUniformLocation(shader.gl_shader_program, "in_CameraPos");
		if (cameraPositionLocation != -1)
		{
			glEnableVertexAttribArray(cameraPositionLocation);
			glUniform3f(cameraPositionLocation, s_view_pos.x, s_view_pos.y, s_view_pos.z);
		}
		CheckForErrors();

		GLint positionLocation = -1;
		positionLocation = glGetAttribLocation(shader.gl_shader_program, "in_Position");
		if (positionLocation != -1)
		{
			if (mesh.vertices)
			{
				glEnableVertexAttribArray(positionLocation);
				glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo);
				glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, NULL);
			}
			else
			{
				glDisableVertexAttribArray(positionLocation);
			}
		}
		CheckForErrors();

		GLint normalLocation = -1;
		normalLocation = glGetAttribLocation(shader.gl_shader_program, "in_Normal");
		if (normalLocation != -1)
		{
			if (mesh.normals)
			{
				glEnableVertexAttribArray(normalLocation);
				glBindBuffer(GL_ARRAY_BUFFER, mesh.nbo);
				glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_TRUE, 0, NULL);
			}
			else
			{
				glDisableVertexAttribArray(normalLocation);
			}
		}
		CheckForErrors();

		GLint matrixLocation = glGetUniformLocation(shader.gl_shader_program, "in_Model");
		if (matrixLocation != -1)
		{
			glEnableVertexAttribArray(matrixLocation);
			if (mat)
			{
				glUniformMatrix4fv(matrixLocation, 1, GL_FALSE, (GLfloat*)mat);
			}
			else
			{
				static const cs::Matrix ident = cs::Matrix::CreateScale(1.0f);
				glUniformMatrix4fv(matrixLocation, 1, GL_FALSE, (GLfloat*)&ident);
			}
		}
		CheckForErrors();

		GLint modelViewProjMatLocation = glGetUniformLocation(shader.gl_shader_program, "in_ModelViewProjection");
		if (modelViewProjMatLocation != -1)
		{
			cs::Matrix matrix;
			if (mat)
			{
				matrix = (*mat) * s_view_matrix * s_projection_matrix;
			}
			else
			{
				matrix = s_view_matrix * s_projection_matrix;
			}

			glEnableVertexAttribArray(modelViewProjMatLocation);
			glUniformMatrix4fv(modelViewProjMatLocation, 1, GL_FALSE, (GLfloat*)&matrix);
		}
		CheckForErrors();

		GLint colorLocation = glGetUniformLocation(shader.gl_shader_program, "in_Color");
		if (colorLocation != -1)
		{
			glEnableVertexAttribArray(colorLocation);
			glUniform4f(colorLocation, color.r, color.g, color.b, color.a);
		}
		CheckForErrors();

		GLint ambientLocation = glGetUniformLocation(shader.gl_shader_program, "in_Ambient");
		if (ambientLocation != -1)
		{
			glEnableVertexAttribArray(ambientLocation);
			glUniform1f(ambientLocation, s_ambient);
		}
		CheckForErrors();

		glBindBuffer(GL_ARRAY_BUFFER, 0);
		CheckForErrors();

		if (mesh.indices)
		{

			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.ibo);
			CheckForErrors();

			glDrawElements(GL_TRIANGLES, (GLsizei)mesh.num_indices, GL_UNSIGNED_INT, NULL);
			CheckForErrors();

			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
			CheckForErrors();
		}
		else
		{
			glDrawArrays(GL_TRIANGLES, 0, (GLsizei)mesh.num_verts);
			CheckForErrors();
		}

		if (ambientLocation != -1)
			glDisableVertexAttribArray(ambientLocation);

		if (colorLocation != -1)
			glDisableVertexAttribArray(colorLocation);

		if (modelViewProjMatLocation != -1)
			glDisableVertexAttribArray(modelViewProjMatLocation);

		if (matrixLocation != -1)
			glDisableVertexAttribArray(matrixLocation);

		//Disable vertex position
		if (positionLocation != -1)
			glDisableVertexAttribArray(positionLocation);

		if (normalLocation != -1)
			glDisableVertexAttribArray(normalLocation);

		if (cameraPositionLocation != -1)
			glDisableVertexAttribArray(cameraPositionLocation);

		//Unbind program
		Shader::ClearActiveShader();

		// ---

		if (alpha_mode == AlphaMode::ADDATIVE)
			glDepthMask(GL_TRUE);

		if (alpha_mode != AlphaMode::SOLID)
			glDisable(GL_BLEND);
	}

 

 

Video Game Programmer.
5 years in industry.

This topic is closed to new replies.

Advertisement