• Advertisement
Sign in to follow this  

Colouring verticies vbos/shaders

This topic is 2133 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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 ! :)

Share this post


Link to post
Share on other sites
Advertisement
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 ! :)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites


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.

Share this post


Link to post
Share on other sites
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. :(

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement