Separating color and position into 2 VBO's

Hey im trying to render 3 line-rectangles with the positions in one VBO and the color in another VBO.

Im updating the VBO’s with glMapBufferRange();

The positions seems to work but the colors doesn’t apply to the lines, they’re always Black even though the pColor pointer returned from glMapBufferRange() are modified. I’ve looked through it multiple times now but can’t figure out what the problem is.

I think the vertexAttribPointers seems fine??

vertexShader.glsl

#version 330 core

layout (location = 0) in vec4 inPos;
layout (location = 3) in vec4 inCol;

out vec4 colorVS;

uniform vec2 windowDimensions;


void main()
{

	vec4 vertexPosition;
	vertexPosition.xyz = inPos.xyz;
	vertexPosition.x /= windowDimensions.x;
	vertexPosition.y /= windowDimensions.y;
	vertexPosition.z  = 0.0f;
	vertexPosition.w  = 1.0f;

	gl_Position = vertexPosition;

	colorVS = inCol;
}

fragmentShader.glsl

#version 330 core

in vec4 colorVS;
out vec4 fragmentColor;

uniform vec4 iColorData;

void main()
{
	
	vec4 result_Color = colorVS;

	//result_Color.r /= iColorData.r; 
	//result_Color.g /= iColorData.g; 
	//result_Color.b /= iColorData.b; 
	//result_Color.a /= iColorData.a; 

	fragmentColor = result_Color;

}

main.cpp

struct GameObject
{
	float x;
	float y;
	float width;
	float height;
	float color;

	float vertices[28];
	float vertex_Positions[16];
	float vertex_Colors[16];
	float vertex_TextureCoords[8];

	float *ptr;
	float *pColor;
};

