PDA

View Full Version : Drawing 3D Lines with Colors?



Keithster
12-29-2015, 12:08 AM
Greetings!

I'm trying to draw colored 3D lines. I got the lines part working, but not the color. (See image below)

Here's my shaders:



layout (location = 0) in vec3 VertPos;
layout (location = 1) in vec3 VertColor;

uniform mat4 V;
uniform mat4 P;

out vec4 FragColor;

void main()
{
gl_Position = P * V * vec4(VertPos, 1);
FragColor = vec4(VertColor, 1);
}

#version 330 core
out vec4 FinalColor;
in vec4 Color;
void main()
{
FinalColor = vec4(Color.r, 1, Color.b, 1); // Setting green to 1 for debugging
}



Here's my line struct:


struct dbg_line
{
v3 Start;
v3 StartColor;
v3 End;
v3 EndColor;
};


Here's how I'm initializing and drawing:


// Initializing
Data->DebugVBO = GLGenArrayBuffer(sizeof(dbg_line) * MAX_DBG_LINES, 0, GL_DYNAMIC_DRAW);
Data->DebugVAO = GLGenVertexArray();

GLAttribute(0, 3, GL_FLOAT, 2 * sizeof(v3), 0);
GLAttribute(1, 3, GL_FLOAT, 2 * sizeof(v3), 1 * sizeof(v3));

// Drawing (Note: Lines get multiplied by ModelToWorld matrix in CPU, not in the shader but I didn't show it here)
u32 Shader = Data->Shaders.Debug;
ShaderUse(Shader);
u32 LineCount = ARRAY_COUNT(Data->DBGLines);
GLBindVAO(Data->DebugVAO);
GLSetArrayBuffer(Data->DebugVBO, LineCount * sizeof(dbg_line), Data->DBGLines);
{
ShaderM4(Shader, "V", &WorldToView);
ShaderM4(Shader, "P", &ViewToProjection);
GLDrawLines(LineCount);
}


Helper functions I'm using:



internal inline void
GLSetArrayBuffer(u32 ArrayBuffer, u32 Size, void *Data)
{
glBindBuffer(GL_ARRAY_BUFFER, ArrayBuffer);
glBufferSubData(GL_ARRAY_BUFFER, 0, Size, Data);
}

internal u32
GLGenArrayBuffer(u32 SizeInBytes, void *Data, u32 Mode)
{
u32 ArrayBuffer;
glGenBuffers(1, &ArrayBuffer);
glBindBuffer(GL_ARRAY_BUFFER, ArrayBuffer);
glBufferData(GL_ARRAY_BUFFER, SizeInBytes, Data, Mode);
return (ArrayBuffer);
}

internal inline void
GLAttribute(u32 Index, u32 Count, u32 Type = GL_FLOAT, u32 Stride = 0, u32 Offset = 0)
{
glEnableVertexAttribArray(Index);
glVertexAttribPointer(Index, Count, Type, GL_FALSE, Stride, (char *)0 + Offset);
}

internal inline void
GLBindVBO(u32 VBO)
{
glBindBuffer(GL_ARRAY_BUFFER, VBO);
}

internal inline void
GLBindVAO(u32 VAO)
{
glBindVertexArray(VAO);
}

internal inline void
GLDrawLines(u32 NumLines)
{
glDrawArrays(GL_LINES, 0, NumLines * 2);
}

internal inline u32
GLGenVertexArray()
{
u32 VertexArray;
glGenVertexArrays(1, &VertexArray);
glBindVertexArray(VertexArray);
return (VertexArray);
}


I've been stuck at this for a while. All I get is the green lines on my bounding boxes even though I'm pretty sure I set the line color to red (when I push a line, I set the Start and End colors to the same value). I probably messed something up with the strides/offsets but I can't see it...

Image [http://i.imgur.com/xhEdbHY.png]

Any help is appreciated!

Thanks!
-Keithster

GClements
12-29-2015, 02:52 AM
Here's my shaders:



layout (location = 0) in vec3 VertPos;
layout (location = 1) in vec3 VertColor;

uniform mat4 V;
uniform mat4 P;

out vec4 FragColor;

...

out vec4 FinalColor;
in vec4 Color;


This shouldn't even link; the fragment shader has an input named Color but the vertex shader has no output by that name (its only output is named FragColor).

Are you checking the compilation and linking status of the program? Are you checking for other errors? In the compatibility profile, errors with shader programs typically result in the fixed-function pipeline being used. This will source vertex positions from attribute zero, meaning that the correct geometry is rendered but with the wrong "style".

I can't see any errors in the client code, and most of the things which would prevent the colours from being read correctly would do the same for the positions, but that part is obviously working.

Keithster
12-29-2015, 03:06 AM
Thank you! I knew it was something stupid I missed. I am checking for shader compilation/linking but I didn't seem to get any log for that one, I'm not sure if something in my shader check code is wrong:




bool ShaderCheckCompileStatus(u32 Shader)
{
GLint CompileSuccess = 0;
glGetShaderiv(Shader, GL_COMPILE_STATUS, &CompileSuccess);
if (CompileSuccess == GL_FALSE)
{
GLint LogLength = 0;
glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &LogLength);

string Error = Salloc(LogLength);
glGetShaderInfoLog(Shader, LogLength, &LogLength, Error);
Log(Error[0]);
glDeleteShader(Shader);
return false;
}
return true;
}

u32 ShaderLoadFromString(string ShaderName, string VertexShaderCode, string FragmentShaderCode)
{
u32 FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
u32 VertexShaderID = glCreateShader(GL_VERTEX_SHADER);

Log("Compiling vertex shader: %s\n", ShaderName);
glShaderSource(VertexShaderID, 1, &VertexShaderCode, null);
glCompileShader(VertexShaderID);

if (!ShaderCheckCompileStatus(VertexShaderID))
return 0;

Log("Compiling fragment shader: %s\n", ShaderName);
glShaderSource(FragmentShaderID, 1, &FragmentShaderCode, null);
glCompileShader(FragmentShaderID);

if (!ShaderCheckCompileStatus(FragmentShaderID))
return 0;

Log("Linking...\n");
u32 ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);

int LogLength;
GLint Success;
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Success);
if (Success == GL_FALSE)
{
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &LogLength);
string ErrorMessage = Salloc(LogLength);
glGetShaderInfoLog(VertexShaderID, LogLength, null, ErrorMessage);
Log("%s\n", ErrorMessage);
}

glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);

Log("Success!\n\n");

return ProgramID;
}

GClements
12-29-2015, 03:20 AM
I didn't seem to get any log for that one, I'm not sure if something in my shader check code is wrong:



glGetProgramiv(ProgramID, GL_LINK_STATUS, &Success);
if (Success == GL_FALSE)
{
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &LogLength);
string ErrorMessage = Salloc(LogLength);
glGetShaderInfoLog(VertexShaderID, LogLength, null, ErrorMessage);


You're passing VertexShaderID to glGetShaderInfoLog(); it should be ProgramID.

Keithster
12-29-2015, 03:27 AM
That didn't change much. Stepping into it I see that 'Success' is equal to 1 so it doesn't get into the entire if statement. Could it the shader version 330?

GClements
12-29-2015, 04:11 AM
I don't think so. You could try printing the info log regardless of whether linking succeeds. Maybe it generates a warning and carries on regardless.

Keithster
12-29-2015, 11:03 AM
Still didn't print anything. LogLength is set to 0. I think I also have another mistake where I'm calling glGetShaderInfoLog instead of glGetProgramInfoLog but still the length is 0 so the get log function wouldn't fill the buffer.