OPENGL: drawing multiple point lights - c++

I'm having an issue drawing multiple point lights in my scene. I am working on a simple maze-style game in OpenGL, where the maze is randomly generated. Each "room" in the maze is represented by a Room struct, like so:
struct Room
{
int x, z;
bool already_visited, n, s, e, w;
GLuint vertex_buffer, texture, uv_buffer, normal_buffer;
std::vector<glm::vec3>vertices, normals;
std::vector<glm::vec2>uvs;
glm::vec3 light_pos; //Stores the position of a light in the room
};
Each room has a light in it, the position of this light is stored in light_pos. This light is used in a simple per-vertex shader, like so:
layout(location = 0) in vec3 pos;
layout(location = 1) in vec2 uv_coords;
layout(location = 2) in vec3 normal;
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform vec3 lightpos;
out vec2 vs_uv;
out vec3 vs_normal;
out vec3 color;
void main()
{
gl_Position = mvpMatrix * vec4(pos,1.0);
vs_normal = normal;
vs_uv = uv_coords;
vec3 lightVector = normalize(lightpos - pos);
float diffuse = clamp(dot(normal,lightVector),0.0,1.0);
color = vec3(diffuse,diffuse,diffuse);
}
My fragment shader looks like this (ignore the "vs_normal", it is unused for now):
in vec2 vs_uv;
in vec3 vs_normal;
in vec3 color;
uniform sampler2D tex;
out vec4 frag_color;
void main()
{
frag_color = vec4(color,1.0) * texture(tex,vs_uv).rgba;
}
And my drawing code looks like this:
mat4 mvMatrix = view_matrix*model_matrix;
mat4 mvpMatrix = projection_matrix * mvMatrix;
glBindVertexArray(vertexBufferObjectID);
glUseProgram(shaderProgram);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
for (int x = 0; x < NUM_ROOMS_X; x++)
{
for (int z = 0; z < NUM_ROOMS_Z; z++)
{
//int x = int(std::round(position.x / ROOM_SIZE_X_MAX));
//int z = int(std::round(position.z / ROOM_SIZE_Z_MAX));
Room rm = room_array[x][z];
glBindBuffer(GL_ARRAY_BUFFER, rm.vertex_buffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glBindBuffer(GL_ARRAY_BUFFER, rm.uv_buffer);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glBindBuffer(GL_ARRAY_BUFFER, rm.normal_buffer);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glUniformMatrix4fv(mvpMatrixID, 1, GL_FALSE, &mvpMatrix[0][0]);
glUniformMatrix4fv(mvMatrixID, 1, GL_FALSE, &mvMatrix[0][0]);
glUniform3fv(light_ID, 3, &rm.light_pos[0]); //Here is where I'm setting the new light position. It looks like this is ignored
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, rm.texture);
glUniform1i(texture_ID, 0);
glDrawArrays(GL_QUADS, 0, rm.vertices.size());
}
}
glUseProgram(0);
glBindVertexArray(0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glBindTexture(GL_TEXTURE_2D, 0);
However, here is what the result looks like (I've modified my drawing code to draw a box where each light is located, and I've circled the room at position (0,0)):
http://imgur.com/w4uPMD6
As you can see, it looks like only the light at position (0,0) affects any of the rooms on the map, the other lights are simply ignored. I know that the lights are positioned correctly, because the boxes I use to show the positions are correct. I think even though I'm setting the new light_pos, it isn't going through for some reason. Any ideas?

One thing that your are doing, which is not very common, is to pass the light position as a vertex attribute. Optimally, you should pass it to the shader as a uniform variable, just as you do with the matrices. But I doubt that is the problem here.
I believe your problem is that you are doing the light calculations in different spaces. The vertexes of the surfaces that you draw are in object/model space, while I'm guessing, your light is located at a point defined in world space. Try multiplying your light position by the inverse of the model matrix you are applying to the vertexes. I'm not familiar with GLM, but I figure there must be an inverse() function in it:
vec3 light_pos_object_space = inverse(model_matrix) * rm.light_pos;
glVertexAttrib3fv(light_ID, &light_pos_object_space[0]);

Figured out my problem. I was calling this function:
glUniform3fv(light_ID, 3, &rm.light_pos[0]);
When I should have been calling this:
glUniform3fv(light_ID, 1, &rm.light_pos[0]);

Related

openGL rectangle rendering triangle instead?

So i'm trying to render a rectangle in openGL using index buffers however instead i'm getting a triangle with one vertex at the origin (even though no vertex in my rectangle is suppsoed to go at the origin).
void Renderer::drawRect(int x,int y,int width, int height)
{
//(Ignoring method arguments for debugging)
float vertices[12] = {200.f, 300.f, 0.f,
200.f, 100.f, 0.f,
600.f, 100.f, 0.f,
600.f, 300.f, 0.f};
unsigned int indices[6] = {0,1,3,1,2,3};
glBindVertexArray(this->flat_shape_VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this->element_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,this->render_buffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glUseProgram(this->shader_program);
glUniformMatrix4fv(this->model_view_projection_uniform,1,GL_FALSE,glm::value_ptr(this->model_view_projection_mat));
glUniform3f(this->color_uniform,(float) this->color.r,(float)this->color.g,(float)this->color.b);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,nullptr);
}
My projection matrix is working fine I can still render a triangle at the correct screen coords. I suspect maybe I did index buffering wrong? Transformation matrices also work fine, atleast on my triangles.
Edit:
The VAO's attributes are set up in the class constructor with glVertexAttribPointer();
Edit 2:
I disabled shaders completely and something interesting happened.
Here is the shader source code:
(vertex shader)
#version 330 core
layout (location = 0) in vec3 aPos;
uniform mat4 mvp;
uniform vec3 aColor;
out vec3 color;
void main()
{
gl_Position = mvp * vec4(aPos, 1.0);
color = aColor;
}
(fragment shader)
#version 330 core
in vec3 color;
out vec4 FragColor;
void main()
{
FragColor = vec4(color,1.0f);
}
My projection matrix shouldn't work with shaders disabled yet I still see a triangle rendering on the screen..??
What is the stride argument of glVertexAttribPointer? stride specifies the byte offset between consecutive generic vertex attributes. In your case it should be 0 or 12 (3*sizeof(float)) but if you look at your images it seems to be 24 because the triangle has the 1st (200, 300) and 3rd (600, 100) vertices and one more vertex with the coordinate (0, 0).
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), nullptr);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);

