I am trying to generate a cube from 6 points (each point representing a side, then 2 extra values to say if its rotated to face on the x, or y axis, z axis doesn't need one because its like that by default). Problem comes in when I try to multiply the gl_Position value by a mat4 rotation matrix to make the sides of the cube rotated properly. It doesn't even glitch out, it just doesn't display the faces at all (it does when I dont have the matrices multiplying the values).
Heres my geometry shader:
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
in vec3 gFacePos[];
out vec2 texCoord;
mat4 xtrans = mat4( //rotate on the x axis
1.0, 0.0, 0.0, 0.0,
0.0, 0.0, -1.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 0.0, 1.0
);
mat4 ytrans = mat4( //rotate on y
0.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0,
-1.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 1.0
);
mat4 rtrans = (gFacePos[0].x * xtrans) + (gFacePos[0].y * ytrans); //figure out what the current point wants to rotate on
void main() { //this whole thing makes a square at the requested point
gl_Position = gl_in[0].gl_Position + vec4(-0.5, 0.5, 0.0, 0.0);
gl_Position *= rtrans; //these break it
texCoord = vec2(0.0, 0.0);
EmitVertex();
gl_Position = gl_in[0].gl_Position + vec4(0.5, 0.5, 0.0, 0.0);
gl_Position *= rtrans;
texCoord = vec2(1.0, 0.0);
EmitVertex();
gl_Position = gl_in[0].gl_Position + vec4(-0.5, -0.5, 0.0, 0.0);
gl_Position *= rtrans;
texCoord = vec2(0.0, 1.0);
EmitVertex();
gl_Position = gl_in[0].gl_Position + vec4(0.5, -0.5, 0.0, 0.0);
gl_Position *= rtrans;
texCoord = vec2(1.0, 1.0);
EmitVertex();
EndPrimitive();
}
Fragment and vertex are pretty standard (vertex has some basic camera stuff on it).
Related
I'm trying to generate a simple shape with a Geometry Shader, but the shape is rendering twice and I don't know why.
First we have a really simple Vertex Shader
#version 150
in vec4 position;
void main() {
gl_Position = position;
}
Then there's a Geometry Shader thats generating a simple triangle.
#version 150
layout (triangles) in;
layout (triangle_strip, max_vertices = 5) out;
out FragData {
vec4 color;
} FragOut;
void main(){
//RED TOP LEFT
FragOut.color = vec4(1.0, 0.0, 0.0, 1.0);
gl_Position = gl_in[0].gl_Position + vec4( -1.0, 0.0, 0.0, 0.0);
EmitVertex();
//BLUE BOTTOM LEFT
FragOut.color = vec4(0., 0., 1., 1.);
gl_Position = gl_in[0].gl_Position + vec4( -1.0, -1.0, 0.0, 0.0);
EmitVertex();
//GREEN BOTTOM RIGHT
FragOut.color = vec4(0.0, 1.0, 0.0, 1.0);
gl_Position = gl_in[0].gl_Position + vec4( 1.0, -1.0, 0.0, 0.0);
EmitVertex();
EndPrimitive();
}
And finally a simple Fragment Shader
#version 150
in FragData {
vec4 color;
} FragIn;
out vec4 fragColor;
void main() {
fragColor = FragIn.color;
}
The result should be a triangle, but TWO triangles are being rendered:
Here's the result
The Geometry Shader is executed once for each primitive. A rect() consists of 2 triangles, so the geometry shader is executed twice and generates 2 triangle_strip primitives.
Draw a single POINTS primitive instead of the rectangle:
beginShape(POINTS);
vertex(x, y);
endShape();
Note that you need to change the Primitive input specification:
layout (triangles) in;
layout (points) in;
I'm doing my first steps with OpenGL and currently fail to send some transformations to my vertex shader. When I use following shader program, everything works fine and I can see my object (a simple triangle):
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos, 1.0);
}
In next step I changed the shader program to accept transformations from outside:
layout (location = 0) in vec3 aPos;
uniform mat4 inputTransform;
void main()
{
gl_Position = inputTransform * vec4(aPos, 1.0);
}
...and my main loop to send transformation data to the shader:
unsigned int transformLoc = glGetUniformLocation(shaderProgram,"inputTransform");
glUseProgram(shaderProgram);
GLfloat trans[4] = {1.0, 0.0, 0.0, 1.0};
glUniformMatrix4fv(transformLoc, 1, GL_FALSE,trans);
Now my triangle disapperas as some very invalid transformation would have been applied. Value in "shaderProgram" is correct, it works properly with a prior call to the fragment shader. I also do not get any compilation errors for the shader programs.
So any idea what could be wrong here?
The uniform mat4 inputTransform is a 4*4 matrix and not a vector with 4 components.
See Data Type (GLSL) - Matrices
You have to initialize it with an array of 16 floats, e.g. by an Identity matrix:
GLfloat trans[16] = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, trans);
The matrix contains the translation, orientation (and scale). In GLSL a mat4 can be initialized:
mat4 m44 = mat4(
vec4( Xx, Xy, Xz, 0.0),
vec4( Yx, Xy, Yz, 0.0),
vec4( Zx Zy Zz, 0.0),
vec4( Tx, Ty, Tz, 1.0) );
This means, if you want to init the matrix with an translation vector, then you can do it manually initializing the translation component of the matrix:
Glfloat Tx = 1.0;
Glfloat Ty = 0.0;
Glfloat Tz = 0.0;
GLfloat trans[16] = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
Tx, Ty, Tz, 1.0
};
In C++ I recommend to use the GLM library for matrix and vector operations, which are related to OpenGL and GLSL.
So... i made this mat4 matriz which would translate a triangle according to the coordinates. I realized that with the following matriz, the triangle would translate to the right of the screen:
Camera[0] = vec4(1.0, 0.0, 0.0, 0.0);
Camera[1] = vec4(0.0, 1.0, 0.0, 0.0);
Camera[2] = vec4(0.0, 0.0, 1.0, 0.0);
Camera[3] = vec4(0.5, 0.0, 0.0, 1.0);
Now, i read that a translating matriz in GLSL would look like this:
Camera[0] = vec4(1.0, 0.0, 0.0, 0.0);
Camera[1] = vec4(0.0, 1.0, 0.0, 0.0);
Camera[2] = vec4(0.0, 0.0, 1.0, 0.0);
Camera[3] = vec4(X, Y, Z, 1.0);
So therefore, i created a variable, which would contain these 3 values.
layout(location = 2) in vec3 CAM;
And i would do the following to establish the values in the corresponding places:
Camera[0] = vec4(1.0, 0.0, 0.0, 0.0);
Camera[1] = vec4(0.0, 1.0, 0.0, 0.0);
Camera[2] = vec4(0.0, 0.0, 1.0, 0.0);
Camera[3] = vec4(CAM.x, CAM.y, CAM.z, 1.0);
I thought that if CAM.x = 0.5 And CAM.y = 0.0, CAM.z = 0.0, i would have the same result as i had when i established manually X to be 0.5, and both Y and Z to be 0.0, since those are precisely the values of CAM. But rather, i got completely different results.
Camera[0] = vec4(1.0, 0.0, 0.0, 0.0);
Camera[1] = vec4(0.0, 1.0, 0.0, 0.0);
Camera[2] = vec4(0.0, 0.0, 1.0, 0.0);
Camera[3] = vec4(0.5, 0.0, 0.0, 1.0);
Gives me the following result:
And
Camera[0] = vec4(1.0, 0.0, 0.0, 0.0);
Camera[1] = vec4(0.0, 1.0, 0.0, 0.0);
Camera[2] = vec4(0.0, 0.0, 1.0, 0.0);
Camera[3] = vec4(CAM.x, CAM.y, CAM.z, 1.0);
gave me the following result:
Even though CAM.x = 0.5; CAM.y = 0.0; CAM.z = 0.0. (I checked it myself inside the vertex Shader by changing the red color of one of the vertices if the values of CAM were correct. By adding the following code: if(CAM.x == 0.5) ColorValue.x = 0.0; I got the following result: ). How can this be??
This is the whole Vertex Code by the way:
#version 330 core
layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec3 COR;
layout(location = 2) in vec3 CAM;
out vec3 ColorValue;
void main(){
mat4 Camera;
Camera[0] = vec4(1.0, 0.0, 0.0, 0.0);
Camera[1] = vec4(0.0, 1.0, 0.0, 0.0);
Camera[2] = vec4(0.0, 0.0, 1.0, 0.0);
Camera[3] = vec4(CAM.x, 0.0, 0.0, 1.0);
vec4 point = vec4(VertexPosition.x, VertexPosition.y, VertexPosition.z, 1.0);
vec4 Transformed_Point = Camera * point;
gl_Position = Transformed_Point;
ColorValue.xyz = COR.xyz;
}
You are handling the camera position as a vertex attribute. That's why the first vertex is correctly shifted but the other two are at their original positions (because their camera attribute is zero). Use a uniform instead.
OS: Win7 VS 2012
Graphics Card: Inter HD 4000
I have no problem generating an image without any computation.
However, when I added p*vPosition for a prospective projection,
My window opened and closed immediately after I executed the program.
Could anyone point out what I have done wrong?
My vshsader.glsl code looks like this:
#version 150
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
void main()
{
float d = -10.0;
mat4 p = mat4( 1.0, 0.0, 0.0, 0.0
0.0, 0.0, 1.0, 0.0
0.0, 0.0, 1.0, 0.0
0.0, 0.0, 1/d, 0.0);
gl_Position = p*vPosition;
color = vColor;
}
You are missing commas at the end of each line of parameters to the mat4 constructor.
It should be:
mat4 p = mat4( 1.0, 0.0, 0.0, 0.0, // <- end with comma
0.0, 0.0, 1.0, 0.0, // <- end with comma
0.0, 0.0, 1.0, 0.0, // <- end with comma
0.0, 0.0, 1/d, 0.0);
Im sure there is a better way for me to calculate my transformation matrix from a quaternion but this is what i have for now. I need to pass the 16 values into the shader but am having an issue. I keep getting type incompatibility errors. Also once i get it in there do i have to do anything to it to multiply it to what i already have?
Here is my display and shader
void display()
{ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
if (trackballMove)
{
glRotatef(angle, axis[0], axis[1], axis[2]);
}
//colorcube();
glUniform3fv( theta, 1, Theta );
float a = angle;
float b = axis[0];
float c = axis[1];
float d = axis[2];
float xform[16] = {(a*a+b*b-c*c-d*d),(2*b*c-2*a*d),(2*b*d+2*a*c),0.0,
(2*b*c+2*a*d),(a*a-b*b+c*c-d*d),(2*c*d-2*a*b),0.0,
(2*b*d-2*a*c),(2*c*d+2*a*b),(a*a-b*b-c*c+d*d),0.0,
0.0,0.0,0.0,1.0};
GLuint Transform = glGetUniformLocation( program, "vTransform");
glUniformMatrix4fv(Transform, xform);
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
glutSwapBuffers();
}
here is the shader
#version 150
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
uniform vec3 theta;
uniform vec4 vTransform;
void main()
{
// Compute the sines and cosines of theta for each of
// the three axes in one computation.
vec3 angles = radians( theta );
vec3 c = cos( angles );
vec3 s = sin( angles );
// Remember: these matrices are column-major
mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,
0.0, c.x, -s.x, 0.0,
0.0, s.x, c.x, 0.0,
0.0, 0.0, 0.0, 1.0 );
mat4 ry = mat4( c.y, 0.0, s.y, 0.0,
0.0, 1.0, 0.0, 0.0,
-s.y, 0.0, c.y, 0.0,
0.0, 0.0, 0.0, 1.0 );
mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
s.z, c.z, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 );
color = vColor;
gl_Position = vTransform *(rx * ry * rz * vPosition);
}
Your glUniformMatrix4fv does not have sufficient number of arguments. The function signature is
glUniformMatrix4fv(GLint location, GLsizei count,
GLboolean transpose, const GLfloat *value);
See the complete API docs here:
http://www.opengl.org/sdk/docs/man4/xhtml/glUniform.xml