• Advertisement
Sign in to follow this  

Colouring verticies vbos/shaders

This topic is 2046 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
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

Share this post


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

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.

Share this post


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

Share this post


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

Share this post


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

  • Advertisement