• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By racarate
      Hey everybody!
      I am trying to replicate all these cool on-screen debug visuals I see in all the SIGGRAPH and GDC talks, but I really don't know where to start.  The only resource I know of is almost 16 years old:
      http://number-none.com/product/Interactive Profiling, Part 1/index.html
      Does anybody have a more up-to-date reference?  Do people use minimal UI libraries like Dear ImgGui?  Also, If I am profiling OpenGL ES 3.0 (which doesn't have timer queries) is there really anything I can do to measure performance GPU-wise?  Or should I just chart CPU-side frame time?  I feel like this is something people re-invent for every game there has gotta be a tutorial out there... right?
       
       
    • By Achivai
      Hey, I am semi-new to 3d-programming and I've hit a snag. I have one object, let's call it Object A. This object has a long int array of 3d xyz-positions stored in it's vbo as an instanced attribute. I am using these numbers to instance object A a couple of thousand times. So far so good. 
      Now I've hit a point where I want to remove one of these instances of object A while the game is running, but I'm not quite sure how to go about it. At first my thought was to update the instanced attribute of Object A and change the positions to some dummy number that I could catch in the vertex shader and then decide there whether to draw the instance of Object A or not, but I think that would be expensive to do while the game is running, considering that it might have to be done several times every frame in some cases. 
      I'm not sure how to proceed, anyone have any tips?
    • 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 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 lxjk
      Hi guys,
      There are many ways to do light culling in tile-based shading. I've been playing with this idea for a while, and just want to throw it out there.
      Because tile frustums are general small compared to light radius, I tried using cone test to reduce false positives introduced by commonly used sphere-frustum test.
      On top of that, I use distance to camera rather than depth for near/far test (aka. sliced by spheres).
      This method can be naturally extended to clustered light culling as well.
      The following image shows the general ideas

       
      Performance-wise I get around 15% improvement over sphere-frustum test. You can also see how a single light performs as the following: from left to right (1) standard rendering of a point light; then tiles passed the test of (2) sphere-frustum test; (3) cone test; (4) spherical-sliced cone test
       

       
      I put the details in my blog post (https://lxjk.github.io/2018/03/25/Improve-Tile-based-Light-Culling-with-Spherical-sliced-Cone.html), GLSL source code included!
       
      Eric
  • Advertisement
  • Advertisement
Sign in to follow this  

OpenGL Engine design questions

This topic is 3445 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Thus far I've found the gamedev forums, and this forum in particular, to provide very useful information on everything that has to do with game engines. I've read many 'classic' threads where Yann L. explains everything from shadow mapping to scene graph implementations, and they've proven very helpful. However, in the process of working on my own rendering, I'm finding it difficult to ty all these theories and 'best designs' together in a coherent design that makes sense for me. I'll list the issues I'm running into and my thoughts about them one by one below... Also note that I'm using OpenGL, and though the renderer is designed to easily allow support for other libraries such as Direct3D I see no need to this yet, so I may sometimes refer to OpenGL specific things.
  • The scenegraph Everything I've read about the subject has led me to believe that spatial ordering and other optimization techniques don't belong in a scene graph. Currently I have a very limited SceneGraph class that consists of GroupNode and GeometryNode objects only (both are derived from SceneNode). GroupNodes can have children, GeometryNodes can't have children, so all geometry nodes are leaves of the tree. This works exactly the way I thought a scene graph is supposed to work (I can add parent-child relations between objects in a scene, and transformations in each node are relative to the parent node). Though many threads I've read about scene graphs add more types of nodes, I probably won't be doing that in the near future because I want things to remain as simple as possible until I've grown more comfortable with the design. So far so good, but my understanding starts lacking when it comes to passing objects from the scene graph to the Renderer. This has to do with the way in which GeometryNodes are defined in my engine:
    • GeometryNode The only thing that makes a GeometryNode different from its parent, SceneNode, is that it contains a BaseGeometry object. The BaseGeometry class is the parent class for all geometry in the engine. So you can make a BoxGeometry object, for example, that inherits from BaseGeometry and which defines the geometry for a box. I'm also working on classes like 'CaligariGeometry', or '3DSMaxGeometry' that will load geometry from disk. Similarly, I imagine there would be TerrainGeometry objects. Because all these Geometry classes inherit from BaseGeometry, they can all be passed to GeometryNodes in the scene graph. The scene graph doesn't really care what the geometry represents, it only knows about GeometryNodes, but what they contain is not of the scene graph's concern.
    • BaseGeometry BaseGeometry, as said, contains geometry data. I currently distinguish between many types of buffers. Think IndexBuffer, VertexBuffer, NormalBuffer, TexcoordBuffer etc. The reason why I did this is because I'm using the OpenGL buffer objects extension, and the framerate was higher when I used this system of many buffers for one object, rather than one large buffer with Vertex objects that contain everything from vertex position data to texture coordinates. I'm quite sure my tests are to be taken too seriously as I've never used any substantial number of vertices. Thus far all I'm rendering is a 100x100 grid with a couple of boxes on it, because I cannot load arbitrary 3D file formats yet that would allow me to more easily load more data.
    This is actually my first problem. With so many buffer objects for each (potentially small) geometric entity I foresee the rendering being horribly inefficient. Suppose you render 10,000 boxes with this scheme. Every box has 8 vertices, 8 colours, and 36 indices. That means this scene requires the use of 30,000 buffer objects whose contents all range from 8 to 36 indices. I thought it would be more efficient if the Renderer class kept several large buffers itself, but as far as I know that means you'd have to copy the geometry data into the renderer's buffers every frame (because with culling etc. going on I can't be certain if a geometric entity is still supposed to be in the renderer's buffers or not), which defeats the point of using vertex buffer objects altogether.
The second thing I have a hard time understanding how culling comes into play. It seems that using a scene graph for culling is not good; a scene graph is not meant for that. Reading through one of the threads on gamedev.net where Yann L. explains all about terrain and scene graphs, I got the impression that it may be good practise to let geometry cull itself. I can see the advantages of this in for example, a TerrainGeometry class, where the TerrainGeometry would implement a spatial partitioning scheme. This way the scene graph will still think of the terrain as a single "GeometryNode" entity, but the terrain itself could be a quadtree without the scene graph ever knowing. For terrain it'd work well, but other entities? Would it work to have an OctreeGeometry as a base class and have, for example, classes like 3DSMaxGeometry also inherit from OctreeGeometry (next to BaseGeometry)? I'm guessing this won't work as well... Animated models aren't really 'optimised' by octrees (from what I've read), and I can't see the benefit of putting small static geometry in an octree either. An other solution could be to work with several 'phases', first of which would be to update the scene graph, and then send all geometry to a culling phase. The drawback I can see to this is that all geometry will be treated equally, which I assume to not be desirable in all cases. Culling algorithms are going to be different for different types of geometry, so some distinction should still be made. These are just some of the questions I'm facing, and perhaps I shouldn't even bother with them and proceed making a horrible inefficient renderer that is to be improved upon later, but I'd still like to hear some opinions, as I find it nearly impossible to 'move on' without addressing any of these concerns. I constantly fear that I'm making my engine so inefficient that the second I'm done with it, I'll want to scratch half of it. Eventually, facing these questions will be inevitable so I thought I might as well do it now. Thanks in advance for any feedback :)

Share this post


Link to post
Share on other sites
Advertisement
I'm gonna do some shameless advertising first ;)

I've written a series of articles about engine architecture, intended for beginners here :
http://www.beyond3d.com/content/articles/98 (Part 1)
http://www.beyond3d.com/content/articles/102/ (Part 2)
(More written, but not published yet :( )

You might find something useful in there.


I tend to rename things, giving good names is difficult, but I find important to name things as accurately as possible in order to be understood easily.
So in my engine design (not necessarily the best, it's just one solution to the problem, probably not the worst at least ;) ), I have a SceneTree (a Tree is a Graph, but everyone gets what a tree is w/o any further specifications), a SpatialGraph (Directed Acyclic Graph), and I used to have a RenderGraph, but I replaced it by a kind of RenderQueue.

The SceneTree is solely used for hierarchical animation. (Be it skeletal animation or a sword held in a character's hand.) This node type has an update(...) function that allows animation, and the nodes make a tree (a single parent, any number of children).

The SpatialGraph is used for culling (in fact finding what's visible). It's its only purpose in life to make culling fast.

The RenderQueue, is filled during culling in the spatialgraph. It's not a single array though, it's a little more complex than that. I did write something directly inspired from Yann Lombard thread about his material system.
The only task of this RenderQueue is to render whatever has been found visible FAST. (ie means sorting sub arrays per key, each key holding data such as depth, shader ID...; whatever is appropriate.)



Examples:
Terrain
It has a single node in the SceneTree, that does nothing.
(Nothing happens based on time on this terrain.)
It's made of a number of nodes in that SpatialGraph, making a Quadtree, which root is the Terrain's SpatialNode, and Leaves would contain mesh or pointers to meshes.

Character
It has a number of nodes in the SceneTree, for Meshs and Bones, which both might be animated hierarchicaly. It might also have something attached to his hand(s), that would need hierarchical relationship.
It has one SpatialLeaf node per mesh.


I call Geometry a Mesh instead.
I might be a bit synthetic, ask if I'm not clear enough.

[Edited by - Ingenu on November 20, 2008 5:14:29 AM]

Share this post


Link to post
Share on other sites
I very much like the SceneTree, SpatialGraph and RenderView nomenclature. It says what it does and this is a huge advantage over the word SceneGraph. I will use Ingenu terms from now on.

Share this post


Link to post
Share on other sites
If all of the boxes are the same, then why would you need so many vertex buffers? Can't you reuse them?

Share this post


Link to post
Share on other sites
It's very hard to think of some kind of general 3D engine architecture which can handle everything in a nice object-oriented way and is also extremely fast and efficient. If something is for everything - it's for nothing.

Why not to keep all subsystems separately? Terrain could store all its nodes in quad-tree structure, characters could have its own hierarchy tree, and world geometry might be handled/occluded by its own BSP/PVS, or oct-tree structure (depending on what we need).
All subsystems write renderable items into render manager (render queue), which perform sorting by depth, material ID, priority, or whatever we want.

Using this approach we can optimize every single subsystem without touching the others.

Share this post


Link to post
Share on other sites
I suppose I'll throw my design into the discussion too, although it doesn't deal with the scene graph side of things as much as you are looking for:

Hieroglyph Design

You don't actually need to have many buffers to represent many objects. You can simply have a single buffer (or multiple large ones if you like) and each object indexes into that big buffer instead of each object having its own. Then you just need to centralize the access to the buffer, which can be coordinated through your renderer interface.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement