Why glm::vec3 is not ordered like a floating array [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm learning openGL from this website https://learnopengl.com
To draw a simple triangle, the first example provided by this website is using a float array:
float triangle[] = {
-0.5f, -0.5f, 0.0f, // left
0.5f, -0.5f, 0.0f, // right
0.0f, 0.5f, 0.0f // top
};
Of course it work well. But beside this example I have tried to use a basic structur carrying glm::vec3 as follow :
struct Position {
glm::vec3 pos;
};
Then to store the same data as the float array I just did a simple array of Position as follow :
Position leTriangle[3];
leTriangle[0].pos = glm::vec3(-0.5f, -0.5f, 0.0f);
leTriangle[1].pos = glm::vec3(0.5f, -0.5f, 0.0f);
leTriangle[2].pos = glm::vec3(0.0f, 0.5f, 0.0f);
(Of course all this was just to test if it could work)
Then after having sent my array of Position to the GPU using glBufferData and glVertexAttribPointer the triangle wasn't appearing anymore. So, juste to see if the array I sent where similar to the exemple floating array, I did this :
float* test = (float*)&leTriangle;
for(int e = 0; e < ((12/4) * 3); e++,test++){
std::cout << *test << std::endl;
}
And instead of printing the same floating array, it print this :
0.0f,-0.5f,-0.5f,// left
0.0f,-0.5f,0.5f, // right
0.0f,0.5f,0.0f // top
X and Z value has been inverted. So I guessed the order of the GLM data is not what I thought.
Can someone explain me why data in GLM are ordered this way? Should I respect this order or maybe I should try to reverse it? Maybe it's not important, is it something I should have in mind when placing 3D object?

Data in the glm::vec3 struct is ordered correctly. You could easily verify this by checking up memory, pointed by your test variable:
You are getting strange results, because something in your test is wrong, you are clearly reading glm::vec3 fields backward. Code in your question does not exhibit this behavior. Perhaps you should check how you assign your data.

Related

C++ GDI: I am seeking explanation for color matrix such that I can create any color manipulation mask

I am trying to implement an application that can manipulate the background screen color attributes through a transparent window. Basically trying to recreate Color Oracle. I am progressing here through C++:GDI+ resources. This GDI has a Color Matrix concept. I am able to create filters for greyscale(as shown in the example in the last hyperlink), brightness tweaking, saturation tweaking; However, as advanced use cases such as color blindness filter, blue light filter, contrast tweaks - I am using the hit-n-trial approach, It will be much efficient if anyone can take me in the right direction to learn fundamentals of this color matrix.
Example Matrix is shown below which boosts saturation by a small factor while restricting brightness component.
MAGCOLOREFFECT magEffectSaturationBoost =
{ { // MagEffectBright
{ 1.02f, 0.0f, 0.0f, 0.0f, 1.0f },
{ 0.0f, 1.02f, 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 1.02f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f, 0.0f },
{ -0.1f, -0.1f, -0.1f, 0.0f, 0.0f }
}
}
// Using the Matrix
ret = MagSetColorEffect(hwndMag, &magEffectSaturationBoost);
It will be much efficient if anyone can take me in the right direction to learn fundamentals of this color matrix.
Each color vector is multipled by 5x5 matrix, to make it possible color vector is 5 elements long - the fifth element is a dummy one, this allows to perform additional operations on colors (rotation, scaling, ...).
In your example each color component is multiplied by 1.02f making color brighter, after multiplication - from each color component 0.1 value is subtracted.
You can find full explanation here:
https://learn.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-using-a-color-matrix-to-transform-a-single-color-use
and:
https://learn.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-coordinate-systems-and-transformations-about
Few more links:
https://docs.rainmeter.net/tips/colormatrix-guide/
https://www.integral-domain.org/lwilliams/math150/labs/matrixcolorfilter.php

Trying to Make Endless Runner C++ with OpenGL

I have an array of cube objects initialised like so (index 0 not used here as that's for the player):
game_object[1] = new GameObject();
game_object[1]->setPosition(vec3(7.0f, 0.0f, 0.0f));
game_object[2] = new GameObject();
game_object[2]->setPosition(vec3(14.0f, 0.0f, 0.0f));
game_object[3] = new GameObject();
game_object[3]->setPosition(vec3(21.0f, 0.0f, 0.0f));
game_object[4] = new GameObject();
game_object[4]->setPosition(vec3(36.0f, 0.0f, 0.0f));
game_object[5] = new GameObject();
game_object[5]->setPosition(vec3(42.0f, 0.0f, 0.0f));
I have a render function in which they are drawn:
glDrawElements(GL_TRIANGLES, 3 * INDICES, GL_UNSIGNED_INT, NULL);
In my update they move to the left as expected. To do this I am just adding another vector to their positions:
for (int i = 1; i < MAX_CUBES; i++)
{
game_object[i]->setPosition(game_object[i]->getPosition() + vec3(-0.03, 0.0, 0.00));
}
However, I want the cubes to repeat this until the user exits the game. I made a reset function to send them back to their starting positions:
void Game::reset()
{
game_object[0]->setPosition(vec3(0.0f, 0.0f, 0.0f));
game_object[1]->setPosition(vec3(7.0f, 0.0f, 0.0f));
game_object[2]->setPosition(vec3(14.0f, 0.0f, 0.0f));
game_object[3]->setPosition(vec3(21.0f, 0.0f, 0.0f));
game_object[4]->setPosition(vec3(36.0f, 0.0f, 0.0f));
game_object[5]->setPosition(vec3(42.0f, 0.0f, 0.0f));
}
This function gets called in the update when the final cube's position is off screen to the left:
if (game_object[5]->getPosition().x <= 0.0)
{
reset();
}
However, this isn't working. Nothing resets after the last cube goes to the left.
Not sure how you are using game_object here but looks very error prone. If you have MAX_CUBES = 5 (as you do have 5 cubes), then that for-loop will miss the last one. Adding further objects (e.g. for gaps, vertical rules, hazards, etc.) will make it even more so.
for (int i = 1; i < MAX_CUBES; i++)
{
game_object[i]->setPosition(game_object[i]->getPosition() + vec3(-0.03, 0.0, 0.00));
}
If MAX_CUBES = 5, then it will move index 1, 2, 3, 4, and not 5, which is the one you check in the condition. 5 will just stay at 42 permanently (is that off-screen?).
Stepping through the code in a debugger will make a problem like this pretty clear regardless, and is an essential tool for programming. Maybe the code just never reaches the if (game_object[5]->getPosition().x <= 0.0) check in the first place? Is there any return in that update function, or is that condition inside another one of some sorts?
Because in your comment you noted that game_object[5]->getPosition().x returns a correct value, the most likely problem is with your reset() function and the setPosition function you are using.
1. Check if set position is working in the first place
Perhaps there is an error with setPosition().
After you set the position using setPosition() and then log the object's coordinates using getPosition() does it return the position you expect?
If not, something is wrong with setPosition.
If so, then...
2. You probably changed the position but failed to render it!
This is a very common problem lol
There is a very high chance you changed the position of the object BUT didn't update what's shown on the screen!
3. Side note for scalability
There is a much more efficient and scalable way of doing a reset if you have eventually have more than 5 objects, by placing their reset values in an array and looping through them:
#define MAX_CUBES 6
double resetPositions_x[MAX_CUBES] = {0.0, 7.0, 14.0, 21.0, 36.0, 42.0};
void Game::reset()
{
for(int i=0;i<MAX_CUBES;i++){
game_object[i]->setPosition(vec3(resetPositions_x[i], 0.0f, 0.0f));
}
}
(Also, it seems every x reset position is a multiple of 7 except 36.0 -> is that a mistake?)

How to make a spring constraint with Bullet Physics?

I want to test the spring contraint of Bullet Physics. So I created a static box hovering above the ground and a second dynamic box hanging down from it. But activating the spring behavior does nothing! The box is indeed hanging freely. I know it because it rotates freely. But it does not oscillate or anything.
btCollisionShape *boxShape = createBoxShape(0.2f, 0.2f, 0.2f);
btRigidBody *box1 = createStatic(boxShape);
btRigidBody *box2 = createDynamic(1.0f /*mass*/, boxShape);
box1->setWorldTransform(btTransform(btQuaternion::getIdentity(), { 0.0f, 2.0f, 1.0f }));
box2->setWorldTransform(btTransform(btQuaternion::getIdentity(), { 0.0f, 1.0f, 1.0f }));
btGeneric6DofSpring2Constraint *spring = new btGeneric6DofSpring2Constraint(
*box1, *box2,
btTransform(btQuaternion::getIdentity(), { 0.0f, -1.0f, 0.0f }),
btTransform(btQuaternion::getIdentity(), { 0.0f, 0.0f, 0.0f })
);
// I thought maybe the linear movement is locked, but even using these lines do not help.
// spring->setLinearUpperLimit(btVector3(0.0f, 0.1, 0.0f));
// spring->setLinearLowerLimit(btVector3(0.0f, -0.1, 0.0f));
// Enabling the spring behavior for they y-coordinate (index = 1)
spring->enableSpring(1, true);
spring->setStiffness(1, 0.01f);
spring->setDamping (1, 0.00f);
spring->setEquilibriumPoint();
What is wrong? I played a lot with the the Stiffness and Damping parameters. But it changed nothing. Setting linear lower and upper limits makes the box movable in the y-direction, but it still not oscillates. And yes, gravity is activated.
Ok, I found a solution by checking out Bullet's provided example projects (could have come up with the idea earlier). Three things I have learned:
The spring constraint will not violate the linear limits. The problem with my former approach was that the linear movement was either locked, or limited to a too small range for the assigned spring stiffness. Now there are no more limits (by setting the lower limit above the upper one).
The stiffness was far too small, so the joined objects were acting as if they were freely movable inside the linear limits. You can check out the values in my code below, I got them from the example project.
There is a small difference in the behavior between btGeneric6DofSpringConstraint and btGeneric6DofSpring2Constraint. The former one seems to violet the non-spring-axes less (x- and z-axes in my case). The latter one seems to apply a stronger damping. But these are just first observations.
btGeneric6DofSpringConstraint *spring = new btGeneric6DofSpringConstraint(
*box1, *box2,
btTransform(btQuaternion::getIdentity(), { 0.0f, -1.0f, 0.0f }),
btTransform(btQuaternion::getIdentity(), { 0.0f, 0.0f, 0.0f }),
true
);
// Removing any restrictions on the y-coordinate of the hanging box
// by setting the lower limit above the upper one.
spring->setLinearLowerLimit(btVector3(0.0f, 1.0f, 0.0f));
spring->setLinearUpperLimit(btVector3(0.0f, 0.0f, 0.0f));
// Enabling the spring behavior for they y-coordinate (index = 1)
spring->enableSpring(1, true);
spring->setStiffness(1, 35.0f);
spring->setDamping (1, 0.5f);
spring->setEquilibriumPoint();

OpenGL glBufferData with data from a pointer

I'm a beginner in OpenGL and I am trying to draw a colored square I followed the tutorial at OpenGL Book and I am using the example to draw here. Since this draws a triangle I modified the code to draw 4 vertices. I made a Rectangle class that can output it's data in array format. This is the data that I am trying to pass into the glBufferData function.
Unfortunately when I use my class's data it does not draw anything on the screen. I'm even checking in gDebugger, I'm looking at my VBO and the data is not correct.
To test, I extracted the vertices out of my class and used them in a local array instead of the pointer returned from my class.
My data is now :
Vertex Vertices[] =
{
{ { -0.5f, 0.5f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
{ { 0.5f, 0.5f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
{ { -0.5f, -0.5f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } },
{ { 0.5f, -0.5f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }
};
instead of
Vertex* Vertices = rec->GetVertexData();
(I checked by hand both arrays, they have the exact same values, the problem is not in my Rectangle's code) and now the call glBufferData(GL_ARRAY_BUFFER, BufferSize, Vertices, GL_STATIC_DRAW); works and I see the correct rectangle on screen. With the data in gDebugger being
After some research I realized that sizeof does not report the correct size given a pointer so I fixed that. I hardcoded (for now) BufferSize = 128; in order to test quicker. Point is, it works with the Vertex array and still not with the Vertex pointer from my class.
I've googled examples of the glBufferData and literally none of them shows you how to use the data from a pointer, you'd think that would be a good example.
So how can I pass an array of Vertex to my glBufferData that's being returned as a pointer from another class ? I'm using OpenGL version 4 with GLEW and GLUT.
Update :
So the error was on my part, I'll post my debugging here in hopes it can help other people. I added a Watch of name Vertice, 8. Which showed me that my array had bogus values. Doing a step by step debugging showed me that when glGenBuffers was called it was overwriting my values. I went back and checked my code and I realized that my mistake was calling Vertex vec[4]; instead of Vertex *vec = new Vertex[4]; and the stack's values was overwritten by another function.
It is often mistaken that arrays are pointers, when in reality they are not. Array expressions decay into a pointer in many circumstances (sizeof being one of the exceptions to this rule) but there are significant differences between array themselves and pointers. For further information, read this excellent post.
As for the problem in hand, once the array decays into a pointer, it's shape (the first dimension) is lost, which is the reason sizeof returns the size of a pointer and not that of the entire array.
float arr[3] = { 1.0f, 2.0f, 3.0f }; // sizeof(arr) = 3 * sizeof(float)
float *ptr = arr; // sizeof(ptr) = sizeof(float*)
how can I pass an array of Vertex to my glBufferData that's being returned as a pointer from another class ?
You've three options to do this. Make the class return the pointer to the array (as you do now) and add another function to expose the count of the elements in it i.e. its length, with which you may calculate the size in bytes. However, this is not a very elegant solution, since in C++ one can have references to array, which brings us to the next solution (live example):
float (&MyClass::GetData()) [3] const
{
return arr;
}
The sizeof operator on this reference would rightly return the size of the whole array. You might use std::array instead to avoid the arcane expression like so std::array<float, 3>& MyClass::GetData() const;.
Another wiser option is to do away with arrays altogether and use std::vector, to which you can return a reference:
std::vector<float> const& MyClass::GetData() const
{
return vec;
}
At the other end
auto const &vec = obj->GetData();
float *data = vec.data();
size_t data_len = vec.size() * sizeof(float);
The additional advantage in using std::vector is that the length can vary at runtime; also lesser bugs due to the hairy nature of arrays.

sketch cylinder [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
sketching object near to each other
I want to sketch below graph in the screen ;
|----| sphere
|----|
/ /
/ /
/ / cylinder
/ /
/ / angle = 45
| |
| |
| | cylinder (i)
| |
| |
| |
----------- cylinder
-----------
To sketch the cylinder marked with (i), I have use below code, can you help me what is my mistake because I could not manage to draw (i) ?
glTranslatef(0.0f, 10.0f, 400.0f ) ;
glColor3f ( 0.0f, 1.0f, 1.0f ) ;
glRotatef (90.0f, 1.0f, 1.0f, 0.0f );
gluCylinder(quadric,0.0f,200.0f,100.0f,32,32);
glTranslatef(0.0f, 10.0f, -400.0f ) ;
I don't want to be the bad guy here, so let me explain, why that bit of code is worth nothing without the context and why you need to understand.
Let's go through this snippet line by line. It all starts with
glTranslatef(0.0f, 10.0f, 400.0f ) ;
The first question is: What matrix is this operating on. Probably modelview, but we don't know. And what is the matrix before that call to glTranslatef? OpenGL matrix operations somewhat like x86 assembly, in that they replace the matrix on the stack with the result of the operation.
glColor3f ( 0.0f, 1.0f, 1.0f ) ;
This set the color state. Of course. One normally groups this call with the geometry to be drawn, and not put it somewhere in the middle of the code though.
glRotatef (90.0f, 1.0f, 1.0f, 0.0f );
Rotating about the axis (1, 1, 0), i.e. it's like sticking a axle through the object, passing through the local origin and going toward the point (1, 1, 0), and then rotating this by 90° about this axis.
gluCylinder(quadric,0.0f,200.0f,100.0f,32,32);
Now a cylinder is drawn, which will be first rotated, then translated, and then… only you know, because you omitted the part, where the modelview matrix is reset when beginning rendering the frame.
glTranslatef(0.0f, 10.0f, -400.0f ) ;
And the final glTranslatef does not have any effect on drawing the cylinder whatsoever.
You see the problem now? You're asking a very specific question, that's clearly homework, put some piece of random code in there, just ask "how to draw it" without any idea, what you're actually doing.
There's no way we can help you, if you don't first grip the basics first. We'll gladly help to get you there. Start with drawing something simple, like a triangle centered in the window.