The uniform floats in this vertex shader don't work - c++

Details:
This shader draws an orbit path of a planet around a star. My intention is to dim the color of the path when it gets farther away from the opengl camera using the uniform floats "near" and "far" to help calculate the color brightness. When I try to use the uniform float variables, the shader doesn't work at all. I have no idea what could be wrong. (I'm new at openGL and C++).
Vertex shader (Works if not using uniform float variables)
#version 450
layout(location=0) in vec3 vertex_position;
uniform mat4 proj, view; //view and projection matrix
uniform mat4 matrix; // model matrix
uniform float near; //closest orbit distance
uniform float far; //farthest orbit distance
uniform vec3 dist_orbit_center;
out vec3 colour;
void main()
{
vec3 dist_vector = dist_orbit_center + vertex_position;
float dist = length(dist_vector);
//Trying out some debugging. Ignoring dist for now
//float ratio = near / far; // Not working!
float ratio = 0.25 / 0.5; // Working!
colour = vec3(0.0, 1.0, 0.1) * ratio;
gl_Position = proj * view * matrix * vec4(vertex_position, 1.0);
}
Fragment shader (Works if not using uniform float variables)
#version 450
in vec3 colour;
out vec4 frag_colour;
void main()
{
frag_colour=vec4 (colour, 1.0);
}
C++ code for drawing planet orbit path (Working except for glUniform1f ?)
if ((orb.flag))
{
double near;
double far;
// get nearest and farthest point of orbit
distance_to_orbit(near, far, cam.pos, sun.pos, plan[orb.body].orbit_radius, plan[orb.body].orbit_axis, Debug);
GLfloat near_display = (float) (near / DISPLAY_FACTOR);
GLfloat far_display = (float) (far / DISPLAY_FACTOR);
glUseProgram(sh_orbit.program);
glBindVertexArray(sh_orbit.vao);
glUniformMatrix4fv (sh_orbit.view_mat_location, 1, GL_FALSE, cam.view_mat.m);
mat4 m = identity_mat4();
mat4 m2;
m2 = translate(m, sun.display_pos);
glUniformMatrix4fv (sh_orbit.matrix_mat_location, 1, GL_FALSE, m2.m);
// For debugging. Not working.
near_display = 0.25;
glUniform1f(sh_orbit.near_location, near_display);
// For debugging. Not working.
far_display = 0.5;
glUniform1f(sh_orbit.far_location, far_display);
glUniform3fv(sh_orbit.dist_orbit_center_location, 1, sun.display_pos.v);
glDrawArrays(GL_LINE_STRIP, 0, 361);
glBindVertexArray(0);
}
C++ code for creating orbit path of planet for vertex shader (Working)
void Setup_planet_orbit(int index)
{
orb.flag = 1;
orb.body = index;
vec3d axis = plan[orb.body].orbit_axis;
vec3d globe = plan[orb.body].origonal_pos;
for (int lp=0; lp<361; lp++)
{
globe = Rotate_point((double) lp * TO_RADIANS, axis,
plan[orb.body].origonal_pos);
sh_orbit.points[lp*3] = (float) (globe.v[0] / DISPLAY_FACTOR);
sh_orbit.points[lp*3+1] = (float) (globe.v[1] / DISPLAY_FACTOR);
sh_orbit.points[lp*3+2] = (float) (globe.v[2] / DISPLAY_FACTOR);
}
glUseProgram(sh_orbit.program);
glBindVertexArray(sh_orbit.vao);
glBindBuffer(GL_ARRAY_BUFFER, sh_orbit.points_vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, 361*3*sizeof(GLfloat),
sh_orbit.points);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
}
C++ code for initializing shader (Working)
bool Get_orbit_shader()
{
float*& point = sh_orbit.points;
point = (float*)malloc (3 * 361 * sizeof (float));
string vertshader=readFile("orbit.vert.txt");
const char* vertex_shader = vertshader.c_str();
string fragshader=readFile("orbit.frag.txt");
const char* fragment_shader = fragshader.c_str();
// Compile vertex shader program
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
int params=-1;
glGetShaderiv (vs, GL_COMPILE_STATUS, &params);
if (GL_TRUE != params)
{
fprintf(stderr, "ERROR: GL shader index %i did not compile\n", vs);
print_shader_info_log(vs);
return false;
}
// Compile fragment shader program
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
glGetShaderiv (fs, GL_COMPILE_STATUS, &params);
if (GL_TRUE != params)
{
fprintf(stderr, "ERROR: GL shader index %i did not compile\n", fs);
print_shader_info_log(fs);
return false;
}
// Link vertex and shader program
sh_orbit.program = glCreateProgram();
glAttachShader(sh_orbit.program, fs);
glAttachShader(sh_orbit.program, vs);
glLinkProgram(sh_orbit.program);
//Check if linked correctly.
glGetProgramiv(sh_orbit.program, GL_LINK_STATUS, &params);
if (GL_TRUE !=params)
{
fprintf (stderr, "ERROR: could not link shader programme GL index
%u\n",
sh_orbit.program);
print_programme_info_log(sh_orbit.program);
return false;
}
print_all(sh_orbit.program);
mat4 matrix = identity_mat4();
glUseProgram(sh_orbit.program);
glGenVertexArrays(1, &sh_orbit.vao);
glBindVertexArray(sh_orbit.vao);
sh_orbit.view_mat_location = glGetUniformLocation(sh_orbit.program,
"view");
glUniformMatrix4fv (sh_orbit.view_mat_location, 1, GL_FALSE,
cam.view_mat.m);
sh_orbit.proj_mat_location = glGetUniformLocation (sh_orbit.program,
"proj");
glUniformMatrix4fv (sh_orbit.proj_mat_location, 1, GL_FALSE,
cam.proj_mat.m);
sh_orbit.proj_mat_location = glGetUniformLocation (sh_orbit.program,
"matrix");
glUniformMatrix4fv (sh_orbit.matrix_mat_location, 1, GL_FALSE, matrix.m);
sh_orbit.near_location = glGetUniformLocation(sh_orbit.program, "near");
glUniform1f (sh_orbit.near_location, 0);
sh_orbit.far_location = glGetUniformLocation (sh_orbit.program, "far");
glUniform1f (sh_orbit.far_location, 0);
vec3 load;
sh_orbit.dist_orbit_center_location = glGetUniformLocation
(sh_orbit.program, "dist_orbit_center");
glUniform3f (sh_orbit.dist_orbit_center_location, load.v[0], load.v[1],
load.v[2]);
glGenBuffers(1, &sh_orbit.points_vbo);
glBindBuffer(GL_ARRAY_BUFFER, sh_orbit.points_vbo);
glBufferData(GL_ARRAY_BUFFER, 361*3*sizeof(GLfloat), sh_orbit.points,
GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
return true;
}
C++ code for finding nearest and farthest point of orbit in 3D space (Working)
/// Find closest and farthest distance to a 3d disk
/// projection of P-C onto plane is Q-C = P-C - Dot(N,P-C)*N
void distance_to_orbit(double &near, double &far, vec3d point, vec3d center,
double radius, vec3d normal, FILE* Debug)
{
vec3d PmC;
vec3d QmC;
vec3d diff;
double lengthQmC;
double sqr_dist;
double dist;
double temp;
vec3d Closest;
vec3d Farthest;
vec3d vec_temp;
PmC = point - center;
double Dot = dot_d(normal, PmC);
vec_temp = normal * Dot; //Distance to plane that circle is on.
QmC = PmC - vec_temp;
lengthQmC = length(QmC);
vec_temp = QmC * (radius / lengthQmC);
Closest = center + vec_temp;
diff = point - Closest;
sqr_dist = dot_d(diff, diff);
near = sqrt(sqr_dist); //distance to nearest point of 3d disc
vec_temp = center - Closest;
vec_temp *= 2.0f;
diff = Closest + vec_temp;
far = get_distance_d(point, diff); //distance to farthest point of 3d
disc
}

Aren't you setting far (and near) to 0 in glUniform1f (sh_orbit.far_location, 0); expression and getting division by zero?

Related

Render Issues Using Assimp and OpenGL

I am using Assimp to load models to render in OpenGL but am running into an issue where chunks/pieces of a mesh don't render.
Example:
What model is supposed to look like:
What I end up rendering:
As you can see, some of the model is rendering properly, but not all.
I have verified multiple times that the meshes being loaded from assimp are loading the correct vertices and indices into my "Mesh" class. Here is my code for loading a model:
This function will recursively call itself for all child nodes and load each mesh inside the node. Each mesh will then be transformed into my own "Mesh" class by creating a vector of vertices and faces.
void Model::LoadAssimpNode(aiNode* node, const aiScene* scene)
{
// Process assimp meshes
for (unsigned int i = 0; i < node->mNumMeshes; i++)
{
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
this->meshes.push_back(this->LoadAssimpMesh(mesh, scene));
}
// Recursivley processes child nodes
for (unsigned int i = 0; i < node->mNumChildren; i++)
{
this->LoadAssimpNode(node->mChildren[i], scene);
}
}
Mesh Model::LoadAssimpMesh(aiMesh* mesh, const aiScene* scene)
{
std::vector<sVertex> vertices;
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{
sVertex vertex;
vertex.x = mesh->mVertices[i].x;
vertex.y = mesh->mVertices[i].y;
vertex.z = mesh->mVertices[i].z;
vertex.nx = mesh->mNormals[i].x;
vertex.ny = mesh->mNormals[i].y;
vertex.nz = mesh->mNormals[i].z;
if (mesh->mTextureCoords[0])
{
vertex.u0 = mesh->mTextureCoords[0][i].x;
vertex.v0 = mesh->mTextureCoords[0][i].y;
}
vertices.push_back(vertex);
}
std::vector<sTriangle> faces;
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
{
sTriangle face;
aiFace assimpFace = mesh->mFaces[i];
if (assimpFace.mNumIndices != 3)
{
std::cout << "Face is not a triangle!" << std::endl;
}
for (unsigned int j = 0; j < assimpFace.mNumIndices; j++)
{
face.vertIndex[j] = assimpFace.mIndices[j];
}
faces.push_back(face);
}
std::vector<Texture> textures;
if (mesh->mMaterialIndex >= 0)
{
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
// Sampler names should adhere to the following convention:
// Diffuse: texure_diffuseN
// Specular: texture_specularN
// Normal: texture_normalN
// Where N = texture numbers
for (Texture texture : this->LoadAssimpMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse"))
{
this->loadedTextures.insert(std::make_pair(texture.path.C_Str(), texture));
textures.push_back(texture);
}
for (Texture texture : this->LoadAssimpMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular"))
{
this->loadedTextures.insert(std::make_pair(texture.path.C_Str(), texture));
textures.push_back(texture);
}
}
return Mesh(vertices, faces, textures);
}
The sVertex and sTriangle structs are defined as:
struct sVertex
{
float x, y, z;
float nx, ny, nz;
float u0, v0;
};
struct sTriangle
{
unsigned int vertIndex[3];
};
Now that the model is effectively loaded from assimp, we now call the SetupMesh() function which sets up the meshes' respective VAO, VBO and EBO:
void Mesh::SetupMesh()
{
// Generate IDs for our VAO, VBO and EBO
glGenVertexArrays(1, &this->VAO);
glGenBuffers(1, &this->VBO);
glGenBuffers(1, &this->EBO);
glBindVertexArray(this->VAO);
// Now ANY state that is related to vertex or index buffer
// and vertex attribute layout, is stored in the 'state'
// of the VAO...
// Tell open GL where to look for for vertex data
glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(sVertex), &this->vertices[0], GL_STATIC_DRAW);
// Tell open GL where our index buffer begins (AKA: where to look for faces)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->faces.size() * sizeof(sTriangle), &this->faces[0], GL_STATIC_DRAW);
// Set the vertex attributes for this shader
// Layout information can be found in the vertex shader, currently:
// 0 = position
// 1 = normals
// 2 = texture coordinates
glEnableVertexAttribArray(0); // position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(sVertex), (void*) offsetof(sVertex, x));
glEnableVertexAttribArray(1); // normal
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(sVertex), (void*) offsetof(sVertex, nx));
glEnableVertexAttribArray(2); // textureCoordinates
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(sVertex), (void*)offsetof(sVertex, u0));
// Now that all the parts are set up, unbind buffers
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
}
Once this is all setup, I will now call the Draw method for each mesh to render in my render loop:
void Mesh::Draw(const CompiledShader& shader)
{
glm::mat4 matModel = glm::mat4(1.0f);
glm::mat4 matTranslate = glm::translate(glm::mat4(1.0f), this->positionXYZ); // Translation matrix
glm::mat4 rotateX = glm::rotate(glm::mat4(1.0f), this->orientationXYZ.x, glm::vec3(1.0f, 0.0f, 0.0f)); // X axis rotation
glm::mat4 rotateY = glm::rotate(glm::mat4(1.0f), this->orientationXYZ.y, glm::vec3(0.0f, 1.0f, 0.0f)); // Y axis rotation
glm::mat4 rotateZ = glm::rotate(glm::mat4(1.0f), this->orientationXYZ.z, glm::vec3(0.0f, 0.0f, 1.0f)); // Z axis rotation
glm::mat4 matScale = glm::scale(glm::mat4(1.0f), glm::vec3(this->scale, this->scale, this->scale)); // Scale the mesh
glm::mat4 matInvTransposeModel = glm::inverse(glm::transpose(matModel));
// Apply all the transformations to our matrix
matModel = matModel * matTranslate;
matModel = matModel * rotateZ;
matModel = matModel * rotateY;
matModel = matModel * rotateX;
matModel = matModel * matScale;
glUseProgram(shader.ID);
glUniformMatrix4fv(glGetUniformLocation(shader.ID, "matModel"), 1, GL_FALSE, glm::value_ptr(matModel)); // Tell shader the model matrix (AKA: Position orientation and scale)
glUniformMatrix4fv(glGetUniformLocation(shader.ID, "matModelInverseTranspose"), 1, GL_FALSE, glm::value_ptr(matInvTransposeModel));
// Draw the mesh
glBindVertexArray(this->VAO);
glDrawElements(GL_TRIANGLES, this->faces.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
My shaders are very simple where the color of a pixel is equal to the vertex's normal:
Vertex Shader:
#version 420
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 textureCoordinates;
uniform mat4 matModel;
uniform mat4 matView;
uniform mat4 matProjection;
uniform mat4 matModelInverseTranspose; // For normal calculation
out vec4 fVertWorldLocation;
out vec4 fNormal;
out vec2 TextureCoordinates;
void main()
{
mat4 MVP = matProjection * matView * matModel;
gl_Position = MVP * vec4(position, 1.0f);
TextureCoordinates = textureCoordinates;
// The location of the vertex in "world" space (not screen space)
fVertWorldLocation = matModel * vec4(position, 1.0f);
// Calculate the normal based on any rotation we've applied.
// This inverse transpose removes scaling and tranlation (movement)
// from the matrix.
fNormal = matModelInverseTranspose * vec4(normal, 1.0f);
};
Fragment Shader:
#version 420
in vec2 TextureCoordinates;
in vec4 fNormal;
out vec4 Color;
uniform sampler2D texture_diffuse;
void main()
{
//Color = vec4(texture(texture_diffuse, TextureCoordinates));
//Color = vec4(TextureCoordinates, 1.0f, 1.0f);
Color = fNormal;
}
Sorry for the insane length of this post, but I feel that all of it was necessary to get my point across.
If anyone could point out what I am doing wrong here it would be greatly appreciated! I feel like I need an extra pair of eyes here because I have read my code over countless times and can't seem to come up with anything.
Made a stupid mistake, I was under the impression that the "count" argument in the glDrawElements() function wanted the number of faces NOT the number of indices.
The problem was fixed by changing my glDrawElements call from:
glDrawElements(GL_TRIANGLES, this->faces.size(), GL_UNSIGNED_INT, 0);
To this:
glDrawElements(GL_TRIANGLES, this->faces.size() * 3, GL_UNSIGNED_INT, 0);

Problems using glReadPixels with GLSL

I`m trying to render some particles and save the scene to a bmp file,
here is my code
// vertex shader
const char *vertexShader = STRINGIFY(
uniform float pointRadius; // point size in world space
uniform float pointScale; // scale to calculate size in pixels
void main()
{
// calculate window-space point size
vec3 posEye = vec3(gl_ModelViewMatrix * vec4(gl_Vertex.xyz, 1.0));
float dist = length(posEye);
gl_PointSize = pointRadius * (pointScale / dist);
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0);
gl_FrontColor = gl_Color;
}
);
// pixel shader for rendering points as shaded spheres
const char *spherePixelShader = STRINGIFY(
void main()
{
const vec3 lightDir = vec3(0.577, 0.577, 0.577);
// calculate normal from texture coordinates
vec3 N ;
N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0);
float mag = dot(N.xy, N.xy);
if (mag > 1.0) discard; // kill pixels outside circle
N.z = sqrt(1.0 - mag);
// calculate lighting
float diffuse = max(0.0, dot(lightDir, N));
gl_FragColor = gl_Color *diffuse;
}
Here is the rendering code
Position of the particles are stored in the VBO target_point_buffer as well as corresponding color data
void display()
{
//pointsprite
glEnable(GL_POINT_SPRITE);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_NV);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
//attach shader
glUseProgram(program);
glUniform1f(glGetUniformLocation(program, "pointScale"), winHeight / tanf(fov*0.5f*(float)M_PI / 180.0f));
glUniform1f(glGetUniformLocation(program, "pointRadius"),radius[0]*scale);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//use vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexPointer(3, GL_DOUBLE, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
//color buffer
glBindBuffer(GL_ARRAY_BUFFER, color_vbo);
glColorPointer(3, GL_FLOAT, 0, 0);
glEnableClientState(GL_COLOR_ARRAY);
Drawsomething();
}
//Save the scene as an bmp file
void save_as_bmp(char *filename)
{
GLbyte pBits[Imagesize];
GLint iViewPort[4];
GLuint lastBuffer;
glGetIntegerv(GL_VIEWPORT,iViewPort);
glGetIntegerv(GL_READ_BUFFER,&lastBUffer);
glReadPixels(iViewPort[0], iViewPort[1], iViewPort[2], iViewPort[3], GL_BGR, GL_UNSIGNED_BYTE, pBits);
writeBMP(filename,pBits);
}
I`ve got the expected scene like this:
However,when I tried to save the scene as a BMP file,the result was not like I expected:
I suppose that it might be something wrong with the gl_TexCoord in the shader, but I can`t figure it out. Can anyone help?
Set GL_PACK_ALIGNMENT to 1 before your glReadPixels() call if you're going to use a three-component format like GL_BGR with GL_UNSIGNED_BYTE.

Particle System error

Im working in Particle System Class from this tutorial Particles - Anton's OpenGL 4 Wiki - Dr Anton Gerdelan
Code:
//Pixel Shader
// shader to update a particle system based on a simple kinematics function
#version 150
in vec3 v; // initial velocity
in float tZero; // start time
uniform mat4 projViewModelMatrix;
uniform vec3 emitterPos_wor; // emitter position in world coordinates
uniform float T; // system time T in seconds
out float opacity;
void main() {
// work out how many seconds into our particle's life-time we are (after its starting time)
float t = T - tZero;
vec3 p;
// gradually make particle more transparent over its life-time
opacity = 1 - (t / 3) - 0.2;
// particle stays put until it has reached its birth second
if (t > 0) {
// gravity
vec3 a = vec3(0,-10,0);
// this is a standard kinematics equation of motion with velocity (from VBO) and acceleration (gravity)
p = emitterPos_wor + v * t + 0.5 * a * t * t;
} else {
p = emitterPos_wor;
}
gl_Position = projViewModelMatrix * vec4(p, 1);
}
// Vertex shader
// shader to render simple particle system's points
#version 150
uniform sampler2D textureMap; // I used a texture for my particles
out vec4 fragColour;
uniform vec4 Color;
in float opacity;
void main() {
vec4 texcol = texture2D(textureMap, gl_PointCoord); // using point uv coordinates which are pre-defined over the point
fragColour = vec4(1-opacity,1-opacity,1-opacity,1-opacity) * texcol * Color; // bright blue!
}
/////// CPU
bool ParticleSystem::init(vec3 Position){
std::vector<vec3> Velocidad;
std::vector<float> Life;
for ( int i = 0; i < MAX_PARTICLES; i++ ) {
Velocidad.push_back(vec3(0,-1,0));
}
for ( int i = 0; i < MAX_PARTICLES; i++ ) {
Life.push_back(0.001f * (float)(i));
}
glGenVertexArrays( 1, &m_VAO );
glBindVertexArray( m_VAO );
glGenBuffers(ARRAY_SIZE_IN_ELEMENTS(m_Buffers), m_Buffers);
glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VEL_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Velocidad[0]) * Velocidad.size(), &Velocidad[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[LIF_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Life[0]) * Life.size(), &Life[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
glBindVertexArray(0);
return true;
}
/////////////////// FINAL RENDER
bool ParticleSystem::render(){
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,ModeloOrtho.getTextureFromID(24));
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
glEnable(GL_POINT_SPRITE);
glPointSize(150.0f);
shaderParticle.setUniform("projViewModelMatrix",vsml->get(VSMathLib::PROJ_VIEW_MODEL));
shaderParticle.setUniform("emitterPos_wor",ParticleInit);
shaderParticle.setUniform("T",ParticleTime);
shaderParticle.setUniform("Color",ColorParticle);
glUseProgram(shaderParticle.getProgramIndex());
glBindVertexArray(m_VAO);
glDrawElements(GL_POINTS, 0, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,0);
return true;
}
The problem is that nothing happens.
And if I change this line:
glDrawElements (GL_POINTS, MAX_PARTICLES, GL_UNSIGNED_INT, 0);
Crash the system.
What am I doing wrong?
vertex shader
/* shader to update a particle system based on a simple kinematics function */
#version 410 core
layout (location = 0) in vec3 v_i; // initial velocity
layout (location = 1) in float start_time;
uniform mat4 V, P;
uniform vec3 emitter_pos_wor; // emitter position in world coordinates
uniform float elapsed_system_time; // system time in seconds
// the fragment shader can use this for it's output colour's alpha component
out float opacity;
void main() {
// work out the elapsed time for _this particle_ after its start time
float t = elapsed_system_time - start_time;
// allow time to loop around so particle emitter keeps going
t = mod (t, 3.0);
opacity = 0.0;
vec3 p = emitter_pos_wor;
// gravity
vec3 a = vec3 (0.0, -1.0, 0.0);
// this is a standard kinematics equation of motion with velocity and
// acceleration (gravity)
p += v_i * t + 0.5 * a * t * t;
// gradually make particle fade to invisible over 3 seconds
opacity = 1.0 - (t / 3.0);
gl_Position = P * V * vec4 (p, 1.0);
gl_PointSize = 15.0; // size in pixels
}
fragment shader
/* shader to render simple particle system points */
#version 410 core
in float opacity;
uniform sampler2D tex; // optional. enable point-sprite coords to use
out vec4 frag_colour;
const vec4 particle_colour = vec4 (0.4, 0.4, 0.8, 0.8);
void main () {
// using point texture coordinates which are pre-defined over the point
vec4 texel = texture (tex, gl_PointCoord);
frag_colour.a = opacity * texel.a;
frag_colour.rgb = particle_colour.rgb * texel.rgb;
}

OpenGL GLM Matrix Calculations Not Working

OpenGL glm calculations don't seem to work in my program. Nothing moves even when i use the glm translate function to translate the z axis with a variable every frame. Am i missing something?
main.cpp
#define GLEW_STATIC
#define NO_SDL_GLEXT
#include "glew.h"
#include <sdl.h>
#undef main
#include "SDL_opengl.h"
#include "timer.h"
#include <time.h>
#include <shader.h>
using namespace std;
#include <glm/gtc/matrix_projection.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
unsigned int vaoID[1]; // Our Vertex Array Object
unsigned int vboID[1]; // Our Vertex Buffer Object
glm::mat4 projectionMatrix; // Store the projection matrix
glm::mat4 viewMatrix; // Store the view matrix
glm::mat4 modelMatrix; // Store the model matrix
Shader *shader; // Our GLSL shader
float ztransform(0);
bool exited(false);
SDL_Event event;
const int FRAMES_PER_SECOND = 60;
void createSquare(void) {
float* vertices = new float[18]; // Vertices for our square
vertices[0] = -0.5; vertices[1] = -0.5; vertices[2] = 0.0; // Bottom left corner
vertices[3] = -0.5; vertices[4] = 0.5; vertices[5] = 0.0; // Top left corner
vertices[6] = 0.5; vertices[7] = 0.5; vertices[8] = 0.0; // Top Right corner
vertices[9] = 0.5; vertices[10] = -0.5; vertices[11] = 0.0; // Bottom right corner
vertices[12] = -0.5; vertices[13] = -0.5; vertices[14] = 0.0; // Bottom left corner
vertices[15] = 0.5; vertices[16] = 0.5; vertices[17] = 0.0; // Top Right corner
glGenVertexArrays(1, &vaoID[0]); // Create our Vertex Array Object
glBindVertexArray(vaoID[0]); // Bind our Vertex Array Object so we can use it
glGenBuffers(1, vboID); // Generate our Vertex Buffer Object
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]); // Bind our Vertex Buffer Object
glBufferData(GL_ARRAY_BUFFER, 18 * sizeof(GLfloat), vertices, GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); // Set up our vertex attributes pointer
glEnableVertexAttribArray(0); // Disable our Vertex Array Object
glBindVertexArray(0); // Disable our Vertex Buffer Object
delete [] vertices; // Delete our vertices from memory
}
void startGL()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_SetVideoMode(800, 600, 32, SDL_OPENGL);
glewInit();
glClearColor(0.4f, 0.0f, 1.0f, 0.0f);
projectionMatrix = glm::perspective(60.0f, (float)800 / (float)600, 0.1f, 100.f); // Create our perspective projection matrix
shader = new Shader("shader.vert", "shader.frag"); // Create our shader by loading our vertex and fragment shader
createSquare();
}
void drawstuff()
{
glViewport(0, 0, 800, 600); // Set the viewport size to fill the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Clear required buffers
viewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, ztransform)); // Create our view matrix which will translate us back 5 units
modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f)); // Create our model matrix which will halve the size of our model
shader->bind(); // Bind our shader
int projectionMatrixLocation = glGetUniformLocation(shader->id(), "projectionMatrix"); // Get the location of our projection matrix in the shader
int viewMatrixLocation = glGetUniformLocation(shader->id(), "viewMatrix"); // Get the location of our view matrix in the shader
int modelMatrixLocation = glGetUniformLocation(shader->id(), "modelMatrix"); // Get the location of our model matrix in the shader
glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix[0][0]); // Send our projection matrix to the shader
glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]); // Send our view matrix to the shader
glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]); // Send our model matrix to the shader
glBindVertexArray(vaoID[0]); // Bind our Vertex Array Object
glDrawArrays(GL_TRIANGLES, 0, 6); // Draw our square
glBindVertexArray(0); // Unbind our Vertex Array Object
shader->unbind(); // Unbind our shader
}
int main (int argc, char* args[])
{
Timer fps;
startGL();
while(exited == false)
{
while( SDL_PollEvent(&event) )
{
if( event.type == SDL_QUIT )
exited = true;
}
drawstuff();
ztransform+=.1
SDL_GL_SwapBuffers();
if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
}
SDL_Quit();
return 0;
}
shader.frag
#version 150 core
in vec3 pass_Color;
out vec4 out_Color;
void main(void)
{
out_Color = vec4(pass_Color, 1.0);
}
shader.vert
#version 150 core
in vec3 in_Position;
in vec3 in_Color;
out vec3 pass_Color;
void main(void)
{
gl_Position = vec4(in_Position, 1.0);
pass_Color = in_Color;
}
You have to apply your transformation in your vertex shader.
you should define in your vertex shader
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
And then apply these transformations to your input position (note: i may have gotten the order wrong)
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_position, 1.0);
Generally though, you would multiply the 3 matrices together in your c++ program and pass in a modelViewProjection matrix.

Assistance in Debug OpenGL glsl Shader or Code using it

I am working on adding a phong shader to my working program. Basically, after I implemented my new shaders, my code gets a "Segmentation Fault: 11" during:
glDrawArrays(GL_TRIANGLES, 0, mCubes.getArrayNumberOfElements());
I know the number of elements is correct because it worked for my previous, simple shader.
Here is my Vertex Shader:
// vertex shader
attribute vec4 vPosition;
attribute vec3 vNormal;
varying vec4 color; //vertex shader
// light and material properties
uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform mat4 ModelView;
//uniform mat4 Projection;
uniform vec4 LightPosition;
uniform float Shininess;
vec3 L, H, N, pos, E;
vec4 diffuse, specular, ambient;
float Kd, Ks;
void main()
{
// Transform vertex position into eye coordinates
pos = (ModelView * vPosition).xyz;
L = normalize( LightPosition.xyz - pos );
E = normalize( -pos );
H = normalize( L + E );
// Transform vertex normal into eye coordinates
N = normalize( ModelView*vec4(vNormal, 0.0) ).xyz;
// Compute terms in the illumination equation
ambient = AmbientProduct;
Kd = max( dot(L, N), 0.0 );
diffuse = Kd*DiffuseProduct;
Ks = pow( max(dot(N, H), 0.0), Shininess );
specular = Ks * SpecularProduct;
if( dot(L, N) < 0.0 )
specular = vec4(0.0, 0.0, 0.0, 1.0);
gl_Position = ModelView * vPosition;
color = ambient + diffuse + specular;
color.a = 1.0;
}
Here is my display function in which the code ends up getting the fault:
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
vector<float> cell = mCubes.getCell();
mat4 matrix = rot * scale(1.0/cell[0], 1.0/cell[1], 1.0/cell[2]) * translate(-cell[0]/2.0, -cell[1]/2.0, -cell[2]/2.0);
glUniformMatrix4fv(vShaderModelView, 1, GL_TRUE, matrix);
glDrawArrays(GL_TRIANGLES, 0, mCubes.getArrayNumberOfElements());
glutSwapBuffers();
glFlush();
}
And here is my init function that mostly sets up and interacts with the shaders:
void init() {
// Create a vertex array object
GLuint vao;
#ifdef __APPLE__
glGenVertexArraysAPPLE( 1, &vao );
glBindVertexArrayAPPLE( vao );
#else
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
#endif
// Create and initialize a buffer object
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData( GL_ARRAY_BUFFER,
mCubes.getDisplayArraySize() + mCubes.getDisplayArraySize()*3, NULL, GL_STATIC_DRAW );
GLintptr offset = 0;
glBufferSubData(GL_ARRAY_BUFFER, offset, mCubes.getDisplayArraySize(), mCubes.getDisplayArray());
offset+= mCubes.getDisplayArraySize();
glBufferSubData(GL_ARRAY_BUFFER, offset, mCubes.getDisplayArraySize(), mCubes.getNormalVector());
// Load shaders and use the resulting shader program
string evname = "PROTCAD3DIR";
string path = PCGeneralIO::getEnvironmentVariable(evname);
path += "/data/shaders/";
#ifdef __APPLE__
string vshadername = path + "kw_vshader1_mac.glsl";
string fshadername = path + "kw_fshader1_mac.glsl";
//#else
// string vshadername = path + "kw_vshader1.glsl";
// string fshadername = path + "kw_fshader1.glsl";
#endif
GLuint program = InitShader( vshadername.c_str(), fshadername.c_str() );
glUseProgram(program);
// Initialize the vertex position attribute from the vertex shader
GLuint vShaderPosition = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(vShaderPosition);
glVertexAttribPointer(vShaderPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
GLuint vShaderNormal = glGetAttribLocation(program, "vNormal");
glEnableVertexAttribArray(vShaderNormal);
//glVertexAttribPointer(vShaderPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset)); //this was the ORIGINAL PROBLEM, now commented out and below is solution
glVertexAttribPointer(vShaderNormal, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset));
vShaderModelView = glGetUniformLocation(program, "ModelView");
vShaderLightPosition = glGetUniformLocation(program, "LightPosition");
vShaderAmbientProduct = glGetUniformLocation(program, "AmbientProduct");
vShaderDiffuseProduct = glGetUniformLocation(program, "DiffuseProduct");
vShaderSpecularProduct = glGetUniformLocation(program, "SpecularProduct");
vShaderShininess = glGetUniformLocation(program, "SpecularProduct");
glEnable( GL_DEPTH_TEST );
vec4 light = vec4(0.5,1.5,1.0,0.0);
glUniform4fv(vShaderLightPosition, 1, light);
vec4 amb = vec4(1.0f,0.0f,0.20f,1.0f);
glUniform4fv(vShaderAmbientProduct, 1, amb);
vec4 diff = vec4(0.5f,0.5f,0.5f,1.0f);
glUniform4fv(vShaderDiffuseProduct, 1, diff);
vec4 spec = vec4(0.80f,0.80f,0.80f,1.0f);
glUniform4fv(vShaderSpecularProduct, 1, spec);
float shin = 6.0f;
glUniform1f(vShaderShininess,shin);
glClearColor(.2, .2, .2, 1); /* Grey background */
}
If you have any question, feel free to ask and I will elaborate. I feel that either the vertex shader itself has a problem, or the way I interact with the shader is doing something wonky. Any help or suggestions are accepted!
EDIT::: (code edited to reflect solution)The problem was in the second:
glVertexAttribPointer(vShaderPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset));
which should have read:
glVertexAttribPointer(vShaderNormal, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset));
And was a stupid copy/paste mistake. However, the finished product still does not look correct:
![at Rotation 0 it seems to be fully colored][1]
http://i.stack.imgur.com/CKJ3f.png
![Rotation of a little bit reveals some odd behavior][2]
http://i.stack.imgur.com/kyRfI.png
![Even more rotation leads you to pull your hair out][3]
i.stack.imgur.com/lYOzK.png
![Then it whites out and you know i screwed up!!][4]
i.stack.imgur.com/FZcqF.png
So, as you rotate the color gets screwed up and turns white, black, patterned and everything, but this is obviously incorrect.
Edit::: This is my attempt to "Correct" the issue of passing the wrong amount of values with vNormal:
void init() {
// Create a vertex array object
GLuint vao;
#ifdef __APPLE__
glGenVertexArraysAPPLE( 1, &vao );
glBindVertexArrayAPPLE( vao );
#else
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
#endif
// Create and initialize a buffer object
GLuint buffer;
realVec *normArray = new realVec[mCubes.getNormalArraySize()];//vec4 array compared to vec3 array
normArray = mCubes.getNormalVector(); // new array of normals
for(int i=0; i<mCubes.getArrayNumberOfElements();i++){
printf("Normal at %d is %f \n",i,normArray[i][0]); //to print normals
printf("Normal at %d is %f \n",i,normArray[i][1]); //to print normals
printf("Normal at %d is %f \n",i,normArray[i][2]); //to print normals
}
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData( GL_ARRAY_BUFFER,
mCubes.getDisplayArraySize() + mCubes.getNormalArraySize(), NULL, GL_STATIC_DRAW ); //Changed size for vec3 array of normals
GLintptr offset = 0;
glBufferSubData(GL_ARRAY_BUFFER, offset, mCubes.getDisplayArraySize(), mCubes.getDisplayArray());
offset+= mCubes.getDisplayArraySize();
glBufferSubData(GL_ARRAY_BUFFER, offset, mCubes.getNormalArraySize(), normArray);
// Load shaders and use the resulting shader program
string evname = "PROTCAD3DIR";
string path = PCGeneralIO::getEnvironmentVariable(evname);
path += "/data/shaders/";
#ifdef __APPLE__
string vshadername = path + "kw_vshader1_mac.glsl";
string fshadername = path + "kw_fshader1_mac.glsl";
//#else
// string vshadername = path + "kw_vshader1.glsl";
// string fshadername = path + "kw_fshader1.glsl";
#endif
GLuint program = InitShader( vshadername.c_str(), fshadername.c_str() );
glUseProgram(program);
//offset =0;
// Initialize the vertex position attribute from the vertex shader
GLuint vShaderPosition = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(vShaderPosition);
glVertexAttribPointer(vShaderPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
GLuint vShaderNormal = glGetAttribLocation(program, "vNormal");
glEnableVertexAttribArray(vShaderNormal);
glVertexAttribPointer(vShaderNormal, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset));
//vShaderMatrix = glGetUniformLocation(program, "vMatrix");
//vShaderColor = glGetUniformLocation(program, "vColor")
vShaderModelView = glGetUniformLocation(program, "ModelView");
vShaderLightPosition = glGetUniformLocation(program, "LightPosition");
//vShaderProjection = glGetUniformLocation(program, "Projection");
vShaderAmbientProduct = glGetUniformLocation(program, "AmbientProduct");
vShaderDiffuseProduct = glGetUniformLocation(program, "DiffuseProduct");
vShaderSpecularProduct = glGetUniformLocation(program, "SpecularProduct");
vShaderShininess = glGetUniformLocation(program, "SpecularProduct");
glEnable( GL_DEPTH_TEST );
vec4 light = vec4(0.5,1.5,1.0,0.0);
glUniform4fv(vShaderLightPosition, 1, light);
vec4 amb = vec4(1.0f,0.0f,0.20f,1.0f);
glUniform4fv(vShaderAmbientProduct, 1, amb);
vec4 diff = vec4(0.5f,0.5f,0.5f,1.0f);
glUniform4fv(vShaderDiffuseProduct, 1, diff);
vec4 spec = vec4(0.80f,0.80f,0.80f,1.0f);
glUniform4fv(vShaderSpecularProduct, 1, spec);
float shin = 6.0f;
glUniform1f(vShaderShininess,shin);
glClearColor(.2, .2, .2, 1); /* Grey background */
}
Should I maybe change the light, ambient, specular, and diffuse properties? I am not sure what the problem is.
You pass your vNormal attribute data using the following code
glVertexAttribPointer(vShaderNormal, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset));
This indicates that your normal have 4 components, whereas in your vertex shader you declare it as
attribute vec3 vNormal;
This mismatch may be related to your problem if the normals are misinterpreted.