Jump to content

  • Log In with Google      Sign In   
  • Create Account


Colouring verticies vbos/shaders


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 Azenris   Members   -  Reputation: 139

Like
0Likes
Like

Posted 05 June 2012 - 09:41 AM

Im just starting out with this trying to get a triangle to show coloured. It currently only shows as white though. Probably something simple I'm overlooking, but I cant seem to see it.
CApplication::CApplication(void)
	: m_appName("<Name> - <Build Version>")
	, shader(GLSLProgram("basic_tex.vert", "basic_tex.frag"))
{
}

bool CApplication::Init(void)
{
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	shader.bindAttrib(0, "a_Vertex");
	shader.bindAttrib(1, "a_Color");

	shader.linkProgram();
	shader.bindShader();

	if (!glGenBuffers || !glBindBuffer || !glBufferData)
		LOG->Send("VBOs not supported by your graphics card");

	// VERTICIES
	glGenBuffers(LAST_BUFFER, m_vbos);

	vertices.push_back(CVertex(-1.0f, -0.5f, -4.0f));
	vertices.push_back(CVertex(1.0f, -0.5f, -4.0f));
	vertices.push_back(CVertex(0.0f,  0.5f, -4.0f));

	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]);
	glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(CVertex), &vertices[0], GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

	// INDEX LIST
	indices.push_back(CIndex(0));
	indices.push_back(CIndex(1));
	indices.push_back(CIndex(2));

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbos[INDEX_BUFFER]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(CIndex), &indices[0], GL_STATIC_DRAW);

	// COLOURS
	colorBuffer.push_back(CColour(1.0f, 0.0f, 0.0f));
	colorBuffer.push_back(CColour(1.0f, 0.0f, 0.0f));
	colorBuffer.push_back(CColour(1.0f, 0.0f, 0.0f));

	glEnableVertexAttribArray(1);
	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[COLOUR_BUFFER]);
	glBufferData(GL_ARRAY_BUFFER, colorBuffer.size() * sizeof(CColour), &colorBuffer[0], GL_STATIC_DRAW);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbos[INDEX_BUFFER]);

	return true;
}

void CApplication::Render(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glGetFloatv(GL_PROJECTION, projMatrix);
	glGetFloatv(GL_MODELVIEW, modelMatrix);

	shader.sendUniform("modelview_matrix", modelMatrix);
	shader.sendUniform("projection_matrix", projMatrix);

	glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
}

void CApplication::OnResize(int width, int height)
{
	if (width == 0)
		height = 1;

	glViewport(0, 0, width, height);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	gluPerspective(52.0f, float(width) / float(height), 1.0f, 100.0f);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

vertshader
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;

layout(location = 0) in vec3 a_Vertex;
layout(location = 1) in vec3 a_Color;

out vec4 color;

void main(void)
{
	gl_Position = projection_matrix * modelview_matrix * vec4(a_Vertex, 1.0);	
	color = vec4(a_Color, 1.0);
}


frag shader
in vec4 color;
out vec4 outColor;

void main(void)
{
	outColor = color;
}


As mentioned my problem is a white triangle is shown on the screen. Currently I wanted it to show red, and eventually be able to specify each vertex a different colour.

Hope I managed to post across relevant information and placed it in the correct place :P
Is there anything that sticks out as wrong?

BTW if you need more information just ask and I'l put it up

Thankyou for any help ! :)

Sponsor:

#2 dpadam450   Members   -  Reputation: 824

Like
0Likes
Like

Posted 05 June 2012 - 10:47 PM

First try moving the following to after shader is bound. Before the shader is compiled and linked, it doesn't know what "a_Vertex" is. It hasn't even looked at the GLSL code to know what a_Vertex is. And even then, if its not the currently bound shader then it still doesn't know how to deal with "a_Vertex" because it only exists in your 1 shader and can't know what to do with it until its ready to receive uniform data.
shader.bindAttrib(0, "a_Vertex");
shader.bindAttrib(1, "a_Color");



try outColor = vec4(1,0,0,1); Does is make the triangle red?

#3 Azenris   Members   -  Reputation: 139

Like
0Likes
Like

Posted 06 June 2012 - 04:30 PM

bah
glGetFloatv(GL_PROJECTION, projMatrix);
glGetFloatv(GL_MODELVIEW, modelMatrix);

should have been

glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);

Atleast that works now, Gonna try moving away from te builtin matrix stack now tho.

Ty for the help.

#4 dpadam450   Members   -  Reputation: 824

Like
0Likes
Like

Posted 06 June 2012 - 08:41 PM

That is actually my biggest complaint with opengl that they made those 2 enums instead of just 1.

#5 Azenris   Members   -  Reputation: 139

Like
0Likes
Like

Posted 07 June 2012 - 12:35 PM

I am still having problems. I changed my code so the fragment shader was setting the colour to yellow. This worked fine and I got a yellow triangle. However when I changed back to passing the colour variable in to the shader, I got this bug where the triangle would flicker between colours rapidly.

I have included an attachment of my program. I have cut it down to the important stuff.

