Thank you for this very straightforward example of how to rotate a simple 3D object and display the result in 2D. I was really just looking for the matrix transformation, but seeing how this code developed as you wrote it was a huge help. I'll be using this to rotate a slightly more complex shape (really just a cube with angled sides) with C and Cairo. Let me know if anyone needs a C version of this (when I get it done!). Thanks again, sincerely appreciate you taking the time to publish this!
I'm a bit late, but i've seen you respond to recent comments, so I hope you can read this. I simply wanted to thank you. I learnt assembly last year and I just recently started learning c++ on my own, but I got tired of needlessly complicated programs in SDL2 when looking for tutorials. The whole "Making a game in SDL2" is not my style of project. So thanks, already knowing all the math used here, you using SDL2 is such a "barebones" project saved me a ton of reading.
I have done this tutorial with C based Language very thanks it's the first time I done a 3D software rendering app. I can Applause your work. Note: I encouter trouble about the z-index variable 'c.z'..I must manually put a fixed value for now under 1 or -1 so 0 is well ^^ I have finally put this: if(c.z>1 || c.z
Thank you so much! I'm preparing for a programming test and these videos help me a lot! Your explanations are great and the projects are super interesting :)
Thank you, I'm happy to see that you were able to adapt the code to your rendering interface, I was worried I didn't spend enough time emphasizing the disconnect between data models and rendering APIs in computer graphics.
Great video and a nice example. However, the rotational matrix in the rotate function is applied incorrectly and leads to an issue where the cube shrinks into the window. This is because the result of one multiplication is used immediately in the next within the same rotation matrix multiplication. For example, when rad = x the y value of the point is updated and then used when updating the z value of the point which is incorrect. To prevent the shrinkage save the new rotated values separately and then update the point with the values.
@@Dee-c1l Just create a new vec3 variable and set it equal to the point in the parameter list. use the copy to do the math and set it equal to the new point after each section heres the code. float rad = 0; vec3 OGpoint = point; //add this rad = x; point.y = cos(rad) * OGpoint.y - sin(rad) * OGpoint.z; point.z = sin(rad) * OGpoint.y + cos(rad) * OGpoint.z; OGpoint = point; // add this rad = y; point.x = cos(rad) * OGpoint.x + sin(rad) * OGpoint.z; point.z = -sin(rad) * OGpoint.x + cos(rad) * OGpoint.z; OGpoint = point; //add this rad = z; point.x = cos(rad) * OGpoint.x - sin(rad) * OGpoint.y; point.y = sin(rad) * OGpoint.x + cos(rad) * OGpoint.y;
Hey just a heads up, not sure if SDL updated the syntax but emplace_back is formatted points.emplace_back(SDL_FPoint{ x, y }); instead of points.emplace_back( x, y ); let me know if I missed something here
Hey, thanks but I still have an error which I am not sure how to fix, could you lend me a brain ? SDL_rect.h:60:16: note: no known conversion for argument 1 from float' to 'SDL_FPoint&&' This is what comes out, not sure what to do with it even though I work with Fpoint correctly (supposedly) Any tips ? I know it's hard to say when you can't see my code, but any help is appreciated. Thank you.
Can you please give more detailed explanation of how do the rotate function work please, give me a link to a page where it does explain it or something. I would appreciate it.
@@TheBuilder oh, I didn't watch the video carefully, classes are only used for screen, which is inbuilt in "graphics.h". Yeah, it will be a straightforward mapping :)
Not really sure why but my cube starts out right but as it spins it gradually becomes flatter and longer until it eventually becomes a line that is spinning and no longer a cube.
I wrote this in Flash, and it worked flawlessly! :) Although it is interesting that i also had the cube shrinking problem in AS, despite it being a scripting language. (100th like by the way)
Hey how did you fix the shrinking problem? I'm new to 3D graphics programming and I don't exactly know how to frame questions yet. Glad to hear that I'm not the first or only one to have that issue. I thought I could simply work the Z component in the Rotate() function but it didn't work with either zero nor a positive or negative number. Thanks in advance!! This is a great video for those of us trying to get started with making our own 3D engines in SDL2 as a starting point.
@@BD-cv3wu If you are still curious about what was causing the shrinking problem, it is an accumulation of floating point error. It can be solved by keeping a copy of the points in their original positions and working off of them instead of rotating the same points over and over.
@@raybourke552 Thanks, I'll try that next time I have a chance. It sucks how evolved computers are, but how they can be undermined by floating point (in)precision! Or null/dangling pointers...or accessing elements of a list/table/vector that are nonexistent...or have null/dangling pointers. :)
I am a newbee and there are at least 30 SDL2's on github, please hint which may be the best for these exercises? Also is SDL.h within the SDL2's? if not can you provide some hint which is best to use? Thanks much
Hello. Many thanks for the video. I tried to follow you on every step but when I compile it gives me """ error: new initializer expression list treated as compound expression""" AND """error: no matching function for call to 'SDL_FPoint::SDL_FPoint(float&)""" Can you please help me?😟
can anyone explain how the function works in general rotate? I've been sitting for several days now and I can't figure out which formula the lines "point.y = cos(rad) * point.y - sin(rad) * point.z;" come from... Help pls.
@@TheBuilder Dont want to be to bothersome, but one more thing. after 31:00 and starting my program, the cube starts to seperate into 2 spinning squares instead of a whole cube. What causes this? thanks.
@@willyknickers9295 floating point numbers lose precision if you operate on them too much the precision loss becomes visible. try adding a delay to see if that helps, and no problem. I get these types of questions fairly regularly, I don't mind.
@@TheBuilder after a while it starts to look like a parallelogram . It seems like the faster the rotation is, the worse it gets. And there is no fun in a barely rotating cube. I honestly have no clue what to do haha. I also get different results from differents speeds 🤔
Sir, when I entered ./pixel, nothing shows up and I entered control + z which shows [3]+ Stopped ./pixel . What might cause the problem? Good video by the way
My cube is getting smaller and smaller while rotating center stays the same. Eventually it shrinks into just a couple of points, is it something wrong with my line function or maybe something else? Thanks😃
You can try enabling -Wconversion in gcc to see if you're losing precision to conversions from float to int. Second floating point numbers lose precision whenever you do operations on them. Try adding a delay to slow the precision loss. Hope that helped
@@BD-cv3wu that's probably because you're using integers not floating point numbers to model your game. Another Idea would be to enable -Wconversion to check if you're converting to int anywhere in your code
If anyone is having an issue with the pixel function "Error C2661 'SDL_FPoint::SDL_FPoint': no overloaded function takes 2 arguments" Try doing this instead in the pixel function: points.emplace_back(SDL_FPoint{ x, y }); Also please if this is somehow bad practice, lemme know :)
Also I had another issue regarding the SDL2.dll not being found (on windows), I found a fix on stack overflow, from the SDL download "copy \SDL2\lib\x64\SDL2.dll to C:\Windows\System32 and \SDL2\lib\x86\SDL2.dll to C:\Windows\SysWOW64."
floats lose precision over time. it could also be that you're converting from floats to ints which would make things worse try enabling -Wconversion in gcc to see if you're doing that anywhere in your code
@@billcosta well I don't know the underlying reason why the equation works but you can read more about it here en.wikipedia.org/wiki/Rotation_matrix I just use the matrix to get the result I want.
could not use emplace_back in my code - i was getting new_allocator.h errors. The solution that worked for me was to redefine the SDL_FPoint and adding constructor into it. The code looks like this: (if u use it u ll need to change name from SDL_FPoint to FPoint in vector. i dont know how it worked - have found it on the stack overflow struct FPoint { float x; float y; FPoint(float a, float b) : x(a) , y(b) {} };
@@engthanoon3889 hi sorry that didnt work, But I think the problem lies with the pixel function... check if it is initialised properly and invoked at the right place
Thank you for this very straightforward example of how to rotate a simple 3D object and display the result in 2D. I was really just looking for the matrix transformation, but seeing how this code developed as you wrote it was a huge help. I'll be using this to rotate a slightly more complex shape (really just a cube with angled sides) with C and Cairo. Let me know if anyone needs a C version of this (when I get it done!). Thanks again, sincerely appreciate you taking the time to publish this!
Glad you enjoyed it and good luck with your project :)
Seeing the c version of it would be very cool
I'm a bit late, but i've seen you respond to recent comments, so I hope you can read this. I simply wanted to thank you. I learnt assembly last year and I just recently started learning c++ on my own, but I got tired of needlessly complicated programs in SDL2 when looking for tutorials. The whole "Making a game in SDL2" is not my style of project. So thanks, already knowing all the math used here, you using SDL2 is such a "barebones" project saved me a ton of reading.
glad you enjoyed it. If you're interested in primitive rendering, I'd recommend reading Computer Graphics from Scratch by Gabriel Gambetta
@@TheBuilder Thanks a lot! I'll take a stab at it. Cheers!
I have done this tutorial with C based Language very thanks it's the first time I done a 3D software rendering app. I can Applause your work.
Note: I encouter trouble about the z-index variable 'c.z'..I must manually put a fixed value for now under 1 or -1 so 0 is well ^^ I have finally put this:
if(c.z>1 || c.z
Awesome video. I'm new to SDL and this tutorial is just what I needed. Thanks
best SDL series
Thank you so much! I'm preparing for a programming test and these videos help me a lot! Your explanations are great and the projects are super interesting :)
You're very welcome!
I never knew you could do this, thanks bro!
thanks for the support
Helped me make a rotating cube using ascii in the terminal, thanks, subscribed!
Thank you, I'm happy to see that you were able to adapt the code to your rendering interface, I was worried I didn't spend enough time emphasizing the disconnect between data models and rendering APIs in computer graphics.
Great video and a nice example. However, the rotational matrix in the rotate function is applied incorrectly and leads to an issue where the cube shrinks into the window. This is because the result of one multiplication is used immediately in the next within the same rotation matrix multiplication. For example, when rad = x the y value of the point is updated and then used when updating the z value of the point which is incorrect. To prevent the shrinkage save the new rotated values separately and then update the point with the values.
that explains it, thanks for clearing it up. I thought it was a floating point rounding error for a while
I'm having this problem. I am very new to this. Can you explain how to write that? Please and thank you.
@@Dee-c1l Just create a new vec3 variable and set it equal to the point in the parameter list. use the copy to do the math and set it equal to the new point after each section
heres the code.
float rad = 0;
vec3 OGpoint = point; //add this
rad = x;
point.y = cos(rad) * OGpoint.y - sin(rad) * OGpoint.z;
point.z = sin(rad) * OGpoint.y + cos(rad) * OGpoint.z;
OGpoint = point; // add this
rad = y;
point.x = cos(rad) * OGpoint.x + sin(rad) * OGpoint.z;
point.z = -sin(rad) * OGpoint.x + cos(rad) * OGpoint.z;
OGpoint = point; //add this
rad = z;
point.x = cos(rad) * OGpoint.x - sin(rad) * OGpoint.y;
point.y = sin(rad) * OGpoint.x + cos(rad) * OGpoint.y;
@@jynflyn1679 Very thankful for your reply. The cube is no longer shrinking. However, it spins on an axis but does not rotate as if out in space.
Great work!!
Thanks a lot!
Hey just a heads up, not sure if SDL updated the syntax but emplace_back is formatted
points.emplace_back(SDL_FPoint{ x, y });
instead of
points.emplace_back( x, y );
let me know if I missed something here
Hey, thanks but I still have an error which I am not sure how to fix, could you lend me a brain ?
SDL_rect.h:60:16: note: no known conversion for argument 1 from float' to 'SDL_FPoint&&'
This is what comes out, not sure what to do with it even though I work with Fpoint correctly (supposedly)
Any tips ? I know it's hard to say when you can't see my code, but any help is appreciated.
Thank you.
Can you please give more detailed explanation of how do the rotate function work please,
give me a link to a page where it does explain it or something.
I would appreciate it.
here you go en.wikipedia.org/wiki/Rotation_matrix
omg this worked smooooooooooth you are awesome
Glad I could help
This helped a lot. Now I just need to find a vide that tells how to map a texture to the cube.
I recommend using openGl and the SOIL library for textures. This video is more of a novelty example not very practical
Subscribe for more projects like this one
Exactly what I have been looking for! Gonna try to recreate that in C with graphics.h
it's a straightforward mapping, you might want to replace vector with a fixed size array since the points never exceed a certain size
@@TheBuilder not quite, as C doesn't have classes. It will be highly similar, but not straightforward mapping
@@TheBuilder oh, I didn't watch the video carefully, classes are only used for screen, which is inbuilt in "graphics.h". Yeah, it will be a straightforward mapping :)
This is also called a software renderer, since it does the same as classic graphics hardware, but really inefficiently on the CPU
Not really sure why but my cube starts out right but as it spins it gradually becomes flatter and longer until it eventually becomes a line that is spinning and no longer a cube.
someone pointed out that in the rotation function, I should have created a new point while performing the calculation.
I love this video thank you making it!
Glad you enjoyed it!
cleanest code ive ever seen
Nice!
Thanks, glad you enjoyed it
I wrote this in Flash, and it worked flawlessly! :)
Although it is interesting that i also had the cube shrinking problem in AS, despite it being a scripting language.
(100th like by the way)
Well done!
Hey how did you fix the shrinking problem? I'm new to 3D graphics programming and I don't exactly know how to frame questions yet. Glad to hear that I'm not the first or only one to have that issue. I thought I could simply work the Z component in the Rotate() function but it didn't work with either zero nor a positive or negative number. Thanks in advance!! This is a great video for those of us trying to get started with making our own 3D engines in SDL2 as a starting point.
@@BD-cv3wu If you are still curious about what was causing the shrinking problem, it is an accumulation of floating point error. It can be solved by keeping a copy of the points in their original positions and working off of them instead of rotating the same points over and over.
@@raybourke552 Thanks, I'll try that next time I have a chance. It sucks how evolved computers are, but how they can be undermined by floating point (in)precision! Or null/dangling pointers...or accessing elements of a list/table/vector that are nonexistent...or have null/dangling pointers. :)
Great video and explanation :^)
yes
Glad you liked it!
Thanks! I used this to create a more robust simple 3d engine, I'm too dumb to understand linear algebra
People don't understand math they just memorize it
@@TheBuilder Ohhh, lemme go like do that then I guess?
I am a newbee and there are at least 30 SDL2's on github, please hint which may be the best for these exercises? Also is SDL.h within the SDL2's? if not can you provide some hint which is best to use? Thanks much
Hello. Many thanks for the video. I tried to follow you on every step but when I compile it gives me """ error: new initializer expression list treated as compound expression""" AND """error: no matching function for call to 'SDL_FPoint::SDL_FPoint(float&)"""
Can you please help me?😟
try extracting that functionality and making it work in isolation
can anyone explain how the function works in general rotate? I've been sitting for several days now and I can't figure out which formula the lines "point.y = cos(rad) * point.y - sin(rad) * point.z;" come from... Help pls.
this link might help en.wikipedia.org/wiki/Rotation_matrix we're simply doing a matrix multiplication with a vector
@@TheBuilder thank you very much and really helped!!!
The C++ Programming Language
hey, after launching the program at 10:00 it instantly quits. Could this be a problem with windows focusing on my distro or a problem in the code?
could it be that it's not running in a loop?
@@TheBuilderyou were going so quick! Thank you very much
@@TheBuilder Dont want to be to bothersome, but one more thing. after 31:00 and starting my program, the cube starts to seperate into 2 spinning squares instead of a whole cube. What causes this?
thanks.
@@willyknickers9295 floating point numbers lose precision if you operate on them too much the precision loss becomes visible. try adding a delay to see if that helps, and no problem. I get these types of questions fairly regularly, I don't mind.
@@TheBuilder after a while it starts to look like a parallelogram . It seems like the faster the rotation is, the worse it gets. And there is no fun in a barely rotating cube. I honestly have no clue what to do haha. I also get different results from differents speeds 🤔
Very interesting ! but i don"t understand what the "points.size()" function do.
gives you the number of elements in the container
@@TheBuilder oh okay i was that simple. thanks bro !
Sir, when I entered ./pixel, nothing shows up and I entered control + z which shows [3]+ Stopped ./pixel . What might cause the problem? Good video by the way
part of being a programmer is being able to debug errors
part of dubugging errors is asking others for information. But Im good thanks for your comment.
My cube is getting smaller and smaller while rotating center stays the same. Eventually it shrinks into just a couple of points, is it something wrong with my line function or maybe something else? Thanks😃
You can try enabling -Wconversion in gcc to see if you're losing precision to conversions from float to int. Second floating point numbers lose precision whenever you do operations on them. Try adding a delay to slow the precision loss. Hope that helped
@@TheBuilder Could you also use the math floor and ceiling functions to offset most precision issues?
@@BD-cv3wu i'd imagine that would make things worse as rounding causes you to lose a lot of precision
@@TheBuilder Yes, yes it does. It works with 2D sidescrolling not 3D at all. My bad.
@@BD-cv3wu that's probably because you're using integers not floating point numbers to model your game. Another Idea would be to enable -Wconversion to check if you're converting to int anywhere in your code
Can u please paste a copy of the code in the description so that i don't have write it all to test it out 😃 it will be helpful
its lost to the ages. try looking up a code snippet on github a few people copied it verbatim on their github profiles
If anyone is having an issue with the pixel function "Error C2661 'SDL_FPoint::SDL_FPoint': no overloaded function takes 2 arguments" Try doing this instead in the pixel function:
points.emplace_back(SDL_FPoint{ x, y });
Also please if this is somehow bad practice, lemme know :)
Also I had another issue regarding the SDL2.dll not being found (on windows), I found a fix on stack overflow, from the SDL download "copy \SDL2\lib\x64\SDL2.dll to C:\Windows\System32 and \SDL2\lib\x86\SDL2.dll to C:\Windows\SysWOW64."
thanks for sharing your experience
Its nice of you to share your fix! You can also just swap to put_back() instead of emplace_back()
Thank you!
You saved my life
Soon as I did the random dots on screen thing my computer started whirring... WTF
I might've screwed somn up
try adding a small delay between each draw loop
@@TheBuilder regardless of it working or not, thank you for answering to random questions on you comments. That's S grade stuff
At 7:42 how did he create a new file
there are several ways to create a file depending on your operating system
over time, my cube becomes smaller and smaller, anyone have the same ?
floats lose precision over time. it could also be that you're converting from floats to ints which would make things worse try enabling -Wconversion in gcc to see if you're doing that anywhere in your code
@@TheBuilder damn i got a lot of strange convertions, i'm gonna work on that. thanks !
you skipped on the most important function in the video, rotate()
It's right there, look at the video chapters
@@TheBuilderyeah i know lol, but no explanation why it works, no explanation on it's math, hell you even speed it up for some reason
@@billcosta well I don't know the underlying reason why the equation works but you can read more about it here en.wikipedia.org/wiki/Rotation_matrix I just use the matrix to get the result I want.
Like and subcripe are done
could not use emplace_back in my code - i was getting new_allocator.h errors.
The solution that worked for me was to redefine the SDL_FPoint and adding constructor into it. The code looks like this: (if u use it u ll need to change name from SDL_FPoint to FPoint in vector. i dont know how it worked - have found it on the stack overflow
struct FPoint
{
float x;
float y;
FPoint(float a, float b)
: x(a)
, y(b)
{}
};
Could you provide Stack over flow link 🌷
a lotttt of thanks that worked with me after a lot of stress❤❤❤❤🥰🥰ua-cam.com/users/sgaming/emoji/7ff574f2/emoji_u2764.png
One day I'll get to the bottom of this, but it's not today
please help me ,I using visual studio ,but when I run the program I show this message"Severity Code Description Project File Line Suppression State
Error C2661 'SDL_FPoint::SDL_FPoint': no overloaded function takes 2 arguments cube_model_vs C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\xmemory 681 "
#include
#include
using namespace std;
class Screen
{
SDL_Event e;
SDL_Window* window;
SDL_Renderer* renderer;
std::vector points;
public:
Screen() {
SDL_Init(SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(640 * 2, 480 * 2, 0, &window, &renderer);
SDL_RenderSetScale(renderer, 2, 2);
}
void pixel(float x, float y) {
points.emplace_back(x, y);
}
void show() {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
for (auto& point : points) {
SDL_RenderDrawPointF(renderer, point.x, point.y);
}
SDL_RenderPresent(renderer);
}
void input() {
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT) {
SDL_Quit();
exit(0);
}
}
}
};
same error here problem in replace never fixed
Change points.emplace_back(x, y) to points.emplace_back((x, y)) and see if it works
Throw error " cannot convert argument 1 from float to const sdl_Fpoint "
@@engthanoon3889 hi sorry that didnt work,
But I think the problem lies with the pixel function... check if it is initialised properly and invoked at the right place
@@iuc7254 thanks i prettier that answer i'll try that ,
Beautiful tutorial, although I didn't understand some maths and how they work, but that's just me. Anyway, thank you.
tbh i dont understand the math either, just translating it to code