3D Model Translation deforming the object

I have created a program that renders a 3d cube, and now I'd like to change the position of the cube. The matrix multiplication I'm doing now seems to distort the cube instead of changing it's position. The distortion is small for values in the 0.1 - 0.4 range and fill the whole screen for larger values.
The vertex shader:
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;
uniform mat4 projectionMatrix;
uniform mat4 cameraMatrix;
uniform mat4 modelMatrix;
out vec3 fragmentColor;
void main()
{
gl_Position = projectionMatrix * cameraMatrix * modelMatrix * vec4(vertexPosition_modelspace,1);
fragmentColor = vertexColor;
}
Model.cpp (note that modelMatrix is initialized to an identity matrix and I'm using glm)
void Model::SetPos(glm::vec3 coords)
{
modelMatrix[0][3] = coords[0];
modelMatrix[1][3] = coords[1];
modelMatrix[2][3] = coords[2];
}
void Model::Render()
{
// Select the right program
glUseProgram(program);
// Set the model matrix in the shader
GLuint MatrixID = glGetUniformLocation(program, "modelMatrix");
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, value_ptr(modelMatrix));
// Setup the shader color attributes
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// Setup the shader vertex attributes
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// Draw the model
glDrawArrays(GL_TRIANGLES, 0, triangles);
// Now disable the attributes
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
The other matrices are initialized like this and remain unchanged:
cameraMatrix = glm::lookAt(pos, target, orient);
projectionMatrix = glm::perspective(45.0f, 1280.0f / 720.0f, 0.1f, 100.0f);
The glm library produces column major matrices. You've also specified GL_FALSE to glUniformMatrix4fv which is correct for column major matrices. However, when you are setting the position you are setting wrong values. This code:
void Model::SetPos(glm::vec3 coords)
{
modelMatrix[0][3] = coords[0];
modelMatrix[1][3] = coords[1];
modelMatrix[2][3] = coords[2];
}
Causes the matrix produce non 1.0 values in the w component after multiplication. This can cause some weird distortions. You should change SetPos to this:
void Model::SetPos(glm::vec3 coords)
{
modelMatrix[3][0] = coords[0];
modelMatrix[3][1] = coords[1];
modelMatrix[3][2] = coords[2];
}

OpenGL transformation in NDC coordinates instead of screen coordinates (2D)

I'm having trouble figuring out how to position a 2D object in my scene using screen coordinates. At the moment I have something working (code below) but it want NDC coordinates which isn't easy to work with. I can't figure out where it's going wrong. I think I've used everything like it should be so I think I'm forgetting something.
Here's the code that handles the drawing of the objects in my scene:
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// RENDERING HERE
colorProgram.bind();
for (size_t t = 0; t < objectsWithGraphicsComponentInThisScene.size(); ++t)
{
// set texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, objectsWithGraphicsComponentInThisScene[t]->getComponent<GraphicsComponent>()->getTexture());
GLint texLocation = colorProgram.getUniformLocation("texSampler");
glUniform1i(texLocation, 0);
glm::mat4 trans;
trans = glm::translate(glm::mat4x4(1.0f), glm::vec3(objectsWithGraphicsComponentInThisScene[t]->getPosition().x, objectsWithGraphicsComponentInThisScene[t]->getPosition().y, 0));
GLint transMatLocation = colorProgram.getUniformLocation("transformMatrix");
glUniformMatrix4fv(transMatLocation, 1, GL_FALSE, glm::value_ptr(trans));
// set camera Matrix
GLint projMatLocation = colorProgram.getUniformLocation("projectionMatrix");
glm::mat4 cameraMatrix = camera->getCameraMatrix();
glUniformMatrix4fv(projMatLocation, 1, GL_FALSE, glm::value_ptr(cameraMatrix));
objectsWithGraphicsComponentInThisScene[t]->getComponent<GraphicsComponent>()->getSprite()->draw();
// unbind all
glBindTexture(GL_TEXTURE_2D, 0);
}
colorProgram.unbind();
where colorProgram is the shader my sprites use and getPosition() simply returns a value which I've set. (where the x y and z value should be given as screen coordinates). so for example, getPosition might return [100, 50, 0] but that will render the object outside of the screen (the screen is 1280x720).
Now the code that renders the sprite (objectsWithGraphicsComponentInThisScene[t]->getComponent()->getSprite()->draw();):
void Sprite::draw()
{
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glEnableVertexAttribArray(0);
// position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
//color
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));
// uv
glVertexAttribPointer(2, 2, GL_FLOAT, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
And here's the code in the shader (colorProgram):
VERTEX SHADER:
#version 130
// per vertex
// input data from VBO
in vec2 vertexPosition;
in vec4 vertexColor;
in vec2 vertexUV;
// output to fragment shader
out vec4 fragmentColor;
out vec2 fragmentUV;
uniform mat4 projectionMatrix;
uniform mat4 transformMatrix;
void main()
{
mat4 resultMatrix = transformMatrix * projectionMatrix;
gl_Position.xy = (resultMatrix * vec4(vertexPosition, 0.0, 1.0)).xy;
gl_Position.z = 0.0;
// Indicate that the coordinates are normalized
gl_Position.w = 1.0;
fragmentColor = vertexColor;
fragmentUV = vec2(vertexUV.x, 1.0 - vertexUV.y);
}
FRAGMENT SHADER
#version 130
// per pixel
// input from vertex shader
in vec4 fragmentColor;
in vec2 fragmentUV;
out vec4 color;
uniform sampler2D texSampler;
void main()
{
vec4 textureColor = texture(texSampler, fragmentUV);
if (textureColor.a < 0.5) discard;
color = fragmentColor * textureColor;
}
If you need more code I'd be happy to add more although I think this is everything that is needed.
This sequence in your vertex shader
mat4 resultMatrix = transformMatrix * projectionMatrix;
gl_Position.xy = (resultMatrix * vec4(vertexPosition, 0.0, 1.0)).xy;
is very unlikely what you actually want. Since you use the matrix * vector convention, you'll end up with
position = transform * projection * v
= transform * (projection * v)
In other words: you apply the transformation after the projection. Since after the projection, the viewing volume is in the [-1,1]^3 range (in euclidean NDC space after the perspecitive divide. In reality, we are working in clip space here, where it is [-w,w]^3, but this is not really important in this context,), translating the object by values like 100 units will certainly move it out of the frustum.
You should just reverse the order of your matrix multiplication.

Make many lit triangles look smooth

I am trying to create a program that shows a wave-like animation using Perlin Noise by creating many triangles.
This is the important part of my program:
class OGLT9_NOISE
{
//class for Perlin Noise (noise3d()) and Fractional Brownian Motion (fmb()) generaion
};
glm::vec3 OGLT9_GRAPHICS::getNormal(glm::vec3 a, glm::vec3 b, glm::vec3 c)
{
return glm::normalize(glm::cross(c-a, b-a));
}
void generateTerrain(OGLT9_SHADER *oglt9Shader)
{
static OGLT9_NOISE noise;
static float yValue = 0;
int terrainRes = 7; //terrain's resolution
float terrainSpacing = 10.0f;
vector<glm::vec3> vertexData;
vector<glm::vec3> normalData;
multi_array<float, 2> terrain;
terrain.resize(extents[1<<terrainRes][1<<terrainRes]);
for(long z=-(1<<(terrainRes-1)); z<(1<<(terrainRes-1)); z++)
for(long x=-(1<<(terrainRes-1)); x<(1<<(terrainRes-1)); x++)
terrain[z+(1<<(terrainRes-1))][x+(1<<(terrainRes-1))] = (noise.fbm((double)x/16.0, yValue, (double)z/16.0, 2, 0.4, 1.2, 2.9, 1.1)/2.0+0.5)*100.0;
for(long z=0; z<(1<<terrainRes)-1; z++)
{
for(long x=0; x<(1<<terrainRes)-1; x++)
{
vertexData.push_back(glm::vec3((float)x*terrainSpacing, terrain[z][x], (float)z*terrainSpacing));
vertexData.push_back(glm::vec3(((float)x+1.0f)*terrainSpacing, terrain[z+1][x+1], ((float)z+1.0f)*terrainSpacing));
vertexData.push_back(glm::vec3(((float)x+1.0f)*terrainSpacing, terrain[z][x+1], (float)z*terrainSpacing));
vertexData.push_back(glm::vec3((float)x*terrainSpacing, terrain[z][x], (float)z*terrainSpacing));
vertexData.push_back(glm::vec3((float)x*terrainSpacing, terrain[z+1][x], ((float)z+1.0f)*terrainSpacing));
vertexData.push_back(glm::vec3(((float)x+1.0f)*terrainSpacing, terrain[z+1][x+1], ((float)z+1.0f)*terrainSpacing));
normalData.push_back(getNormal(vertexData[vertexData.size()-6], vertexData[vertexData.size()-5], vertexData[vertexData.size()-4]));
normalData.push_back(normalData[normalData.size()-1]);
normalData.push_back(normalData[normalData.size()-2]);
normalData.push_back(getNormal(vertexData[vertexData.size()-3], vertexData[vertexData.size()-2], vertexData[vertexData.size()-1]));
normalData.push_back(normalData[normalData.size()-1]);
normalData.push_back(normalData[normalData.size()-2]);
}
}
glUseProgram(oglt9Shader->program);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertexData.size()*3*sizeof(float), vertexData.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glGenBuffers(1, &nbo);
glBindBuffer(GL_ARRAY_BUFFER, nbo);
glBufferData(GL_ARRAY_BUFFER, normalData.size()*3*sizeof(float), normalData.data(), GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
numVertices = vertexData.size()*3;
yValue += 0.01f;
}
void render()
{
//Clear screen and enable depth buffer
//Create and transmit matrices and light direction to shaders
generateTerrain(oglt9Shader);
glDrawArrays(GL_TRIANGLES, 0, numVertices);
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &nbo);
//Swap buffers to window
}
And my vertex shader...
#version 430 core
layout (location = 0) in vec3 vPosition;
layout (location = 1) in vec3 vNormal;
uniform mat4 mMatrix;
uniform mat4 vMatrix;
uniform mat4 pMatrix;
out vec3 fPosition;
out vec3 fNormal;
void main(void)
{
gl_Position = pMatrix * vMatrix * mMatrix * vec4(vPosition, 1.0);
fPosition = vPosition;
fNormal = normalize(transpose(inverse(mat3(mMatrix))) * vNormal);
}
#version 430 core
in vec3 fPosition;
in vec3 fNormal;
out vec4 outColor;
uniform vec3 lightDirection;
...and fragment shader.
void main(void)
{
vec3 rawColor = vec3(1.0);
vec3 ambientColor = vec3(1.0, 1.0, 1.0);
float diffuseIntensity = max(0.0, dot(fNormal, lightDirection));
vec3 diffuseColor = diffuseIntensity * vec3(0.9, 0.9, 0.9);
outColor = vec4(rawColor*ambientColor*diffuseColor, 1.0);
}
This is the final image:
So, what can I do to make the triangles smooth so you can't see these hard edges anymore?
You're using the same normal for all 3 vertices of each triangle. This will essentially result in flat shading, meaning that the color of each triangle is constant.
What you need is normals that better approximate the actual normals of the surface, instead of calculating the normal of each triangle separately. To get a smooth looking surface, you need to have one normal per vertex, and then use that normal when specifying the vertex for all the triangles that share the vertex.
The most efficient way of doing this is that you really store each vertex/normal of your grid in the VBO only once. You can then use an index buffer to reference the vertices when defining the triangles. This means that you have an additional buffer of type GL_ELEMENT_ARRAY_BUFFER containing indices, and then draw with glDrawElements(). You should be able to find reference information and tutorials on how to do that.
To actually obtain the normals, one common approach is that you average the triangle normals of all adjacent triangles to calculate the normal at a vertex.

can't draw any other objects before or after drawing particles

I am working on a game, and trying to implement the instancized CPU-Particle System programmed on http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/particles-instancing/
i managed to get it working in my code structure, but i am trying to draw other objects in the same window, which i can't, i have tested it, and it only allows me to draw one, either draw the particle system or draw the object i want.
The problem happens specifically at this code part :
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Use our shader
glUseProgram(particleprogramID->programHandle);
unit2 +=1;
glActiveTexture(GL_TEXTURE0 + unit2);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(TextureID, unit2);
glm::mat4 ViewMatrix = camera->getViewMatrix();
// Same as the billboards tutorial
glUniform3f(CameraRight_worldspace_ID, ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]);
glUniform3f(CameraUp_worldspace_ID , ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]);
glUniformMatrix4fv(ViewProjMatrixID, 1, GL_FALSE, &mvp[0][0]);
//glUniformMatrix4fv(modviewprojID, 1, GL_FALSE, &mvp[0][0]);
//1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, billboard_vertex_buffer);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
// 2nd attribute buffer : positions of particles' centers
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, particles_position_buffer);
glVertexAttribPointer(
1,
4,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
// 3rd attribute buffer : particles' colors
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, particles_color_buffer);
glVertexAttribPointer(
2,
4,
GL_UNSIGNED_BYTE,
GL_TRUE,
0,
(void*)0
);
glVertexAttribDivisor(0, 0);
glVertexAttribDivisor(1, 1);
glVertexAttribDivisor(2, 1);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, ParticlesCount);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
then i try to draw my star:
unit2 += 1;
starTexture->Bind(unit2);
shaderObject ->useShader();
glUniform1i(glGetUniformLocation(shaderObject->programHandle, "colorTexture"), unit2);
glUniformMatrix4fv(glGetUniformLocation(shaderObject->programHandle, "modelMatrix"), 1, GL_FALSE, glm::value_ptr(star1->getModelMatrix()));
glUniformMatrix4fv(glGetUniformLocation(shaderObject->programHandle, "projectionMatrix"), 1, GL_FALSE, glm::value_ptr(projectionViewMatrix));
star1->draw();
the vertex and fragment shader for the particle system:
#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 squareVertices;
layout(location = 1) in vec4 xyzs; // Position of the center of the particule and size of the square
layout(location = 2) in vec4 color; // Position of the center of the particule and size of the square
// Output data ; will be interpolated for each fragment.
out vec2 UV;
out vec4 particlecolor;
// Values that stay constant for the whole mesh.
uniform vec3 CameraRight_worldspace;
uniform vec3 CameraUp_worldspace;
uniform mat4 VP; // Model-View-Projection matrix, but without the Model (the position is in BillboardPos; the orientation depends on the camera)
void main()
{
float particleSize = xyzs.w; // because we encoded it this way.
vec3 particleCenter_wordspace = xyzs.xyz;
vec3 vertexPosition_worldspace =
particleCenter_wordspace
+ CameraRight_worldspace * squareVertices.x * particleSize
+ CameraUp_worldspace * squareVertices.y * particleSize;
// Output position of the vertex
gl_Position = VP * vec4(vertexPosition_worldspace, 1.0f);
// UV of the vertex. No special space for this one.
UV = squareVertices.xy + vec2(0.5, 0.5);
particlecolor = color;
}
frragment shader:
#version 330 core
// Interpolated values from the vertex shaders
in vec2 UV;
in vec4 particlecolor;
// Ouput data
out vec4 color;
uniform sampler2D myTexture;
void main(){
// Output color = color of the texture at the specified UV
color = texture2D( myTexture, UV ) * particlecolor;
}
and it only displays the particle system:
worth mentioning is:
the object i want to draw is a star modelled in blender and is displayed correctly when drawn alone or with other objects other than the particle system. and has its own class having buffers for psitions, UVs, indices and normals...
it seems like the star data are being swallowed by the buffer...
i appreciate every help...