After compiling run the .exe in "temptest.zip\temptest\Debug" this is where the shsders are located.

Here is some of the code incase you dont want to download my program.

App

#include "application.h"
#include "log.h"

CApplication::CApplication(void)
	: m_appName("TESTING GLSL")
	, shader(GLSLProgram("vert_shader.vert", "frag_shader.frag"))
{
}

CApplication::~CApplication(void)
{
}

bool CApplication::Init(void)
{
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	if (!shader.initialize())
		LOG->Send("Failed to compile shader");

	shader.bindAttrib(0, "in vertex");
	shader.bindAttrib(1, "in_colour");

	shader.linkProgram();
	shader.bindShader();

	if (!glGenBuffers || !glBindBuffer || !glBufferData)
		LOG->Send("VBOs not supported by your graphics card");

	// VERTEX
	glGenBuffers(LAST_BUFFER, m_vbos);

	vertices.push_back(CVertex(-1.0f, -0.5f, -4.0f));
	vertices.push_back(CVertex(1.0f, -0.5f, -4.0f));
	vertices.push_back(CVertex(0.0f,  0.5f, -4.0f));

	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]);
	glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(CVertex), &vertices[0], GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

	// COLOUR
	colors.push_back(CColour(1.0f, 0.0f, 1.0f));
	colors.push_back(CColour(1.0f, 0.0f, 1.0f));
	colors.push_back(CColour(1.0f, 0.0f, 1.0f));

	glEnableVertexAttribArray(1);
	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[COLOUR_BUFFER]);
	glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(CColour), &colors[0], GL_STATIC_DRAW);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

	// INDEX
	indices.push_back(CIndex(0));
	indices.push_back(CIndex(1));
	indices.push_back(CIndex(2));

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbos[INDEX_BUFFER]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(CIndex), &indices[0], GL_STATIC_DRAW);

	return true;
}

void CApplication::Update(float elapsed)
{
}

void CApplication::Render(void)
{	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
	glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);
	
	shader.sendUniform("projection_matrix", projMatrix);
	shader.sendUniform("modelview_matrix", modelMatrix);

	glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
}

void CApplication::Release(void)
{
}

void CApplication::OnResize(int width, int height)
{	
	if (height == 0)
		height = 1;

	glViewport(0, 0, width, height);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	gluPerspective(52.0f, float(width) / float(height), 1.0f, 100.0f);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
}

std::string CApplication::GetAppName(void) const
{
	return m_appName;
}

Vert shader
#version 130

uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;

layout(location = 0) in vec3 in_vertex;
layout(location = 1) in vec3 in_colour;

out vec4 out_colour;

void main(void)
{
	gl_Position = projection_matrix * modelview_matrix * vec4(in_vertex, 1.0);
	out_colour = vec4(in_colour, 1.0);
}

Frag shader
#version 130

in vec4 in_colour;

out vec4 out_colour;

void main(void)
{
	out_colour = in_colour;
}


I Have tried previous suggestions to the location where I bind but has no effect.

Any help appreciated. Thanks ! :)

Attached Files



#6 dpadam450   Members   -  Reputation: 824

Like
0Likes
Like

Posted 07 June 2012 - 03:29 PM

In your new code you didn't do what I told you. Put the bindAttribute call after you have bound the shader. You never changed that line. Likewise, if you ever turn that shader off and then back on, you will need to bindAttributes again.

#7 Azenris   Members   -  Reputation: 139

Like
0Likes
Like

Posted 07 June 2012 - 04:08 PM

I Have tried previous suggestions to the location where I bind but has no effect.

Any help appreciated. Thanks ! :)


I tried, It didnt seem to have any effect on my code, Ill put it as you mentioned however my problem persists.

#8 Azenris   Members   -  Reputation: 139

Like
0Likes
Like

Posted 08 June 2012 - 10:45 AM

I noticed an error in the code i uploaded

shader.bindAttrib(0, "in vertex");
shader.bindAttrib(1, "in_colour");


It uses an incorrect name. However this causes no issues I think as the location 0 is always for verticies. I changed it anyway and the problem still persists.
I also added


if (glGetAttribLocation(shader.m_programID, "in_vertex") != 0)
   	 LOG->Send("Something gone wrong #1");
    if (glGetAttribLocation(shader.m_programID, "in_colour") != 1)
        LOG->Send("Something gone wrong #2");

just to make sure its bound ok.

Still not sure why the colour is flickering. I tried to google and couldnt find anything on it. :(

#9 dpadam450   Members   -  Reputation: 824

Like
0Likes
Like

Posted 08 June 2012 - 11:42 AM

Just curious, what is the sizeof(CColour)? What does CColour class look like? Other than that I don't know.

What does your draw code look like? It sounds like with the flicker that you are not rebinding the attrib by calling glBindBuffer/glVertexAttribPointer each frame.

#10 Azenris   Members   -  Reputation: 139

Like
0Likes
Like

Posted 08 June 2012 - 01:04 PM

Do you mean to modify my render to this

void CApplication::Render(void)
{	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
	glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);
	
	shader.sendUniform("projection_matrix", projMatrix);
	shader.sendUniform("modelview_matrix", modelMatrix);

	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[VERTEX_BUFFER]);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

	glBindBuffer(GL_ARRAY_BUFFER, m_vbos[COLOUR_BUFFER]);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

	glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
}

