• 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:
      https://github.com/fleissna/flyEngine

      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.

      Bye,

      Phil
    • By deadless games
      i'm am looking for volunteers with little or no experience to help with music and graphic design.
      i was thinking of making a platformer game by myself to get into programming but struggled to make music and do Character design
      you PC doesn't need to be amazing,need to be willing to spend time doing your role,
      if you are interested please contact me with one of the means below.
      email deadlessgames@gmail.com
      discord xwolf572#6974
       
    • 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 ==========  
       
      Renderer.cpp
      #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; }  
      Game.zip
    • By Old Mohave Games Studio
      Bitcoin Survival! An 1-bit graphics charming game made in 5 days for the 2018's Crypto Game Jam. It's a Roguelike Clicker Game in which you must mine bitcoins to buy and upgrade itens in order to survive as long as you can! All assets original made by me. Come play. And, please, share and rate. Any suggestions for the game are welcome too. (ALSO REPORT ME ANY BUGS FOUND)
      DEVLOG. V. 0.2
      - The game has been extensively polished. Many bugs have been fixed and many features have been added to the game. The difficulty has been balanced once again. Maybe I still have to update some things in the tutorial, but that's easy and I will be doing this in the next days. Hope you enjoy the game at this actual stage. It's almost like a new game.
      - It's mobile compatible!
      IF YOU LIKED THE GAME, PLEASE DON'T FORGET TO SHARE AND RATE IT! That would help me a lot.
      https://www.scirra.com/arcade/strategy-games/bitcoin-survival-28765




    • By 51mon
      Hey
      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?
       
      Thanks!
  • Advertisement
  • Advertisement

Improving 2D raycasting performance

Recommended Posts

Hello everybody.

I have implemented a 2D raycasting algorithm in my game engine but I must be doing something very wrong, since my game is pretty much unplayable if I cast around 10 rays each frame (it runs fine at around 5-6 casts per frame). I tried profiling but, as you can see from the two pictures, I ended up on STL territory, which tells me that the performance issues arise from my approach to the problem.

I'm using the Sweep-and-Prune algorithm for my broadphase detection, which divides my entire map into sections, and colliders inside a section are only checked for collisions with other colliders from that section. This approach is used in my raycasting algorithm as well. Initially, I get a list of all colliders inside the raycast's radius and then I check the ray against every collider in that list. As far as I understand it the problem lies not in the Ray vs. Shape checks, but in the preparation work before that. Any tips or guidelines on how to correct my approach, or specifics of the algorithms, are most welcome.

Thank you in advance.

Raycast

 

bool MCollisionEngine::Raycast(const glm::vec2& Origin, const glm::vec2& Direction, float MaxDistance, std::string LayerMask, bool bHitTriggers) const
{
	std::vector<PCollider*> PossibleColliders = GetCollidersInRadius(Origin, MaxDistance, LayerMask, bHitTriggers);
	const std::bitset<32> CollisionMask = std::bitset<32>(LayerMask);

	for (PCollider* const Collider : PossibleColliders)
	{
		const PCollisionLayer& ColliderLayer = Layers.at(Collider->LayerKey);

		if (CollisionMask.test(ColliderLayer.Index))
		{
			SShape* Shape = Collider->Shape.get();
			switch (Shape->GetType())
			{
				case EShapeType::AABB:
					if (RayIntersectsAABB(Origin, Direction, MaxDistance, static_cast<SAABB*>(Shape)))
					{
						return true;
					}
					break;

				case EShapeType::Circle:
					if (RayIntersectsCircle(Origin, Direction, MaxDistance, static_cast<SCircle*>(Shape)))
					{
						return true;
					}
					break;

				case EShapeType::OBB:
					if (RayIntersectsOBB(Origin, Direction, MaxDistance, static_cast<SOBB*>(Shape)))
					{
						return true;
					}
					break;
			}
		}
	}

	return false;
}

 

 

BroadCircleToOBB

 

bool MCollisionEngine::BroadCircleToOBB(const SCircle& Circle, const SOBB* const OBB)
{
	const std::vector<glm::vec2>& Normals = OBB->GetNormals();

	for (int i = 0; i < 2; i++)
	{
		const glm::vec2& Normal = Normals[i];

		Line CircleProj = Circle.ProjectInto(Normal);
		Line OBBProj = OBB->ProjectInto(Normal);

		if (glm::length(CircleProj.CalculatePenetrationVector(OBBProj)) < Utils::EPSILON)
		{
			return false;
		}
	}

	return true;
}

 

 

