How to pass and use 4x4 transformation matrix into vShader with glUniformMatrix4fv? - c++

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

Related

Draw two shapes on top of each other in geometry shader?

With this small program I want to achieve:
Publish a point
Transform this point with vertex shader
Create a square and a triangle with geometry shader
Fill both the triangle and the square with fragment shader
Unfortunately, I cannot manage to superpose both shapes. I see either only the triangle or only the square. I tried to play with z but it doesn't change anything.
void main(void) {
finalColour = vec4(1.0, 0.5, 0.5, 1.0);
square(1.0, 0.0);
finalColour = vec4(0.0, 1.0, 1.0, 0.0);
triangle(vec3(0.0, 0.0, 0.0), angle[0], 1.0);
EndPrimitive();
}
void main(void) {
// finalColour = vec4(1.0, 0.5, 0.5, 1.0);
// square(1.0, 0.0);
finalColour = vec4(0.0, 1.0, 1.0, 0.0);
triangle(vec3(0.0, 0.0, 0.0), angle[0], 1.0);
EndPrimitive();
}
Main
#include <SFML/Graphics.hpp>
#include <GL/glew.h>
#include <vector>
#define WIDTH 800
int main() {
sf::RenderWindow window(sf::VideoMode(WIDTH, WIDTH), "Test");
sf::Shader shader;
shader.loadFromFile("shader.vert", "shader.geom", "shader.frag");
sf::Transform matrix = sf::Transform::Identity;
matrix.scale(1.0 / WIDTH, 1.0 / WIDTH);
sf::Glsl::Mat4 projectionViewMatrix = matrix;
shader.setUniform("projectionViewMatrix", projectionViewMatrix);
std::vector<GLfloat> vertices;
vertices.push_back(0.0); vertices.push_back(0.0); vertices.push_back(0.0);
while (window.isOpen()) {
sf::Event currEvent;
while (window.pollEvent(currEvent)) {
switch (currEvent.type) {
case(sf::Event::Closed):
window.close(); break;
}
}
window.clear(sf::Color::Black);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glVertexPointer(3, GL_FLOAT, 0, vertices.data());
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, vertices.size() / 3);
glDisableClientState(GL_VERTEX_ARRAY);
sf::Shader::bind(&shader);
window.display();
}
}
Vertex
#version 150
in vec3 position;
out float angle;
uniform mat4 projectionViewMatrix;
void main(void){
gl_Position = projectionViewMatrix * vec4(position.xy, 0.0 ,1.0);
angle = position.z;
}
Geometry
#version 150
layout (points) in;
layout (triangle_strip, max_vertices = 6) out;
in float angle[];
out vec4 finalColour;
uniform mat4 projectionViewMatrix;
void createVertex(vec3 offset) {
vec4 actualOffset = vec4(offset, 1.0);
vec4 worldPosition = gl_in[0].gl_Position + actualOffset;
gl_Position = worldPosition;
EmitVertex();
}
void createAngularVertex(vec3 offset, float angle, float radius) {
vec4 actualOffset = vec4(offset, 1.0);
vec4 worldPosition = gl_in[0].gl_Position + actualOffset;
gl_Position = worldPosition;
gl_Position.x += cos(angle) * radius;
gl_Position.y += sin(angle) * radius;
EmitVertex();
}
void square(float size, float z) {
createVertex(vec3(-size, -size, z));
createVertex(vec3(size, -size, z));
createVertex(vec3(-size, size, z));
createVertex(vec3(size, size, z));
createVertex(vec3(size, -size, z));
createVertex(vec3(-size, size, z));
EndPrimitive();
}
void triangle(vec3 offset, float angle, float radius) {
float pi = 3.1415;
float angleOffset = 0.5;
createAngularVertex(offset, angle, radius);
createAngularVertex(offset, angle + pi + angleOffset, radius);
createAngularVertex(offset, angle + pi - angleOffset, radius);
EndPrimitive();
}
void main(void) {
finalColour = vec4(1.0, 0.5, 0.5, 1.0);
square(1.0, 0.0);
finalColour = vec4(0.0, 1.0, 1.0, 0.0);
triangle(vec3(0.0, 0.0, 0.0), angle[0], 0.1);
EndPrimitive();
}
Fragment
#version 150
in vec4 finalColour;
out vec4 out_Colour;
void main(void){
out_Colour = vec4(finalColour.rgb, 1.0);
}
The geometry shader creates 2 primitives, one with 6 vertices and one with 3 vertices, requiring a total of 9 vertices:
layout (triangle_strip, max_vertices = 6) out;
layout (triangle_strip, max_vertices = 9) out;

Sending transformation to vertex shader fails

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.

Translating Matriz in GLSL won't work with variables

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.

Rotating verticies created by a geometry shader

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).

Opengl Shader Basic Computation

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);