I added the glBindBuffer/glVertexAttribPointer each frame. Doesnt seem to change anything.

I checked sizeof(CColour), it is 12 bytes. Here is what the class looks like


#ifndef HG_GEOMETRY_H
#define HG_GEOMETRY_H

#include "mgl.h"

#pragma pack(push, 1)

class CVertex
{
public:
	CVertex(GLfloat _x, GLfloat _y, GLfloat _z)
		: x(_x)
		, y(_y)
		, z(_z)
	{
	}

	GLfloat x;
	GLfloat y;
	GLfloat z;
};

class CColour
{
public:
	CColour(GLfloat _r, GLfloat _g, GLfloat _b)
		: r(_r)
		, g(_g)
		, b(_b)
	{
	}

	GLfloat r;
	GLfloat g;
	GLfloat b;
};

class CIndex
{
public:
	CIndex(GLuint _index)
		: index(_index)
	{
	}

	GLuint index;
};

#pragma pack(pop)

#endif


#11 dpadam450   Members   -  Reputation: 824

Like
0Likes
Like

Posted 08 June 2012 - 02:10 PM

Can you also add the other .bindAttrib() after the calls below in your draw? Is that where you put it before? Because you have to bind it every single frame unless you use this shader for everything. If at any point the current shader is switched to another shader, OR if it is unbound to not use a shader at all, you have to resend everything to set it up again?
shader.sendUniform("projection_matrix", projMatrix);
shader.sendUniform("modelview_matrix", modelMatrix);

Other than that I have no suggestions.

Edited by dpadam450, 08 June 2012 - 02:10 PM.


#12 Azenris   Members   -  Reputation: 139

Like
0Likes
Like

Posted 16 June 2012 - 11:55 AM

This shader is the only one being used yea, its nothing more than a demo to learn about GLSL... what a road block at step one Posted Image

I'm curious is everyone else getting the flashing triangle if they run the app?

I tried to change to shaders abit. First I changed the frag shader

in vec4 in_colour;

out vec4 out_colour;

void main(void)
{
	out_colour = in_colour;
}


to

in vec4 in_colour;

out vec4 out_colour;

void main(void)
{
	out_colour = vec4(1.0, 1.0, 0.0, 1.0);
}


The output was then a yellow triangle (no flickering in the colour)

I then tried a second experiment with changing the vertex shader. (after i changed the fragment shader back)

from

uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;

in vec3 in_vertex;
in vec3 in_colour;

out vec4 out_colour;

void main(void)
{
	gl_Position = projection_matrix * modelview_matrix * vec4(in_vertex, 1.0);
	out_colour = vec4(in_colour, 1.0);
}

to

uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;

in vec3 in_vertex;
in vec3 in_colour;

out vec4 out_colour;

void main(void)
{
	gl_Position = projection_matrix * modelview_matrix * vec4(in_vertex, 1.0);
	out_colour = vec4(1.0, 1.0, 0.0, 1.0);
}

This resulted in the original colour flickering. Does this mean anything to you? Maybe I wrote the fragment shader wrong? Does it look right to you? Its like the fragment shader is changing the colour even though all I do is take the input for the output.

#13 Sponji   Members   -  Reputation: 1125

Like
0Likes
Like

Posted 16 June 2012 - 06:44 PM

Your vertex shader outputs "out_colour", but your fragment shader gets in "in_colour". They should have the same name. And btw the plural of vertex is vertices.
Derp

#14 Azenris   Members   -  Reputation: 139

Like
0Likes
Like

Posted 16 June 2012 - 07:13 PM

Thank you, the naming issue was the problem. TY for all the help.

#15 dpadam450   Members   -  Reputation: 824

Like
0Likes
Like

Posted 16 June 2012 - 09:37 PM

Two things that will help you:
Unless I #version 400, my GTS450 complains about this for the layout keyword. Try using that, if it works keep it.
[ >> ] 0(6) : error C0000: syntax error, unexpected '(', expecting "::" at token "("

Secondly, I modified your code:
This only takes into account errors from the vertex shader, but add it in for the fragment shader as well. It appears you aren't outputting
shader compile errors anywhere.
if (!compileShader(m_vertexShader) || !compileShader(m_fragmentShader))
{
std::string log;

GLchar *debug;
GLint debugLength;
glGetShaderiv( m_vertexShader.id, GL_INFO_LOG_LENGTH, &debugLength);

debug = new GLchar[debugLength];
glGetShaderInfoLog(m_vertexShader.id, debugLength, &debugLength, debug);

log.append(debug,0,debugLength);
std::cout << debug;

LOG->Send("Could not compile the shaders, they are invalid");
LOG->Send(debug);
return false;
}




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS