PDA

View Full Version : Struggling to color each vertex of Hexagon



TheFearlessHobbit
03-08-2017, 06:06 PM
Hello everyone, I am a new registered user.

I just recently started learning OpenGL and I come from a WIN32 API background. To cut straight to the chase, I am stuck and I am here to ask for assistance. Basically, I have a Hexagon drawn like this:


// Position Color
GLfloat vertices[] = { -0.25f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // Red
0.25f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // Green
0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f , // Blue

0.25f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, // Purple
-0.25f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f, // White
-0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f // Yellow
};

Here is how my vertex and fragment shaders currently look like:
Vertex

#version 430 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec3 newColor;

uniform mat4 resultantMatrix;

out vec3 output;

void main()
{
vec4 currentPos = vec4(position, 1.0f);
gl_Position = resultantMatrix * currentPos ;
output = color; //... maybe + newColor;?
// Err.... How to output 2 things in the fragment shader...?
};

Fragment

#version 430 core

in vec3 o;
out vec4 Color;

uniform float Timer;

void main()
{
vec3 tempColor = output * abs(sin(Timer));
tempColor.x = (sin(Timer) / 2) + 0.5f;
// tempColor.y = (sin(Timer) / 2) + 0.5f; // Not doing what I expect it to do
Color = vec4(tempColor, 1.0f);
};


What I am trying to accomplish is I want to make the color of each vertex change as time goes on. The issue I am having is here:


glGenBuffers(1, &vao);
glBindVertexArray(vao);

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
// glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(21 * sizeof(GLfloat))); It stores the colors in the 2nd layout but it still wouldn't work

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// glEnableVertexAttribArray(2);

Currently my hexagon only colors 2 or 3 vertices differently, the others are all the same. I am trying to separate the data into another layout but either I'm doing it wrong or the result is not what I want. I would greatly appreciate any help you could give me because I am absolutely stuck. I prefer not to generate another VBO because that may seem a bit expensive for such a simple thing, I am sure there's a trick I can pull here to make all vertices glow differently, but my knowledge of OpenGL is not decent yet, hence why I'm here seeking your help.

Thank you very much.

puregainz
03-09-2017, 10:57 AM
Hello !

i'm a beginner myself but I am able to answer some of your question:

1)Using multiple outputs of the Vertex shader as inputs to the Fragment shader:

Either you just put the outputs right after another and let OpenGL shader program linke figure the location itself:

Vertex shader:
out vec4 color1;
out vec4 color2;

Fragment Shader:
in vec4 color1;
in vec4 color2;

Or use GLSL "Interface Blocks":

Vertex Shader:
out VS_OUT{
vec4 color1;
vec4 color2
}vs_out;

Fragment Shader:
in VS_OUT{
vec4 color1;
vec4 color2
}fs_in;

Note that you will have to refer color1 as:
vs_out.color1 in the vertex shader
fs_in.color1 in the fragment shader

2)Attributes Pointer and location

I recommend you read this post on stackoverflow:
stackoverflow.com/questions/16380005/opengl-3-4-glvertexattribpointer-stride-and-offset-miscalculation


I see you have chosen the "Interleaved" way of packing your data in the buffer

I don't really understand the purpose of the second color, knowing you didn't even load some of it in the buffer.

3)General Debugging
First I recommend you to check shader compilation errors, here is an example implementation:



void checkcompile(GLuint shader) {
GLint isCompiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);

// The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(shader, maxLength, &maxLength,&errorLog[0]);

string msg(errorLog.begin(), errorLog.end());
//the string msg is now holding the error log, print it as you want
}
}


Secondly, on windows platform you could use some OpenGL Tracing tool like GLIntercept (Google it) to track more general OpenGL errors.

Good luck

Silence
03-09-2017, 11:05 PM
Well, first I would try something simple:

Draw your polygon, without any color animation, without your secondary color.

When this works fine, then add progressively what you want.

From what I see, and except for your second color, the VBO and pointers are set correctly. This latter looks weird, but you'll tell more once you have something working. You'll have to rename o in your fragment shader into output in order it to match the one from your vertex shader.

TheFearlessHobbit
03-10-2017, 04:54 PM
Well, first I would try something simple:

Draw your polygon, without any color animation, without your secondary color.

When this works fine, then add progressively what you want.

From what I see, and except for your second color, the VBO and pointers are set correctly. This latter looks weird, but you'll tell more once you have something working. You'll have to rename o in your fragment shader into output in order it to match the one from your vertex shader.

Hello, thank you for your reply. I managed to get it to change colors. What I did was, I made it switch between one color output to another per time using if-else clause in my fragment shader. However, I seem to be facing another challenge. I want to be able to print out some text near my hexagon, but the text will not show. That's how I'm trying to display text:


text = "Hello";
glRasterPos2i(20, 20); // location to start printing text
for (int i = 0; i < text.size(); ++i)
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, text[i]);

The above code lies in my update() function which looks something like this:


timeSinceStart = glutGet(GLUT_ELAPSED_TIME);
TimeLocation = glGetUniformLocation(program, "Timer ");
timeSinceStart /= 1000; // Convert to MS
glProgramUniform1f(program, TimeLocation, timeSinceStart);

text = "Hello";
glRasterPos2i(20, 20); // location to start printing text
for (int i = 0; i < text.size(); ++i)
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, text[i]); // Print a character on the screen

fRotationAngle += 0.01f
if (fRotationAngle > 360)
{
fRotationAngle -= 360;
}

glutPostRedisplay(); // Tell Glut to re-draw the updated scene

It's worth mentioning that my hexagon is rotating, and I am taking advantage of the glm library that OpenGL offers so I wouldn't have to create and define my own matrices and other mathematical-related concepts. Do you think this is a camera issue? Because if I do glLoadIdentity() all the sudden my hexagon disappears and my text appears. How can I make my text follow my hexagon and not just sit on the origin?

Thank you for your help. :)