int main()
{
//   setting up shaders .....
//    ....
//    ....
	GameObject tanks[3] = {};
	GameBuffer positions[3] = {};
	
	GameBuffer gamePositionBuffer[3] = 
	{
		tanks[0].vertex_Positions[0],
		tanks[1].vertex_Positions[0],
		tanks[2].vertex_Positions[0],
	};

	GameBuffer gameColorBuffer[3] = 
	{
		tanks[0].vertex_Colors[0],
		tanks[1].vertex_Colors[0],
		tanks[2].vertex_Colors[0],
	};

	int indices[] =
	{
		0, 1,
		1, 2,
		2, 3,
		3, 0,

		4, 5,
		5, 6,
		6, 7,
		7, 4,

		8,  9 ,
		9,  10,
		10, 11,
		11, 8
	};
	
	unsigned int gamePositionVAO, gamePositionVBO, gameIBO, gameColorVBO, gameColorVAO;

	glGenVertexArrays(1, &gamePositionVAO);
	glGenVertexArrays(1, &gameColorVAO);

	glGenBuffers(1, &gamePositionVBO);
	glGenBuffers(1, &gameColorVBO);
	glGenBuffers(1, &gameIBO);

	// POSITION VBO
	glBindVertexArray(gamePositionVAO);
	glBindBuffer(GL_ARRAY_BUFFER, gamePositionVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(gamePositionBuffer), gamePositionBuffer, GL_DYNAMIC_DRAW);

	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gameIBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);


	// COLOR VBO
	glBindVertexArray(gameColorVAO);
	glBindBuffer(GL_ARRAY_BUFFER, gameColorVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(gameColorBuffer), gameColorBuffer, GL_STATIC_DRAW);

	glEnableVertexAttribArray(3);
	glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);

	tanks[0].pColor = (float*)glMapBufferRange(GL_ARRAY_BUFFER, 0, sizeof(tanks[0].vertex_Colors), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
	tanks[0].pColor[0]  = 1.0f;
	tanks[0].pColor[1]  = 1.0f;
	tanks[0].pColor[2]  = 1.0f;
	tanks[0].pColor[3]  = 1.0f;
	tanks[0].pColor[4]  = 1.0f;
	tanks[0].pColor[5]  = 1.0f;
	tanks[0].pColor[6]  = 1.0f;
	tanks[0].pColor[7]  = 1.0f;
	tanks[0].pColor[8]  = 1.0f;
	tanks[0].pColor[9]  = 1.0f;
	tanks[0].pColor[10] = 1.0f;
	tanks[0].pColor[11] = 1.0f;
	tanks[0].pColor[12] = 1.0f;
	tanks[0].pColor[13] = 1.0f;
	tanks[0].pColor[14] = 1.0f;
	tanks[0].pColor[15] = 1.0f;
	glUnmapBuffer(GL_ARRAY_BUFFER);

	glBindVertexArray(gamePositionVAO);
	glBindBuffer(GL_ARRAY_BUFFER, gamePositionVBO);
	tanks[0].ptr = (float*)glMapBufferRange(GL_ARRAY_BUFFER, 0, sizeof(tanks[0].vertex_Positions), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
	tanks[0].init(-200.0f, 0.0f, 100.0f, 100.0f);
	glUnmapBuffer(GL_ARRAY_BUFFER);




	tanks[1].ptr = (float*)glMapBufferRange(GL_ARRAY_BUFFER, sizeof(tanks[0].vertex_Positions), sizeof(tanks[0].vertex_Positions), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
	tanks[1].init(0.0f, 30.0f, 400.0f, 500.0f);
	glUnmapBuffer(GL_ARRAY_BUFFER);


	tanks[2].ptr = (float*)glMapBufferRange(GL_ARRAY_BUFFER, 2  * sizeof(tanks[0].vertex_Positions), sizeof(tanks[0].vertex_Positions), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
	tanks[2].init(0.0f, -300.0f, 40.0f, 50.0f);
	glUnmapBuffer(GL_ARRAY_BUFFER);



	glBindVertexArray(gamePositionVAO);
	glBindBuffer(GL_ARRAY_BUFFER, gamePositionVBO);


	glViewport(0, 0, 800, 600);

	glUseProgram(shaderProgram);

	int    winWidth = 0;
	int    winHeight = 0;
	double mouseCurPosX = 0;
	double mouseCurPosY = 0;

	int winDimLoc = glGetUniformLocation(shaderProgram, "windowDimensions"); 
	char windowTitle[100] = {};

 	float movY = 0.0f;
 	float movX_1 = 0.0f;
	
	while(!glfwWindowShouldClose(window) && running) 
	{
		glfwGetWindowSize(window, &winWidth, &winHeight);

		glUniform2f(winDimLoc, (float)winWidth, (float)winHeight);


		glViewport(0, 0, winWidth, winHeight);
		checkInput(window);

		glClearColor(0.0f, 0.2f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		glfwGetCursorPos(window, &mouseCurPosX, &mouseCurPosY);
		sprintf(windowTitle, "CJGL Game - MouseCursor: %4.3f, %4.3f - Window (width/height): %d/%d)", mouseCurPosX, mouseCurPosY, winWidth, winHeight);
		glfwSetWindowTitle(window, windowTitle);

		if(keyPressed[LEFT_MOUSE_BUTTON])
		{

		}
		if(keyPressed[RIGHT_MOUSE_BUTTON])
		{
		}

		if(keyPressed[ESC])
		{
			running = false;
		}
		if(keyPressed['W'])
		{
			tanks[0].ptr = (float*)glMapBufferRange(GL_ARRAY_BUFFER, 0, sizeof(tanks[0].vertex_Positions), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
			movY++;
			tanks[0].setY(movY);
			glUnmapBuffer(GL_ARRAY_BUFFER);

		}
		if(keyPressed['S'])
		{
			tanks[0].ptr = (float*)glMapBufferRange(GL_ARRAY_BUFFER, 0, sizeof(tanks[0].vertex_Positions), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
			movY--;
			tanks[0].setY(movY);
			glUnmapBuffer(GL_ARRAY_BUFFER);

		}
		if(keyPressed['A'])
		{
		}
		if(keyPressed['D'])
		{
		}

		if(keyPressed[LEFT_ARROW])
		{
			tanks[1].ptr = (float*)glMapBufferRange(GL_ARRAY_BUFFER, sizeof(tanks[0].vertex_Positions), sizeof(tanks[0].vertex_Positions), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
			movX_1--;
			tanks[1].setX(movX_1);
			glUnmapBuffer(GL_ARRAY_BUFFER);
		}
		if(keyPressed[RIGHT_ARROW])
		{
			tanks[1].ptr = (float*)glMapBufferRange(GL_ARRAY_BUFFER, sizeof(tanks[0].vertex_Positions), sizeof(tanks[0].vertex_Positions), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
			movX_1++;
			tanks[1].setX(movX_1);
			glUnmapBuffer(GL_ARRAY_BUFFER);
		}

		glBindBuffer(GL_ARRAY_BUFFER, gamePositionVBO);
		glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0);



		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	glDeleteShader(VS);
	glDeleteShader(FS);
	glDeleteProgram(shaderProgram);

	glDeleteBuffers(1, &gamePositionVBO);
	glDeleteBuffers(1, &gameIBO);
	glDeleteBuffers(1, &gamePositionVAO);

	
	glfwDestroyWindow(window);
	glfwTerminate();


	return 0;
}

You should only have one VAO.

As it stands, you’re putting the state for the colour attribute into gamePositionVAO, which isn’t used. It needs to go in the same VAO as the other data.

It might help to read a tutorial on VAOs, as this suggests a fundamental lack of understanding about what VAOs are and how they’re used.

1 Like