• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By fleissi
      Hey guys!

      I'm new here and I recently started developing my own rendering engine. It's open source, based on OpenGL/DirectX and C++.
      The full source code is hosted on github:

      I would appreciate if people with experience in game development / engine desgin could take a look at my source code. I'm looking for honest, constructive criticism on how to improve the engine.
      I'm currently writing my master's thesis in computer science and in the recent year I've gone through all the basics about graphics programming, learned DirectX and OpenGL, read some articles on Nvidia GPU Gems, read books and integrated some of this stuff step by step into the engine.

      I know about the basics, but I feel like there is some missing link that I didn't get yet to merge all those little pieces together.

      Features I have so far:
      - Dynamic shader generation based on material properties
      - Dynamic sorting of meshes to be renderd based on shader and material
      - Rendering large amounts of static meshes
      - Hierarchical culling (detail + view frustum)
      - Limited support for dynamic (i.e. moving) meshes
      - Normal, Parallax and Relief Mapping implementations
      - Wind animations based on vertex displacement
      - A very basic integration of the Bullet physics engine
      - Procedural Grass generation
      - Some post processing effects (Depth of Field, Light Volumes, Screen Space Reflections, God Rays)
      - Caching mechanisms for textures, shaders, materials and meshes

      Features I would like to have:
      - Global illumination methods
      - Scalable physics
      - Occlusion culling
      - A nice procedural terrain generator
      - Scripting
      - Level Editing
      - Sound system
      - Optimization techniques

      Books I have so far:
      - Real-Time Rendering Third Edition
      - 3D Game Programming with DirectX 11
      - Vulkan Cookbook (not started yet)

      I hope you guys can take a look at my source code and if you're really motivated, feel free to contribute :-)
      There are some videos on youtube that demonstrate some of the features:
      Procedural grass on the GPU
      Procedural Terrain Engine
      Quadtree detail and view frustum culling

      The long term goal is to turn this into a commercial game engine. I'm aware that this is a very ambitious goal, but I'm sure it's possible if you work hard for it.


    • By tj8146
      I have attached my project in a .zip file if you wish to run it for yourself.
      I am making a simple 2d top-down game and I am trying to run my code to see if my window creation is working and to see if my timer is also working with it. Every time I run it though I get errors. And when I fix those errors, more come, then the same errors keep appearing. I end up just going round in circles.  Is there anyone who could help with this? 
      Errors when I build my code:
      1>Renderer.cpp 1>c:\users\documents\opengl\game\game\renderer.h(15): error C2039: 'string': is not a member of 'std' 1>c:\program files (x86)\windows kits\10\include\10.0.16299.0\ucrt\stddef.h(18): note: see declaration of 'std' 1>c:\users\documents\opengl\game\game\renderer.h(15): error C2061: syntax error: identifier 'string' 1>c:\users\documents\opengl\game\game\renderer.cpp(28): error C2511: 'bool Game::Rendering::initialize(int,int,bool,std::string)': overloaded member function not found in 'Game::Rendering' 1>c:\users\documents\opengl\game\game\renderer.h(9): note: see declaration of 'Game::Rendering' 1>c:\users\documents\opengl\game\game\renderer.cpp(35): error C2597: illegal reference to non-static member 'Game::Rendering::window' 1>c:\users\documents\opengl\game\game\renderer.cpp(36): error C2597: illegal reference to non-static member 'Game::Rendering::window' 1>c:\users\documents\opengl\game\game\renderer.cpp(43): error C2597: illegal reference to non-static member 'Game::Rendering::window' 1>Done building project "Game.vcxproj" -- FAILED. ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========  
      #include <GL/glew.h> #include <GLFW/glfw3.h> #include "Renderer.h" #include "Timer.h" #include <iostream> namespace Game { GLFWwindow* window; /* Initialize the library */ Rendering::Rendering() { mClock = new Clock; } Rendering::~Rendering() { shutdown(); } bool Rendering::initialize(uint width, uint height, bool fullscreen, std::string window_title) { if (!glfwInit()) { return -1; } /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); if (!window) { glfwTerminate(); return -1; } /* Make the window's context current */ glfwMakeContextCurrent(window); glViewport(0, 0, (GLsizei)width, (GLsizei)height); glOrtho(0, (GLsizei)width, (GLsizei)height, 0, 1, -1); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glfwSwapInterval(1); glEnable(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glEnable(GL_TEXTURE_2D); glLoadIdentity(); return true; } bool Rendering::render() { /* Loop until the user closes the window */ if (!glfwWindowShouldClose(window)) return false; /* Render here */ mClock->reset(); glfwPollEvents(); if (mClock->step()) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glfwSwapBuffers(window); mClock->update(); } return true; } void Rendering::shutdown() { glfwDestroyWindow(window); glfwTerminate(); } GLFWwindow* Rendering::getCurrentWindow() { return window; } } Renderer.h
      #pragma once namespace Game { class Clock; class Rendering { public: Rendering(); ~Rendering(); bool initialize(uint width, uint height, bool fullscreen, std::string window_title = "Rendering window"); void shutdown(); bool render(); GLFWwindow* getCurrentWindow(); private: GLFWwindow * window; Clock* mClock; }; } Timer.cpp
      #include <GL/glew.h> #include <GLFW/glfw3.h> #include <time.h> #include "Timer.h" namespace Game { Clock::Clock() : mTicksPerSecond(50), mSkipTics(1000 / mTicksPerSecond), mMaxFrameSkip(10), mLoops(0) { mLastTick = tick(); } Clock::~Clock() { } bool Clock::step() { if (tick() > mLastTick && mLoops < mMaxFrameSkip) return true; return false; } void Clock::reset() { mLoops = 0; } void Clock::update() { mLastTick += mSkipTics; mLoops++; } clock_t Clock::tick() { return clock(); } } TImer.h
      #pragma once #include "Common.h" namespace Game { class Clock { public: Clock(); ~Clock(); void update(); bool step(); void reset(); clock_t tick(); private: uint mTicksPerSecond; ufloat mSkipTics; uint mMaxFrameSkip; uint mLoops; uint mLastTick; }; } Common.h
      #pragma once #include <cstdio> #include <cstdlib> #include <ctime> #include <cstring> #include <cmath> #include <iostream> namespace Game { typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; typedef float ufloat; }  
    • By 51mon
      I'm dealing with ribbons following the shape of multiple spline segments. It's straightforward to compute the direction at any point along the spline. However the ribbon also got a flat shape and I'm struggling with finding a way to compute the angle of the ribbon in the plane perpendicular to the direction.
      To illustrate what I mean here's a piece of code that almost worked:
      float3x3 rotMtxFromSpline; rotMtxFromSpline[1] = normalize(splineDir); rotMtxFromSpline[0] = normalize(cross(float3(1, 0, 0), rotMtxFromSpline[1])); rotMtxFromSpline[2] = cross(rotMtxFromSpline[0], rotMtxFromSpline[1]); // Rotate rotMtxFromSpline[0] in the rotMtxFromSpline[0]-rotMtxFromSpline[2]-plane to align with float3(0, 0, 1) dir rotMtxFromSpline[0] = normalize(dot(rotMtxFromSpline[0], float3(0, 0, 1)) * rotMtxFromSpline[0] + dot(rotMtxFromSpline[2], float3(0, 0, 1)) * rotMtxFromSpline[2]); rotMtxFromSpline[2] = cross(rotMtxFromSpline[0], rotMtxFromSpline[1]); The problem with this code is when the spline segment becomes perpendicular to (0,0,1)-dir as the orientation switch from one side to the other very easily.
      The approach above is kind of a global approach and I'm thinking if there's a way to append some info to each spline segment to remedy the issue.
      Anyhow I wanted to post this question in case anyone had a similar problem that they solved or maybe anyone know some web resource dealing with this issue?
    • By Ty Typhoon
      Before read everything i am honest:
      Payment after release you get your percentage lifetime for that project.
      i dont need your inspirations, ideas, music or designs.
      My head is full with that.
      I need workers who i can trust.
      Please let us talk in discord.
      I got a lot of stuff planned, there is much work to do.
      But first my team and me try to start with a small mini game and we need maybe exactly you.
      Planned for more than pc, like ps4, xbox one and mobile - so its very important to us to hopefully welcome a programmer.
      The mini game will be part of the planned big game. There will be never before seen guns and gameplay, you will get deeper info if youre a safe part of the team.
      I need:
      Zbrush pros
      Join here please:
      You find me here:
      Joerg Federmann Composing#2898
    • By Ty Typhoon
      I like to build my A - Team now.
      I need loyal people who can trust and believe in a dream.
      If you got time and no need for direct pay please contact me now.
      We cant pay now, you will recieve a lifetime percentage if the released game will give earnings. 
      If I get the best people together for a team, everything should be possible.
      What i need:
      - Programmer c++
      - Unity / Unreal - we must check whats possible, please share your experience with me.
      - Sculpter, 3D Artist
      - Animator
      - Marketing / Promotion 
      What i do:
      - Studio Owner
      - Director
      - Recruit exactly you
      - Sounddesign
      - Main theme composing
      - Vocals
      - Game design
      - Gun, swords, shields and weapon design
      - Character, plants and animal design
      Please dont ask about the Name of the Game, about Designs or Screenshots.
      The game will be defintitly affected about our and your skills if you join the team.
      Planned for the big Game:
      - 1st person shooter
      - online multiplayer
      - character manipulation
      - complete big open world with like lifetime actions and reactions
      - gunstore with many items to buy
      - many upgrades for players
      - specials like mini games
      So if you are interested in joining a team with a nearly complete game idea, contact me now and tell me what you can do.
      joerg federmann composing#2898
  • Advertisement
  • Advertisement