SOBB::GetSupportPoint

 

glm::vec2 SOBB::GetSupportPoint(const glm::vec2& Direction) const
{
	const std::vector<glm::vec2>& Vertices = GetVertices();

	float BestProjection = -std::numeric_limits<float>::max();
	glm::vec2 BestVertex;

	for (const glm::vec2& Vertex : Vertices)
	{
		float Projection = glm::dot(Vertex, Direction);

		if (Projection > BestProjection)
		{
			BestProjection = Projection;
			BestVertex = Vertex;
		}
	}

	return BestVertex + Position;
}

 

1.png

2.png

Edited by Kercyn

Share this post


Link to post
Share on other sites
Advertisement

You should click on that button top right of the profiling results that says something like "generate detailed report". Then you can click around the hot path and see which lines of code are hot. Anyways, just from the call stack it looks like your function GetCollidersInRadius is super slow.

 

Edit: Also because you keep using "const auto&" I have no clue what your code is doing. It's completely unreadable for me personally.

Edited by Randy Gaul

Share this post


Link to post
Share on other sites
16 hours ago, Randy Gaul said:

You should click on that button top right of the profiling results that says something like "generate detailed report". Then you can click around the hot path and see which lines of code are hot. Anyways, just from the call stack it looks like your function GetCollidersInRadius is super slow.

 

Edit: Also because you keep using "const auto&" I have no clue what your code is doing. It's completely unreadable for me personally.

 

Thanks for the reply. It's too late right now to check your suggestion so I'll do it tomorrow. For the const auto& issue, I replaced all autos in the first post with their actual type. I'm also including the headers used in the snippets above, just in case.

PCollisionLayer

 

class PCollisionLayer final
{
	public:
		PCollisionLayer() = default;
		PCollisionLayer(std::size_t Index_, std::bitset<32> CollisionMask_)
			: Index(Index_), CollisionMask(CollisionMask_)
		{}
		~PCollisionLayer() = default;

		//! The layer's index in the collision mask.
		std::size_t Index;

		std::bitset<32> CollisionMask;
};

Line

 

class Line final
{
	public:
		Line() = default;
		Line(glm::vec2 a_, glm::vec2 b_);
		~Line() = default;

		glm::vec2 a;
		glm::vec2 b;

		//! Calculates the penetration vector between this and Other.
		// http://www.metanetsoftware.com/technique/tutorialA.html
		glm::vec2 CalculatePenetrationVector(const Line& Other) const;

		Line ProjectInto(const glm::vec2& Axis) const;
		bool IsPointInside(const glm::vec2& Point) const;

		float GetLength() const;
		
		bool operator<(const Line& lhs) const;
		bool operator>(const Line& lhs) const;
		bool operator<=(const Line& lhs) const;
		bool operator>=(const Line& lhs) const;

		bool operator==(const Line& lhs) const;
		bool operator!=(const Line& lhs) const;
};

 

 

EDIT: I tried what you suggested but unfortunately all I got was a fancier way of viewing what already existed in the call stack table. My main concern is that my entire approach is wrong, since the "hottest" line ends up being a range-based for.

Edited by Kercyn

Share this post


Link to post
Share on other sites
On 7/6/2017 at 4:12 PM, Kercyn said:

EDIT: I tried what you suggested but unfortunately all I got was a fancier way of viewing what already existed in the call stack table. My main concern is that my entire approach is wrong, since the "hottest" line ends up being a range-based for.

Try posting that image so others can see the hot path in your code, if you still wanted advice on this stuff.

Share this post


Link to post
Share on other sites

I was struggling with this for a couple of days, but I finally decided to replace my algorithm with a much simpler one that runs way more efficiently. Thanks for the guidelines!

Share this post


Link to post
Share on other sites
On 7/15/2017 at 5:22 AM, Kercyn said:

I was struggling with this for a couple of days, but I finally decided to replace my algorithm with a much simpler one that runs way more efficiently. Thanks for the guidelines!

can you please tell me about the better algorithm? 

Share this post


Link to post
Share on other sites
14 hours ago, Andrew Feng said:

can you please tell me about the better algorithm? 

You can find the source code here.

What I'm doing is applying a reverse-rotation to the ray, so that I can treat the problem as a ray vs AABB collision. Then I'm implementing the algorithm described here. It may not be the fastest or most efficient implementation, but for my current needs, it's "good enough".

Edited by Kercyn

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