Help me to better understand Rotation Matrix

Recommended Posts

Hi guys, I'm trying to build my 3x3 rotation matrix algorithm for the sake of thoroughly understand it as much as I can

The code below is what I just wrote from memory in an attempt to explain it to myself and test what I understand and what I do not.

I roughly start to get it (saw it last week for the first time and kind of crashed my soul, at the time) and if I decompose it in small single pieces as I did below, it actually works and my point is being rotated to the appropriate coordinates (or almost, since the y component ends up getting 0ed out, so I think I just need to add back the p_proj_to_rA Vector to the final resoult to have it right).

This being said, I completely missed the point of building a rotation matrix out of it, even though the whole time I was convinced to be moving toward the goal :D

I mean I've made my matrix class with all the relevant operations/methods, but I just don't know how to do the final step to convert what I have below into a rotation matrix...and I do not mean the fomula, which I have in the book and I can copypaste that and have it work if I want to, what I need is to actually see how to derive that final matrix formula from what I have below, I need to understand how it correlate in a way that if I where to reason about the final rotation matrix formula in the book I could say "of course, it's obvious".

So everyone that deeply understand rotation matrix and how to end up with one(without just copy-pasting the formula from a book or using a function that just give you one) is welcome to take on the challenge of making it look obvious to me, so that I can finish my program and end up with the correct one for wathever Axis of rotation I choose :D

Or just link me wathever online resource helped you in the past :)

Thanks :)


	Vector p = { 1, 1, 1 };// point that needs to rotate
	Vector rA = { 0, 1, 0 }; // rotation Axis
	p.computeMagnitude(); // sqrt( x*x + y*y + z*z )
	rA.computeMagnitude();// sqrt( x*x + y*y + z*z )

	//projection of our point on the rotation axis, which corresponds to the dotProduct since rA is of lenght 1
	// Formula 1 dotProduct(p,rA) = px*rAx + py*rAy + pz*rAz
	// Formula 2 dotProduct(p,rA) = |p| * |rA| * cos(angleBetween) 

	//	    proj_rA(p) = dotProduct(p,rA) = |p| * 1 * cos(angleBetween) = |p| * cos(angleBetween)

	//Solve Formula 2 for angleBetween
	//|p| * cos(angleBetween) =      dotProduct(p,rA)
	//      cos(angleBetween) =     (dotProduct(p,rA) / |p|)
	//          angleBetween  = acos( dotProduct(p,rA) / |p| ) 

	//	    proj_rA(p) = |p| * cos(angleBetween)
	//      proj_rA(p) = |p| * cos( acos( dotProduct(p,rA) / |p| ) )
	//projection of p on rA:
	double proj_to_rA = p.magnitude * cos(Vector::angleBetween(p, rA));

	//vector p projected on rA, which is basically a longer or shorter version of rA
	Vector p_proj_to_rA = rA * proj_to_rA;

	//subtracting from p the (projection of p on rA) zeroes out the dotProduct(p,rA) so the resulting vector must be orthogonal to rA
	Vector p_perp_to_rA1 = p - p_proj_to_rA;

	//the cross product between two vector is a vector orthogonal to both of them
	//Formula 1 crossProduct(A,B) = |A|*|B|*sin(angleBetween) 
	//Formula 2 v1.y*v2.z - v1.z*v2.y, //X
	//	    v1.z*v2.x - v1.x*v2.z, //Y
	//	    v1.x*v2.y - v1.y*v2.x  //Z
	Vector p_perp_to_rA2 = Vector::crossProduct(rA, p_perp_to_rA1);

	//since rA, p_perp_to_rA1 and p_perp_to_rA2 are all perpendicular to each other, 
	//if we now only consider p_perp_to_rA1 and p_perp_to_rA2 they describe a 2d plane
	//perpendicular to rA, and we rotate stuff based on this plane
	//Now the desired point of that plane is the sum  (VectorX on p_perp_to_rA1  + VectorY on p_perp_to_rA2)
	double desiredRotation = toRad(-30);
	double X = cos(desiredRotation);
	double Y = sin(desiredRotation);
	Vector finalPoint = Vector(p_perp_to_rA1 * X) + Vector(p_perp_to_rA2 * Y);

	cout << "x,y,z{ 1, 1, 1 } -30 degree on the x,y,z{ 0, 1, 0 } Axis = " << finalPoint << endl;

	return 0;



x,y,z{ 1, 1, 1 } -30 degree on the x,y,z{ 0, 1, 0 } Axis =   x,y,z{0.366025 ,0, 1.36603}


Edited by MarcusAseth

Share this post

Link to post
Share on other sites

Rotation matrix is nothing special, that is, it's a matrix, like all other matrices. I'll do this in 2D to reduce writing, but the general principle extends to matrices of any size.

Say I have a matrix (LaTeX stuff doesn't work for me, so I drop down to the less nice but working ASCII variation)

    [ a b ]
A = [ c d ]

Applying that to a vector (x, y) gives

    [ x ]   [ a b ]   [ x ]   [ a * x + b * y ]
A * [ y ] = [ c d ] * [ y ] = [ c * x + d * y ]

Nothing new, right? "x" gets applied to the first column, "y" to the second column, and you add the results.

Let's apply vector (1, 0) and vector (0, 1):

    [ 1 ]   [ a b ]   [ 1 ]   [ a ]
A * [ 0 ] = [ c d ] * [ 0 ] = [ c ]

    [ 0 ]   [ a b ]   [ 0 ]   [ b ]
A * [ 1 ] = [ c d ] * [ 1 ] = [ d ]

Now compare the result vectors with the original matrix. As you can see, the (1, 0) vector gave us the first column, and the (0, 1) vector gave us the second column. Trivially explainable from the equations right?

But wait, what if we do it the other way around? That is, in our 2D space, we decide where (1, 0) should end up after applying the matrix (giving us a and c), we decide where (0, 1) should end up after applying the matrix (giving us b and d), and we use those numbers to construct the matrix.

So where does (1, 0) end up after rotation? It's at (cos(p), sin(p)), with "p" the rotation angle. Similarly, (0, 1) ends up at (-sin(p), cos(p)). The rotation matrix is thus

[ cos(p) -sin(p) ]
[ sin(p)  cos(p) ]

This will work for any regular matrix without problem, it rests on the fact that the transformation applies to each axis individually, and is then summed (ie the set equations that define the meaning of the matrix).

A translation matrix is a bit weird in the sense that the 4th axis always uses the unit vector (0, 0, 0, 1) in the matrix application (it's not a regular axis like the x, y, and z axes), so you may want to handle that separately.






Edited by Alberth
Stupid latex code was still inserted as text

Share this post

Link to post
Share on other sites
11 minutes ago, Alberth said:

So where does (1, 0) end up after rotation? It's at (cos(p), sin(p)), with "p" the rotation angle. Similarly, (0, 1) ends up at (-sin(p), cos(p)). The rotation matrix is thus

[ cos(p) -sin(p) ]
[ sin(p)  cos(p) ]


You completely lost me here xD

I guess for me that is not obvious at all, I mean, if you where to ask me how to buil that rotation matrix you wrote I won't know where to start, I think  the problem for me would become even exponentially bigger adding a third dimension.

Share this post

Link to post
Share on other sites

The point I was trying to make is

  • the first column in a matrix is the position where the first unit vector ends up (after applying the matrix),
  • the second column in a matrix is where the second unit vector ends up (after the applying the matrix),
  • the third column in a matrix is where the third unit vector ends up (after the applying the matrix),
  • etc.

This reduces the problem of making any 3D matrix to knowing where the three unit vectors end up.

Maybe your problem is not so much in creating a matrix, but more in understanding how to do rotation in 3D space?


Matrices are just a convenient way to write a set of equations in a compact way (this is why everybody loves them), but they don't enable anything you can't already do with simple variables, and the "*" and "+" operators.


Share this post

Link to post
Share on other sites

That's totally possible, that's why I'm going trough THIS and

" rel="external nofollow">THIS playlist right now, I think that knowledge will either solve my problem or enable me to get more out of your and everyone else explanation, therefore I'll be reading what you've wrote above more than once for sure :P

Edited by MarcusAseth

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement