Jump to content
  • Advertisement

Search the Community

Showing results for tags 'C++'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Categories

  • Audio
    • Music and Sound FX
  • Business
    • Business and Law
    • Career Development
    • Production and Management
  • Game Design
    • Game Design and Theory
    • Writing for Games
    • UX for Games
  • Industry
    • Interviews
    • Event Coverage
  • Programming
    • Artificial Intelligence
    • General and Gameplay Programming
    • Graphics and GPU Programming
    • Engines and Middleware
    • Math and Physics
    • Networking and Multiplayer
  • Visual Arts
  • Archive

Categories

  • Audio
  • Visual Arts
  • Programming
  • Writing

Categories

  • Game Dev Loadout
  • Game Dev Unchained

Categories

  • Game Developers Conference
    • GDC 2017
    • GDC 2018
  • Power-Up Digital Games Conference
    • PDGC I: Words of Wisdom
    • PDGC II: The Devs Strike Back
    • PDGC III: Syntax Error

Forums

  • Audio
    • Music and Sound FX
  • Business
    • Games Career Development
    • Production and Management
    • Games Business and Law
  • Game Design
    • Game Design and Theory
    • Writing for Games
  • Programming
    • Artificial Intelligence
    • Engines and Middleware
    • General and Gameplay Programming
    • Graphics and GPU Programming
    • Math and Physics
    • Networking and Multiplayer
  • Visual Arts
    • 2D and 3D Art
    • Critique and Feedback
  • Community
    • GameDev Challenges
    • GDNet+ Member Forum
    • GDNet Lounge
    • GDNet Comments, Suggestions, and Ideas
    • Coding Horrors
    • Your Announcements
    • Hobby Project Classifieds
    • Indie Showcase
    • Article Writing
  • Affiliates
    • NeHe Productions
    • AngelCode
  • Topical
    • Virtual and Augmented Reality
    • News
  • Workshops
    • C# Workshop
    • CPP Workshop
    • Freehand Drawing Workshop
    • Hands-On Interactive Game Development
    • SICP Workshop
    • XNA 4.0 Workshop
  • Archive
    • Topical
    • Affiliates
    • Contests
    • Technical
  • GameDev Challenges's Topics
  • For Beginners's Forum

Calendars

  • Community Calendar
  • Games Industry Events
  • Game Jams
  • GameDev Challenges's Schedule

Blogs

There are no results to display.

There are no results to display.

Product Groups

  • Advertisements
  • GameDev Gear

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


About Me


Website


Role


Twitter


Github


Twitch


Steam

Found 787 results

  1. I am looking for some advice in how best to structure a text-based football game in C++. I am actually a trying to mimic an old DOS game called Armchair Quarterback but without any graphics for the time being. The original DOS game had very minimal graphics just showing a cursor moving across a static graphic (but I will leave the graphics to the end). I attached what the original game looked like below. So far, I wrote functions for the following : - for the user to select a team - for the user to select the opponent's which is always the CPU controlled - for the user to select difficulty (enum) Things left to do: Set-up one overarching team class for all the teams in the game then each specific team would inherit the attributes from the overarching team class. In the original game, each team only had four attributes that they were rated on. I would also have to construct 17 offensive plays that the user has to choose from. Would each play be a separate function??? Also, the main logic and AI would need to be constructed (would need some variables for logic and AI). -Bigger pass plays have lower % of completion than shorter pass plays -CPU is guessing what the user selects to "play" defense -The user is guessing what the CPU selects to "play" defense -This will incorporate the attribute ratings for the offense and defense per team plus randomness and the situation in the game (down and distance???) Any help would be appreciated in how the code base should be structured. Thanks! DK -
  2. I'm doing a WinAPI/DX10 framework rewrite and this time around I'd like to start handling errors a little more seriously in my code. Up to this point I've allowed the code to fail naturally and catch the exception within VS. I always found that to be the quickest method. Usually a break occurs and I just step through the call stack and find the problem in seconds (hopefully). However I'm not really sure that's the proper way to do this, but it does feel like I can avoid writing code that is littered with FAILED() or if( == NULL) statements. So what is the proper way? I've read a few other threads on here that talk about using asserts, but I've never really seen any code written with that so I'm bit doubtfull. Most of the conditions I'd like to monitor for errors are usually DirectX function return values, sometimes null points, sometimes WinAPI function fail handles, sometimes index overrun errors, but mostly DX function fails. Again, I feel like debug DX libraries are very verbose and do a wonderful job interacting with VS as it is, so up to this point I've just relied on output window messages for that, but again I'd like to know if that is a proper way to do things. P.S the framework is really just a learning tool for me so it's not going to see serious use. So I lean on the side of cleaner, more readable code vs obfuscated one, so I'd like to not go too crazy with error checking however I'd like to get at least an idea of the way things are done properly. P.P.S I'd also like to mention that I am aware of exceptions however I'm particularly asking about catching programming errors, I was under the impression that exception handling is more of a run-time error detection method to catch things that are not really the programmers fault (like memory, harwdware or network issues).
  3. I am looking for resources on best practices (really any info at this point) on how to program a dependency graph with functions that create nodes, create attributes and connect attributes. For some reason this topic is kryptonite for my Google Fu.
  4. Based upon where my how far back from the camera is there will be a artifact of my point light. Here is what I mean before going into details I have a flat rectangle and a standing rectangle of 20x20 dimensions with a point light of 22 radius. My camera currently sits at -76 but if I were to move the camera to -75 then even in the most extreme example of point light z = 3.0 from above will no longer have the artifact. I am not sure what could be causing it but I have tried several idea to avail. The one with the biggest benefit seemed to be scaling my world matrix for rendering the point lights sphere by a small modifier like 1.1 in addition to the radius.That seemed to only mask the issue for a little bit. When looking at the render targets in RenderDoc going into the lighting pass the render targets seem correct so my guess is that it is my shading code. I am not sure what other details would be beneficial to detailing the problem but if there is something mentioned I will post it. Shader Code Texture2D NormalMap : register( t0 ); Texture2D DiffuseAlbedoMap : register( t1 ); Texture2D SpecularAlbedoMap : register( t2 ); Texture2D PositionMap : register(t3); cbuffer WorldViewProjCB : register( b0 ) { matrix WorldViewProjMatrix; matrix WorldViewMatrix; } cbuffer CameraPosition : register ( b2 ) { float3 CameraPosition; } cbuffer LightInfo : register ( b3 ) { float3 LightPosition; float3 LightColor; float3 LightDirection; float2 SpotLightAngles; float4 LightRange; }; struct VertexShaderInput { float4 Position : POSITION; }; struct VertexShaderOutput { float4 PositionCS : SV_Position; float3 ViewRay : VIEWRAY; }; VertexShaderOutput VertexShaderFunction(in VertexShaderInput input) { VertexShaderOutput output; output.PositionCS = mul( input.Position, WorldViewProjMatrix ); float3 positionVS = mul( input.Position, WorldViewMatrix ).xyz; output.ViewRay = positionVS; return output; } void GetGBufferAttributes(in float2 screenPos, out float3 normal, out float3 position, out float3 diffuseAlbedo, out float3 specularAlbedo, out float specularPower) { int3 sampleIndices = int3(screenPos.xy, 0); normal = NormalMap.Load(sampleIndices).xyz; position = PositionMap.Load(sampleIndices).xyz; diffuseAlbedo = DiffuseAlbedoMap.Load(sampleIndices).xyz; float4 spec = SpecularAlbedoMap.Load(sampleIndices); specularAlbedo = spec.xyz; specularPower = spec.w; } float3 CalcLighting(in float3 normal, in float3 position, in float3 diffuseAlbedo, in float3 specularAlbedo, in float specularPower) { float3 L = 0; float attenuation = 1.0f; L = LightPosition - position; float dist = length(L); attenuation = max(0, 1.0f - (dist / LightRange.x)); L /= dist; float nDotL = saturate(dot(normal, L)); float3 diffuse = nDotL * LightColor * diffuseAlbedo; float3 V = CameraPosition - position; float3 H = normalize( L + V); float3 specular = pow(saturate(dot(normal, H)), specularPower) * LightColor * specularAlbedo.xyz * nDotL; return (diffuse + specular) * attenuation; } float4 PixelShaderFunction( in float4 screenPos : SV_Position ) : SV_Target0 { float3 normal; float3 position; float3 diffuseAlbedo; float3 specularAlbedo; float specularPower; GetGBufferAttributes(screenPos.xy, normal, position, diffuseAlbedo, specularAlbedo, specularPower); float3 lighting = CalcLighting(normal, position, diffuseAlbedo, specularAlbedo, specularPower); return float4(lighting, 1.0f); }
  5. Hope this is the right forum. I'm using Ogre and have rendered a wireframe of triangles by creating manual objects and feeding it vertex and index buffers. My question is, if I want to turn some of the edges of my wire mesh a different color, how would that normally be done? I.e., A triangle having 3 edges where 2 edges are white and I change one edge to green.
  6. 3dBookman

    The 3D book

    After a break of several years the 3D book project is back on. A few short words now on what this blog is about. I have to deliver my wife to the bus station in a few minutes, then a week alone so may have the time then to explain things. But the 3D book is something I started in 014 and put several years into, then the break, now on again. A win32 app with a text window and an ogl window. I just remembered I had something written on this so here it is I write to see if anyone in this community of game developers, programmers, enthusiasts, may be interested in a project I have been developing[off and on] for several years now. So follows a short description of this project, which I call the 3D-Book project. The 3D-Format Reader: A new format of media. Imagine opening a book, the left page is conventional formatted text - on the right page a 3D animation of the subject of the text on the left hand page. The text page with user input from mouse and keyboard, the 3D page with user intput from a game pad. An anatomy text for a future surgeon, with the a beating heart in 3D animation. A children's story adventure book with a 3D fantasy world to enter on the right page. ... Currently 3D-Format Reader consists of a C++ Windows program: Two "child" windows in a main window frame. Two windows: a text-2D rendering window and a 3D-rendering window. The text-2D window, as its' name implies, displays text and 2D graphics; it is programmed using Microsoft's DirectWrite text formatting API and Microsoft's Direct2D API for 2D graphics. The 3D-rendering window uses the OpenGL API. A 3DE-Book page is formatted in one of two possible modes: DW_MODE or GL_MODE. In GL_MODE both windows are shown; the text-2D rendering window is on the left and the 3D OpenGL window is on the right. In DW_MODE, only the text-2D rendering window is shown, the OpenGL window is hidden (Logically it is still there, it has just been given zero width). The 3D-Format Reader reads text files, which consists of the text of the book, control character for the formatting of text, (bold, underline, ...), display of tables, loading of images(.jpg .png ...), and control of 2D and 3D routines. 3D-Reader programming is based on a Model-View-Controller (MVC) architecture. The MVC design is modular: The Controller component handles user input from the operating system , the Model component processes the input, and the View component sends output back to the user on the display. Typical Parent-Child windows programs have multiple "call back" window procedures(winProcs): One for the parent window and one for child window. The MVC model, simplifies message routing by using a call-back window procedure which receives Windows messages for the main window, the text-2D window and the OGL window. A sample MVC program by Song Ho Ahn was used as a template for the 3DE-Reader. Rushed for time now, so a hasty sign off and thanks for reading. ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 8 - 21 -18 I spent the last few days working on procedural mesh generation. First looking to find a bit of code to do what I had in mind. Which begs the question: What did I have in mind? I just wanted a cube mesh generator such that... Requirements Input: An integer n = units from origin to cube face. Output: The vertices for a unit cube centered on the origin. 8n² triangles per cube face. 3 times 8n² verts in clockwise winding order (from the outside of the cube) ready for the rendering pipeline. Screenshot of some cubes generated with the procedural cube mesh generator. That was about it for the output requirements. I did not want to hand code even a single vertex and did not want to load a mesh file. I was sure the code was out there somewhere, but was not finding it. So, a bit reluctantly at first, I started coding the mesh generator. I started enjoying creating this thing and stopped searching for the "out-there-somewhere" code; although still curious how others did this. Analysis First question: How do we number the verts? It would be great to conceive of some concise algorithm to put out the cube face verts all in clockwise order for the outside faces of the cube directly. That seemed beyond me so I plodded along step by step. I decided to just use a simple nested loop to generate the cube face verts and number them in the order they were produced. The hope(and the presumption) was: The loop code was in some order, running thru the x y and z coordinates in order, from -n to +n, therefore the output would be a recognizable pattern. The simple nested loop vert generator did not let us down: It gave us a recognizable pattern, at least for this face. It turned out (as expected now) that all six faces have similar recognizable patterns. Plotting the first row or two of verts you can easily see how to run the rest of the pattern. Plot of the first(of six) cube faces verts output by the vert generator: Input of n: There are (2n+1)² verts per cube face, or 25 verts for n = 2. This is looking at the x = -n face from the outside of the cube. To simplify the math it helps to define s = 2n. Then there are (s + 1)² verts, or 25 for s = 4 s² cells on the face, or 16 for 4 = 2. We are going divide each cell into 2 triangles, so there are 2s² triangles per face, or 32 for s = 4. Second question: What pattern for the triangles? How to number the 2s² = 32 triangles? What we want in the end is a bit of code such that... for triangles T[0] thru T[2s²-1] or T[0] thru T[31]( for n = 4), we have T[N] = f0(N), f1(N), f2(N). Where f0(N) gives the first vertex of T[N] as a function of N. and f1 and f2 give the second and third verts, all in CW winding order looking into the cube of course. Here the choice is a bit arbitrary, but it would seem to make things easier if we can manage to have the order of triangles follow the order of verts to a degree. Numbering the triangles. And now the problem becomes: Look at the triangle vert list, T0 - T8...T31 in the image, and try to discern some pattern leading us to the sought after functions f0(N), f1(N), f2(N) where N is the number of the triangle, 0 thru 2s²-1. This really is the holy grail of this whole effort; then we have T[N] = f0(N), f1(N), f2(N) and that list of verts can be sent directly to the rendering pipeline. Of course we want these functions to work for all six faces and all 12s² triangles to cover the cube. But first let's see if we can just do this one face, 0 thru 2s²-1.. Thru a bit of trial and error the 32 triangles(T0 - T31) were ordered as shown. Now we have an ordered list of the triangles and the verts from our loop. T0 = 0 5 6 T1 = 6 1 0 T2 = 1 6 7 T3 = 7 2 1 T4 = 2 7 8 T5 = 8 3 2 T6 = 3 8 9 T7 = 9 4 3 T8 = 5 10 11 ... T30 T31. If we can find a pattern in the verts on the right side of this list; we can implement it in an algorithm and the rest is just coding. Pattern recognition: It appears T2 = T0 with 1 added to each component T3 = T1 with 1 added to each component In general T[N+2] = T[N] with 1 added to each component, until we come to T8 at least. Also it is hard to recognize a relation between the even and odd triangles,To see what is happening here it helps to look at an image of the generalized case where n can take on any integer value n > 0. Looking for patterns in this generalized(for any n) vert plot we see... We have defined s = 2n. The 4 corner coordinates(+-n,+-n) of the x = - n cube face, one at each corner (+-n,+-n). There are (s+1)² verts/face numbered (0 thru (s+1)² -1). There are 2s² triangles/face numbered (0 thru 2s² -1). They are indicated in red. It's not as bad as it looks iff you break it down. Let's look at the even triangles only and just the 0th vert of these triangles. For any row we see the number of that first vert of the even triangles just increases by one going down the row. We can even try a relation such as T[N].0 = N/2. Here T[N].0 denotes the 0th vert of th Nth triangle. Which works until we have to jump to the next row. Every time we jump a row we T[N+1].0 = T[N].0 + 2 for the first triangle in the higher row. So we need a corrective term to the T[N].0 = N/2 relation that adds 1 every time we jump a row. We can use computer integer division to generate such a term and N/2s is such a term. It only changes value when we jump rows and we get our first function ... f0(N) = N/2 + N/2s. (even triangles) Remember the integer division will discard any remainder from the terms and check this works for the entire cube face, but only for the even triangles. What about the odd triangles? Going back to the triangle vs vert list for the specific case n = 2, s = 4 for the first row; we see for the odd triangles T[N].0 = T[N-1].0 + s + 2. And adding this term, s + 2 to the formula for the even triangle 0th vert we get f0[N] for the odd triangles. f0(N) = N/2 + N/2s + s + 2. (odd triangles) Continuing this somewhat tedious analysis for the remaining functions f1(N), f2(N) we eventually have these relations for the x = -n cube face triangles. for N = 0 thru N = 2s² - 1. defining m = N/2 + N/2s. T[N] = m, m + s + 1, m + s + 2 T[N] = f0(N), f1(N), f2(N). (even N) T[N] = m + s + 2, m + 1, m T[N] = f0'(N), f1'(N), f2'(N) (odd N) So it turns out we have two sets of functions for the verts, fn(N) for the even triangles and fn'(N) for the odd. To recap here; we now have formulae for all the T[N] verts as functions of N and the input parameter n: Input: An integer n = units from origin to cube face. But this is only for the first face x = -n, we have five more faces to determine. So the question is: Do these formulae work for the other faces? And the answer is no they do not, but going through a similar analysis for the remaining face gives similar T[N] = f0(N), f1(N), f2(N) for them. There is still the choice of how to number the remaining triangles and verts on the remaining five faces, and the f0(N), f1(N), f2(N) will depend on the somewhat arbitrary choice of how we do the numbering. For the particular choice of a numbering scheme I ended up making, it became clear how to determine the f0(N), f1(N), f2(N) for the remaining faces. It required making generalized vert plots for the remaining five face similar to the previous image. Then these relation emerged... For face x = -n T[N] N(0 thru 2²-1) we have the f0(N), f1(N), f2(N), even and odd For face x = n T[N] N(2s² thru 4s²-1) add (s+1)² to the x=-n face components and reverse the winding order For face y = -n T[N] N(4s² thru 6s²-1) add 2(s+1)² to the x=-n face components and reverse the winding order For face y = n T[N] N(6s² thru 8s²-1) add 3(s+1)² to the x=-n face components For face z = -n T[N] N(8s²0 thru 10s²-1) add 4(s+1)² to the x=-n face components For face z = n T[N] N(10s²0 thru 12s²-1) add 5(s+1)² to the x=-n face components and reverse the winding order And these are enough to allow us to write explicit expressions for all 12n² triangles for all 6 faces T[N] and what remains to be done is to implement these expression in code. Which turned out to be a much simpler task than finding the f0(N), f1(N), f2(N) and resulted in a surprisingly short bit of code. Implementation I have attempted to make this C++ snippet of code as generic as possible and have removed any dev-platform specific #includes and the like. GLM, a C++ mathematics library for graphics developed by Christophe Riccio is used. It is a header only library. https://github.com/g-truc/glm/releases/download/0.9.9.0/glm-0.9.9.0.zip That is the only outside dependency. // Procedural cube face verticies generator #include <vector> #include <glm/gtc/matrix_transform.hpp> struct Triangle { glm::vec3 vert[3]; // the three verts of the triangle }; /* std::vector<Triangle> cube_Faces(int n) Input: integer 'n'; the units from origin to cube face. Output: vector<Triangle> glTriangle; container for the 12*(2*n)² triangles covering the 6 cube faces. */ std::vector<Triangle> cube_Faces(int n){ size_t number_of_triangles(12*(2*n )*(2*n)); size_t number_of_face_verts(6*(2*n +1 )*(2*n+1)); std::vector<glm::vec3> face_verts(number_of_face_verts); std::vector<Triangle> glTriangle(number_of_triangles); // Generate the 6*(2n +1 )² face verts ------------------------------- int l(0); for(int i = 0; i < 6; i++){ for(int j = -n; j <= n; j++){ for(int k = -n; k <= n; k++){ // Below "ifS" strip out all interior cube verts. if( i == 0){ // do yz faces face_verts[l].x = (float)(-n); //x face_verts[l].y = (float)j; //y face_verts[l].z = (float)k;}//z if( i == 1){ // do yz faces face_verts[l].x = (float)(n); //x face_verts[l].y = (float)j; //y face_verts[l].z = (float)k;}//z if( i == 2){ // do zx faces face_verts[l].x = (float)j; //x face_verts[l].y = (float)(-n); //y face_verts[l].z = (float)k;}//z if( i == 3){ // do zx faces face_verts[l].x = (float)j; //x face_verts[l].y = (float)(n); //y face_verts[l].z = (float)k;}//z if( i == 4){ // do xy faces face_verts[l].x = (float)j; //x face_verts[l].y = (float)k; //y face_verts[l].z = (float)(-n);}//z if( i == 5){ // do xy faces face_verts[l].x = (float)j; //x face_verts[l].y = (float)k; //y face_verts[l].z = (float)(n);}//z l++; } } } // Generate the 12*(2*n)² triangles from the face verts ------- int s = 2*n; int q = 2*s*s; int a = (s+1)*(s+1); int f(0); int r(0); int h(0); for( int N=0; N < number_of_triangles; ){ // triangles already in CW winding if( N < q || N < 5*q && N > 3*q - 1 ){ // do the even indicies f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r; glTriangle[N].vert[0] = face_verts[h]; glTriangle[N].vert[1] = face_verts[s + 1 + h]; glTriangle[N].vert[2] = face_verts[s + 2 + h]; N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r; // do the odd indicies glTriangle[N].vert[0] = face_verts[s + 2 + h]; glTriangle[N].vert[1] = face_verts[ 1 + h]; glTriangle[N].vert[2] = face_verts[h]; N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r; } // triangles needing reverse order for CW winding if( N > 5*q - 1 || N < 3*q && N > q - 1 ){ // do the even indicies glTriangle[N].vert[0] = face_verts[s + 2 + h]; glTriangle[N].vert[1] = face_verts[s + 1 + h]; glTriangle[N].vert[2] = face_verts[h]; N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r; // do the odd indicies glTriangle[N].vert[0] = face_verts[h]; glTriangle[N].vert[1] = face_verts[1 + h]; glTriangle[N].vert[2] = face_verts[s + 2 + h]; N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r; } } // Normalize the cube to side = 1 ------------------------------ for(int i = 0; i < number_of_triangles; i++){ glTriangle[i].vert[0].x = glTriangle[i].vert[0].x/(2.0*(float)n); glTriangle[i].vert[0].y = glTriangle[i].vert[0].y/(2.0*(float)n); glTriangle[i].vert[0].z = glTriangle[i].vert[0].z/(2.0*(float)n); glTriangle[i].vert[1].x = glTriangle[i].vert[1].x/(2.0*(float)n); glTriangle[i].vert[1].y = glTriangle[i].vert[1].y/(2.0*(float)n); glTriangle[i].vert[1].z = glTriangle[i].vert[1].z/(2.0*(float)n); glTriangle[i].vert[2].x = glTriangle[i].vert[2].x/(2.0*(float)n); glTriangle[i].vert[2].y = glTriangle[i].vert[2].y/(2.0*(float)n); glTriangle[i].vert[2].z = glTriangle[i].vert[2].z/(2.0*(float)n); }; return glTriangle; } The rendering was done using OpenGl. // OGL render call to the cube mesh generator - PSUEDOCODE int n(2); int cube_triangle_Count = (12*(2*n)*(2*n)); std::vector<Triangle> cube_Triangles(cube_triangle_Count); cube_Triangles = cube_Faces(n); glBindBuffer(GL_ARRAY_BUFFER, uiVBO[0]); glBufferData(GL_ARRAY_BUFFER, cube_Triangles.size()*sizeof(Triangle), &cube_Triangles[0], GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), 0); glEnableVertexAttribArray(0); glDrawArray(GL_TRIANGLES,0,3*cube_triangle_Count); This just gets the position attribute of the cube face triangle verts; for the color and other attributes there are a couple of options: Use separate GL_ARRAY_BUFFERS for the color and other attributes. Or add attributes to the Triangle struct... struct Triangle { glm::vec3 vert[3]; // the three verts of the triangle attribute1; attribute2; ... }; Screenshot of the spherified cube. What's next? Now that we have the cube mesh what we can do with with it practically unlimited. The first thing I did was turn it into a sphere. Playing with tesselating the cube or sphere or stellating it with different patterns; might do. Ended up trying a few matrix transformations on the cube mesh. These are shown in the image below. These shapes are result short bits of code like the code for the column shape below. //Column for(int i = 0; i < number_of_triangles; i++){ for(int j = 0; j < 3; j++){ if( glTriangle[i].vert[j].y < 0.5f && glTriangle[i].vert[j].y > -0.5f ){ float length_of_v = sqrt((glTriangle[i].vert[j].x * glTriangle[i].vert[j].x) + (glTriangle[i].vert[j].z * glTriangle[i].vert[j].z)); glTriangle[i].vert[j].x = 0.5f*glTriangle[i].vert[j].x/length_of_v; glTriangle[i].vert[j].z = 0.5f*glTriangle[i].vert[j].z/length_of_v; } } } Doing this; the blacksmith at his forge analogy soon presents. The mesh is the ingot, hammer matrices stretch, round and bend it against the fixed geometry of the anvil - coordinate system. I am the smith. Tetrahedron The tetrahedron is the platonic solid with the least number of faces(4), edges(6), and verts(4). In antiquity it was associated with the element of fire due to its' sharp vertices. The algorithm for the tetrahedron mesh was developed in a similar way to the cube, but here it seemed simpler to get a routine for just one face - an equilateral triangle - and use matrix translations and rotations to form the complete tetrahedron. So more like origami or tinsmithing than blacksmithing. Procedural tetrahedron screenshot. The n = 4 and the general case To get an routine for the general case, n an integer > 0, a bit of what I think is known as mathematical induction was used. PSUEDO-CODE Algorithm to generate equilateral triangle face with unit side composed of n² "sub-triangle" in the xy plane. std::vector<Triangle> equilateral(int n){ std::vector<Triangle> tri_Angle(n²); // Create the seed triangle in xy plane . // This is triangle "0" in the image above. // This is in the xy(z=0) plane so all the // tri_Angle.vert[0 thrue n -1 ].z = 0. // We just work with the x and y verts. tri_Angle[all].vert[all].z = 0; // The seed triangle tri_Angle[0].vert[0].x = 0; tri_Angle[0].vert[0].y = 0; tri_Angle[0].vert[1].x = 1/2n; tri_Angle[0].vert[1].y = sin(π/3)/n; tri_Angle[0].vert[2].x = 1/n; tri_Angle[0].vert[2].y = 0; // Build the equilateral triangle face. int count(0); for(int row = 0; row < n; row++){ count = 0; Spin = glmRotateMatrix( π/3, zaxis ); // The magic happens here! for(int i = 2*n*row - row*row; i < 2*n*row - row*row + 2*n - 2*row - 1; i++) { if (count % 2 == 0 ) // Triangle is even in the row - just translate { // more magic. x_Lat = glm_Matrix((count + row)/2n, row*sin(π/3)/n, 0.0f); tri_Angle[i].vert[0] = x_Lat* tri_Angle[0].vert[0]; tri_Angle[i].vert[1] = x_Lat* tri_Angle[0].vert[1]; } else // Triangle is odd in the row - rotate then translate { //and more magic. x_Lat = glm_Matrix((count + row + 1)/2n, row*sin(π/3)/n, 0.0f); tri_Angle[i].vert[0] = x_Lat*Spin*tri_Angle[0].vert[0]; tri_Angle[i].vert[1] = x_Lat*Spin*tri_Angle[0].vert[1]; } } count++; } return tri_Angle; } This is the psuedocode version of the routine which generates the verts for the n² triangles in a face. Getting this algorithm was a bit of a brain drain but looking for patterns in the image of the face allowed it to happen. We use a "seed" triangle, which is triangle 0 on the lower left of the figure. The verts of this one triangle are input; the rest of the n² triangles verts are generated by translating and rotating this seed triangle. Notice: There are n rows, every row has 2 less triangles than the row below. If we number the triangles from 0 to 2n - 2*row - 2, where the rows run 0 to n; the even triangles just need to be translated ... in the x direction by (count + row)/2n where count = their position in the row 0 to 2n - 2*row - 2. in the y direction by row*height. height = height of seed triangle. The odd triangles need to be rotated pi/3 = 60 degrees around the z axis then translated ... in the x direction by (count + row + 1)/2n where count = their position in the row 0 to 2n - 2*row - 2. in the y direction by row*height. height = height of seed triangle. Now we have a single face for the tetrahedron, to join the four faces together we need the angle between the faces called the dihedral angle. Dihedral Angle Each of the five platonic solids has a characteristic called the dihedral angle. This is the angle between the faces. For the cube it is 90 degrees or pi/2 radians. For the tetrahedron it is 70.528779° = arccos(1/3) = atan(2*sqrt(2)); The tetrahedron, with just four faces, is the simplest of the platonic solids. The simplest way I can think of to build it: Start with the four face stacked one on another, edges aligned. Imagine the top three faces each hinged to the bottom face along one edge. Then rotate each face around then hinged edge by arccos(1/3), the dihedral angle. That is the method of the bit of code shown below. vector<Triangle> tetrahedron(int N){ std::vector<Triangle> tetra(4n²); tetra[all].vert[all].z = 0; // The seed triangle tetra[0].vert[0].x = 0; tetra[0].vert[0].y = 0; tetra[0].vert[1].x = 1/2n; tetra[0].vert[1].y = sin(π/3)/n; tetra[0].vert[2].x = 1/n; tetra[0].vert[2].y = 0; // ----- The first face ----- // generate the first equilateral triangle face with unit side // composed of n² "sub-triangle" in the xy(z=0) plane. int count(0); for(int row = 0; row < n; row++) { count = 0; Spin = glmRotateMatrix( π/3, zaxis ); for(int i = 2*n*row - row*row; i < 2*n*row - row*row + 2*n - 2*row - 1; i++) { if (count % 2 == 0 ) // Triangle is even in the row - just translate { x_Lat = glm_Matrix((count + row)/2n, row*sin(π/3)/n, 0.0f); tetra[i].vert[0] = x_Lat* tetra[0].vert[0]; tetra[i].vert[1] = x_Lat* tetra[0].vert[1]; } else // Triangle is odd in the row - rotate then translate { x_Lat = glm_Matrix((count + row + 1)/2n, row*sin(π/3)/n, 0.0f); tetra[i].vert[0] = x_Lat*Spin*tetra[0].vert[0]; tetra[i].vert[1] = x_Lat*Spin*tetra[0].vert[1]; } } count++; } // ----- The second face ----- // generate the second equilateral face from the first // by rotating around the X axis by the dihedral angle. float tetra_Dihedral = atan(2*sqrt(2)); Spin = glmRotateMatrix( -tetra_Dihedral, xaxis ); //just rotate for(int i = 0; i < n²; i++) { for(int j = 0; j < 3; j++) { tetra[n² + i].vert[j] = Spin*tetra[i].vert[j]; } } //The rotation gives CCW verts so need need to make them CW again for(int i = n²; i < 2n²; i++) { swap(tetra[i].vert[0] ---- with --- tetra[i].vert[2]; } // ----- The third face ----- // For the second face we rotated the first triangle around its' // base on the X - axis. For the third face we rotate the first // triangle around its' edge along the vector ( 0.5, 0.866025, 0.0 ). Spin = glmRotateMatrix( tetra_Dihedral ,glm::vec3(0.5f,0.866025f,0.0f)); for(int i = 0; i < n²; i++) { for(int j = 0; j < 3; j++) { tetra[2n² + i].vert[j] = Spin*tetra[i].vert[j]; } } //need to make it CW again for(int i = 2n²; i < 3n²; i++) { swap(tetra[i].vert[0] ---- with --- tetra[i].vert[2]; } // ----- The forth face ----- // For the forth face we first translate the original face along the // X axis so it right edge vector (-0.5f, 0.866025f, 0.0f) passes thru the origin. // Then we rotate the first triangle around the that vector by the dihedral angle. x_Lat = glm::translate( glm::vec3(-1.0f, 0.0f, 0.0f)); Spin = glmRotateMatrix( -tetra_Dihedral, glm::vec3(-0.5f,0.866025f,0.0f)); for(int i = 0; i < n²; i++) { for(int j = 0; j < 3; j++) { tetra[3n² + i].vert[j] = Spin*x_Lat*tetra[i].vert[j]; } } //need to make it CW again for(int i = 3n²; i < 4n²; i++) { swap(tetra[i].vert[0] ---- with --- tetra[i].vert[2]; } // We now have the complete tetrahedron, tetra(4n²), but its' base // is not horizontal so let's make is so. // put the base in the xz plane // rotate 90 - dihedral angle around X axis. Spin = glm::rotate( tetra_Dihedral - half_PI, xaxis); for(int i = 0; i < 4n²; i++) { for(int j = 0; j < 3; j++) { tetra[i].vert[j] = Spin*tetra[i].vert[j]; } } // We now have the complete tetrahedron, tetra(4n²), sitting with its' // base on the xz(y=0) plane, let's put its' center at the origin. // For this we need another Platonic Solid attribute: The radius of // the tetrahedrons circumscribed sphere which is sqrt(3/8). So the // center of the tet is this vertical distance down from its' apex. // To put the center at the origin we need to translate down this // distance along the Y axis. We need also to xlat along the Z axis // by 1/2(sqrt(3)) = 0.28867; the distance from the center of a face // to the center of a side. // Finally we need to center along the X axis( xlat -.5) x_Lat = glm::translate( glm::vec3(-0.5f, -sqrt(3/8), sqrt(3)/2); for(int i = 0; i < 4n²; i++) { for(int j = 0; j < 3; j++) { tetra[i].vert[j] = x_Lat*tetra[i].vert[j]; } } return tetra; } Notes: Oops: Left out std::vector<Triangle> tri_Angles(4*n*n); Should be the first line of the function body! Corrections to the corrections: First line of function definition vector<Triangle> tetrahedron(int N){ should be vector<Triangle> tetrahedron(int n){ Those last two for loops could and probably should be combined to do a translate*rotate*triangle in one statement, but I have not tried it. All distances are for a tetrahedron with unit side. The sign of the dihedral angle in the rotations was usually determined by trial and error. I.e.; I tried one sign, compiled the code and rendered the tet. If it was wrong I just reversed the sign. The end result is a tetrahedron with its' center at the origin, its' base in the xz plane, and one edge parallel to the X axis. Of the five platonic solids; three (tetrahedron, octahedron, icosahedron) are composed of equilateral triangle faces. One of square faces (cube). And one of pentagon faces (dodecahedron). Two tetrahedrons fit nicely in a cube. 11-16-18: Corrections to code blocks for equilateral triangle and tetrahedron. 11-18-18: More corrections. Icosahedron Two faces = Icosahedron Petal Five petals in this flower = 10 faces = half of the icosahedron 12-5-18 Understanding the icosahedrons' 3d form via 2d images is difficult; we need to make a small, palm sized, 3d model. It takes nineteen paper triangles and some tape. The vertices of five equilateral triangles must come together at each vertex of the icosahedron. The icosahedron has 20 faces and 12 verts, but leaving one face off the model allows us to look in side. Besides; when where done we'll have a neat little icosahedron basket. You don't really need to make a model to code the icosahedron; but it helped me to see some properties which simplified its' construction. Symmetries are important to the mathematician and perhaps even more so to the physicist. They say something has a certain symmetry if you perform a certain operation on it and the world remains unchanged. Unchanged in the sense that you can not even detect something has been done to it. Example: Rotate a square 90 degrees around its' center in the plane. The square has that type of rotational symmetry. The square also has an inversion symmetry; if you take every point on the square and invert it through the origin you end up with the same square you started with. Inversion is simply negating all the coordinates. The center must be at the origin of course. This is true for the cube, but not for the tetrahedron. Symmetries simplify the construction (coding) of an object. Going back to the cube; it might have been easier to do three faces and then just invert them thru the origin to get the other three. For the tetrahedron simple inversion is not a symmetry, but I am pretty sure inversion together with a rotation is. If so; we could do two faces and then perform an inversion - rotation on them in one step. And inversion in Cartesian coordinates just means to negate all the verts - easy! Toying with our icosahedron model; holding it gently with our thumb on one vertex and our middle finger on the opposite vertex, lazily twirling it around an imaginary axis through those two vertices; we are struck with a thought: We are toying with our icoshedron model twirling it around an axis through - Eureka! - two opposite vertices: The icosahedron has inversion symmetry. This is great - our work has just been cut in half. We can code half of the icosahedrons verts and just invert(negate) to get the rest. Thank you inversion symmetry. But let's not stop now, we are on a roll (no pun intended); lets see if we can find more symmetries to make our work easier. Looking intently; holding our model as before, but still, not rotating. Then slowly rotating about the axis we see another symmetry. After one fifth of a revolution(2π/5 radians) the universe is the looks the same as when we started rotating it. The icosahedron has a 2π/5 rotational symmerty. Can we use this to cut our work load? You bet we can. First we need to clear up a few points about something central to our construction efforts: The axis of symmetry. (Sorry, the puns just keep coming.) An axis of symmetry is a line passing thru two opposite vertices and the center of the icosahedron. The icosahedron has six of them: We only need one. We will use the Z axis. Dihedral angle: To be precise, it is the angle between the normals of two adjacent faces. The images: Looking at the images we see a flower shape with five "petals". A petals is just two faces joined along a side. The angle between the two petal faces is the icosa's dihedral angle; arccos(- √5/3) radians. Five petals make a "flower" , which is ten faces, so it is half of the icosahedron. Once we have five petals joined to make this flower, we just copy/invert all its' verts to get the other half: We have our icosahedron. The Plan: Refer to the figures 1.) Make a petal. 2.) Attach one tip of the petal the axis of symmetry. (Oriented properly of course.) 3.) Copy/rotate the petal around the axis of symmetry by 2π/5 radians four times to get five petals = a flower. We are using the 2π/5 radians rotational symmetry here. 4.) Copy/invert( r -> -r ) our five-petal-ten-face flower to get our 20 face icosahedron. Using inversion symmetry here. So just four steps; sounds simple enough. Each step has its own steps of course, but they are mostly intuitive common sense things we must do to get the result. Constants: Before we get to the code we need four constants. 1.) The dihedral angle between two faces, the dihedral_angle. dihedral_angle. = arccos(- √5/3) = 46.06322 radians = 138.18969°. 2.) The angle between the Z axis and the normal of a face of a petal at the vertex. 0.652351 radians 3.) The radius of a circumscribed sphere(A sphere that touches all 12 verts). In other words the distance from the icosahedron center to a vertex. Also called the circumradius. R = sin(2π/5). 4.) The rotational symmetry: 2π/5 radians Let's not do a blow by blow, or should say, a bend by bend, description of the code. If a picture is worth a thousand words, it seems safe to assume an animated 3D image is worth even more. I suggest we compile the code and render to the display step by step. In fact this is how the code was developed; with a projection matrix and a rotation around the Z axis. Compile - Render the first face: F0. " " the first petal: P0 from F0 and F1. " " the second petal P1. " " the third petal P2. " " the fourth petal P3. " " the fifth petal P4. We now have the flower. Compile - Render the inversion of the flower. Done. The icosahedron psuedocode. struct Triangle { glm::vec3 vert[3]; // the three verts of the triangle }; //PSUEDOCODE ICOSAHEDRON /* input: integer n - number of triangles along icosahedron edge. output: std::vector<Triangle> icosahedron - mesh with 20n² triangles. */ std::vector<Triangle> icosahedron( int n ){ const float dihedral_Angle = acos(-(sqrt(5.0f)/3.0f)); const float dihedral_Comp = π - dihedral_Angle; std::vector<Triangle> T_icosahedron(20n²); // Create the seed triangle T. Triangle T; T.vert[0].x = 0; T.vert[0].y = 0; T.vert[0].z = 0; T.vert[1].x = 1/2n; T.vert[1].y = sin(π/3); T.vert[1].z = 0; T.vert[2].x = 1/n; T.vert[2].y = 0; T.vert[2].z = 0; // ----- F0 ----- // Create the first face; "F0" in the xy(z=0) plane // from the seed triangle T. int count(0); for(int row = 0; row < n; row++){ count = 0; for(int i = 2*n*row - row*row; i < 2*n*row - row*row + 2*n - 2*row - 1; i++){ if (count % 2 == 0 ){ // Triangle is even in the row - just translate . x_Lat = glm::translate(count+row)/2n, row*sin(π/3), 0); for(int j = 0; j < 3; j++){ T_icosahedron[i].vert[j] = x_Lat*T.vert[j]; } } else{ // Triangle is odd in the row - rotate then translate. x_Lat = glm::translate( glm::vec3((count+1+row)/2n, row*sin(π/3), 0)); Spin = glm::rotate( π/3, zaxis ); for(int j = 0; j < 3; j++){ T_icosahedron[i].vert[j] = x_Lat*Spin*T.vert[j]; } } count++; } } // At this point comment out the rest of the code, // return T_icosahedron; // Compile and render F0 to the display. // ----- P0 ----- // Create the first petal "P0" in the xy(z=0) plane. glm::vec3 axis(0.5f, sin(π/3), 0.0f); Spin = glm::rotate( π/3, zaxis ); //just rotate Spin2 = glm::rotate( -dihedral_Comp, axis ); for(int i = 0; i < n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[n² + i].vert[i] = Spin2*Spin*T_icosahedron[i].vert[j]; } } // xlate P0 by -1.0 along x and bend down by epsilon from the xy plane // epsilon is the angle we want between the Z axis and the normal of F0. // epsilon = 0.6523581f; x_Lat = glm::translate( glm::vec3(-1.0f, 0.0f, 0.0f)); Spin2 = glm::rotate( glm::mat4(1.0), -π/3, zaxis ); Spin = glm::rotate( glm::mat4(1.0), -epsilon, xaxis ); //just rotate for(int i = 0; i < 2n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i].vert[j] = Spin*Spin2**x_Lat*T_icosahedron[i].vert[j]; } } // At this point comment out the rest of the code, // return T_icosahedron; // Compile and render P0 to the display. // Create P1 from the P0 verts, rotate 2π/5 around z then Spin = glm::rotate( 2π/5, zaxis ); //just rotate for(int i = 0; i < 2n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i+2n²].vert[j] = Spin*T_icosahedron[i].vert[j]; } } // At this point comment out the rest of the code, // return T_icosahedron; // Compile and render P0 - P1 to the display. // Create P2 thru P4 from P0 verts: rotate around z: // 2*2π/5 for P2, 3*2π/5 for P3 and finally 4*2π/5 for P4 // P2 Spin = glm::rotate( 2*2π/5, zaxis ); //just rotate for(int i = 0; i < 2n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i+4n²].vert[j] = Spin*T_icosahedron[i].vert[j]; } } // P3 Spin = glm::rotate( 3*2π/5, zaxis ); //just rotate for(int i = 0; i < 2n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i+6n²].vert[j] = tSpin*T_icosahedron[i].vert[j]; } } // P4 Spin = glm::rotate( 4*2π/5, zaxis ); //just rotate for(int i = 0; i < 2n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i+8n²].vert[j] = Spin*T_icosahedron[i].vert[j]; } } // At this point we should have the full flower. // Comment out the rest of the code, // return T_icosahedron; // Compile and render P0 thru P4 to the display. // Move everthing up along z to put the icosahedron center at the origin. // radius of circumscribed sphere = sin(2π/5), for face side = 1. x_Lat = glm::translate( glm::vec3(0, 0, sin(2π/5)); for(int i = 0; i < 10n²; i++){ for(int j = 0; j < 3; j++){ T_icosahedron[i].vert[j] = x_Lat*T_icosahedron[i].vert[j]; } } // invert all the verts and reverse for cw winding // this creates the other half of the icosahedron from the first 10 triangles for(int i = 0; i < 10n²; i++){ for(int j = 0; j < 3; j++){ // invert T_icosahedron[i+10n²].vert[j].x = -T_icosahedron[i].vert[j].x; T_icosahedron[i+10n²].vert[j].y = -T_icosahedron[i].vert[j].y; T_icosahedron[i+10n²].vert[j].z = -T_icosahedron[i].vert[j].z; } // Swap verts 0 and 2 to get back to CW winding. hold = T_icosahedron[i+10n²].vert[0];// reverse T_icosahedron[i+10n²].vert[0] = T_icosahedron[i+10*n²].vert[2]; T_icosahedron[i+10n²].vert[2] = hold; } return T_icosahedron; // Spherify - uncomment the code below to spherify the icosahedron /* for(int i = 0; i < 20n²; i++){ for(int j = 0; j < 3; j++){ float length_of_v = sqrt( (T_icosahedron[i].vert[j].x * T_icosahedron[i].vert[j].x) + (T_icosahedron[i].vert[j].y * T_icosahedron[i].vert[j].y) + (T_icosahedron[i].vert[j].z * T_icosahedron[i].vert[j].z)); T_icosahedron[i].vert[j].x = T_icosahedron[i].vert[j].x/length_of_v; T_icosahedron[i].vert[j].y = T_icosahedron[i].vert[j].y/length_of_v; T_icosahedron[i].vert[j].z = T_icosahedron[i].vert[j].z/length_of_v; } } */ return T_icosahedron; }
  7. Atum engine is a newcomer in a row of game engines. Most game engines focus on render techniques in features list. The main task of Atum is to deliver the best toolset, that’s why, as I hope, Atum will be a good light weighted alternative to Unity for indie games. Atum already has fully workable editor that has an ability to play test edited scene. All system code has simple ideas behind them and focuses on easy to use functionality. That’s why code is minimized as much as possible. All source can be found here - https://github.com/ENgineE777/Atum In case you have questions related to Atum engine do not hesitate to contact me via email enginee777@gmail.com Currently the engine have follow features: - PC, Android and iOS platforms are supported - Scene Editor with ability to play test edited scene - Powerful system for binding properties into the editor - Powerful assets system - Track based editor for creation of animated objects - Sprite Editor - Render system that supports DX11 and OpenGL - UI system bassed on assets - Script system based on angel script - Controls system based on aliases - Font system based on stb_truetype.h - Support of PhysX 3.0, there are samples in repo that's using physics - Network code which allows to create server/clinet; there is some code in repo which allows
  8. For my test case I have a sphere sliding across a horizontal plane that will eventually come in contact with a vertical plane. I have figured out the correct way to deal with a moving sphere to plane for either sliding to resting contact or bouncing off of it. However, it was always with only one rigid body object to one static collision. Now there are two static collision objects. The way the static collisions are added are 1) Vertical plane 2) Horizontal plane. As a result it find the collision with the horizontal plane to slide across it (index 1) but it will find collision with the vertical plane (index 0) once it reaches it. With the logic I have below, it will never consider the collision with the vertical plane. How should I ensure that it will respond to collision with it? float fAccumulator = 0.0f; while(fAccumulator < fElapsedTime && mRigidBodyObjects.size() > 0) { F32 left_time = fElapsedTime - fAccumulator; for(unsigned int i = 0; i < mRigidBodyObjects.size(); ++i) { int j1 = -1; RigidBodyCollisionResult crFirstCollisionResult; crFirstCollisionResult.fCollisionTime = FLT_MAX; RigidBodyCollisionResult crCollisionResult; for(unsigned int j = 0; j < mStaticObjects.size(); ++j) { crCollisionResult = mRigidBodySolver.Collide(mRigidBodyObjects[i], mStaticObjects[j], left_time); if(crCollisionResult.enCollisionState == WILL_COLLIDE) { if(crCollisionResult.fCollisionTime <= crFirstCollisionResult.fCollisionTime) { crFirstCollisionResult = crCollisionResult; j1 = j; } } else if(crCollisionResult.enCollisionState == HAS_COLLISION || crCollisionResult.enCollisionState == RESTING_CONTACT) { crFirstCollisionResult = crCollisionResult; j1 = j; } } if(crCollisionResult.enCollisionState == WILL_COLLIDE || crCollisionResult.enCollisionState == NO_COLLISION) { mRigidBodyObjects[i]->ApplyGravity(); } if(j1 != -1) { if(crFirstCollisionResult.enCollisionState == WILL_COLLIDE && crFirstCollisionResult.fCollisionTime <= fElapsedTime) { mRigidBodyObjects[i]->Update(crFirstCollisionResult.fCollisionTime); mRigidBodySolver.HandleCollisionReponse(mRigidBodyObjects[i], mStaticObjects[j1], crFirstCollisionResult, crFirstCollisionResult.fCollisionTime); fAccumulator += crFirstCollisionResult.fCollisionTime; } else if(crFirstCollisionResult.enCollisionState == HAS_COLLISION || crFirstCollisionResult.enCollisionState == RESTING_CONTACT) { mRigidBodySolver.HandleCollisionReponse(mRigidBodyObjects[i], mStaticObjects[j1], crFirstCollisionResult, left_time); mRigidBodyObjects[i]->Update(left_time); fAccumulator += left_time; } else { mRigidBodySolver.HandleCollisionReponse(mRigidBodyObjects[i], mStaticObjects[j1], crFirstCollisionResult, left_time); mRigidBodyObjects[i]->Update(left_time); fAccumulator += left_time; } } else { mRigidBodyObjects[i]->Update(left_time); fAccumulator = fElapsedTime; } } }
  9. Hello! For more that two years I'm making my 2D sandbox adventure RPG with generated and almost fully destructible world. Recently the project become open-source and detailed description can be found here - https://github.com/mrDIMAS/TheDwarfAdventure Here is gameplay video (very short) with core mechanics: Latest stable build can be found here - https://github.com/mrDIMAS/TheDwarfAdventure/releases I need some feedback and if you found a bug - create an issue - this will help me a lot.
  10. I'm trying to write a game on OpenGL using C++. From third-party libraries for creating windows (widgets?) Inside OpenGL, I was able to add ImGui to my project, create a window and attach some functions to it. But I did not find information like changing the style of this window. Specifically, in this situation, I need to create the starting window of the game (start the game, settings, exit, etc.) and create in-game windows (inventory, character menu, minimap, chat, etc.). I heard about Qt, but given the size they require, my program will weigh 3-4 times more than we would like. In addition, I do not need any super high-quality graphics and a large set of visualization capabilities. I would like to understand what my program consists of and have a set of basic concepts about how this is implemented. Could you advise: is there a similar library with the ability to create and edit the style of in-game windows (maybe in ImGui this function is still there?) with open source code in C++?
  11. Hello ! I have two gpu on my computer, one from my cpu and another one from my graphic card. I am trying to use the opengl/opencl interop capabilities. But I am stuck at the creation of the opencl context, I don't know how to identify which platform / device of the two one is used by opengl. In the above code, which fonction should I use in the test "DEVICE MATCHING OPENGL ONE" to test if the device is the one used by OpenGL, or what should I do to test if the platform_id is the good one ? sf::ContextSettings settings; settings.depthBits = 24; settings.stencilBits = 8; settings.antialiasingLevel = 2; sf::Window window(sf::VideoMode(2048, 1024), "GAME", sf::Style::Fullscreen, settings); glewInit(); cl_platform_id platform_ids[16] = { NULL }; cl_device_id device_id = NULL; cl_uint ret_num_devices; cl_uint ret_num_platforms; cl_platform_id platform_id = 0; cl_int ret = clGetPlatformIDs(_countof(platform_ids), platform_ids, &ret_num_platforms); size_t n = 0; cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties) platform_id, 0 }; for (size_t i = 0; i < ret_num_platforms; ++i) { platform_id = platform_ids[i]; cl_device_id curDevices_id[16]; ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, _countof(curDevices_id), curDevices_id, &ret_num_devices); for (cl_uint nDevices = 0; nDevices < ret_num_devices; ++nDevices) { cl_device_id curDevice_id = curDevices_id[nDevices]; clGetGLContextInfoKHR_fn clGetGLContextInfo = reinterpret_cast<clGetGLContextInfoKHR_fn> (clGetExtensionFunctionAddressForPlatform( platform_id, "clGetGLContextInfoKHR")); if (clGetGLContextInfo) { cl_device_id clGLDevice = 0; props[5] = reinterpret_cast<cl_context_properties>(platform_id); clGetGLContextInfo(props, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(clGLDevice), &clGLDevice, &n); if (DEVICE MATCHING OPENGL ONE) { device_id = clGLDevice; } } } if (device_id) { break; } } cl_context context = clCreateContext(props, 1, &device_id, NULL, NULL, &ret); Thanks for your future help!
  12. Well Rogue is a unique multiplayer shooter that allows you to semi customise your own powers & create your own weapons.Wether you create a handgun or something else, it’s up to you and what gun you create that could turn the tide of war in your favour.WHAT GAMEMODES WILL THERE BE?: Well here are a list of them (TO BE CHANGED) Free For All, 20 players battle it out to see who will get the most kills Team Capture,10 V 10 will battle it out to capture an area War, a massive 50v50 fight for an area, (or 100v100 not yet decided) Hop into your vehicles, get your Grenade Ready. At the moment my main focus is on assembling a strong team that can work together to make something great. The game will be built on the unreal engine. The 2 main focuses on recruiting are 3D Artists/Animators (animators are important) and UE4 Programmers. if interested contact me on discord at RioIsntHere#4207
  13. Hi, I wrote my animation importer for Direct3D 11 using assimp and an FBX file exported from Blender and everything is working after I flipped the axes such that Y=Z and Z=-Y. I basically multiplied BoneOffsetMatrix = BoneOffsetMatrix * FlipMatrix and GlobalInverseMatrix = Inverse(FlipMatrix) * GlobalInverseMatrix where FlipMatrix = ( 1,0,0,0, 0,0,1,0, 0,-1,0,0, 0,0,0,1 ) (matrices in row-major format). But why do I have to? There are tutorials (for OpenGL, but still) where this worked fine without this step. Is it a setting in Blender that is wrong? I am applying those transformations to my own vertices, so I'm not using the ones provided in the FBX file. But even if I did, those would be wrong without flipping the axes after the global inverse transformation. Even though it is working, I want to give my editor to modders of my game, so I can't be sure that it works at their ends since I had to add a step that should not be required according to the documentation. Cheers, Magogan
  14. dimi309

    Frogger GameDev Challenge 2018

    This is just a brief note on my participation to the challenge. The game developed to that end is a 3D remake of the original frogger concept and has been made available as an open source product under the BSD (3 clause) license. It is a small casual game, in which the player is controlling a frog. The frog has to get to the other side of a road, avoiding passing cars, and a pond in which wooden planks float. The cars can crush the frog and, if it fails to use the planks when crossing the pond, it drowns. As a side-note I have always wondered why this is so since the 80s. It is an amphibian after all... The game works on Windows, MacOS and Linux and I have used my own small3d framework to develop it, in C++. small3d is also provided as an open source, BSD licensed project. This is not a masterpiece, but I think it's ok for something developed over the course of a couple of weeks. I only noticed the gamedev.net challenge when an announcement was made about the extension to the deadline for submissions.
  15. phil67rpg

    1942 plane game

    Well I have a peculiar problem. When I set my global variable screen=0.0f and I put my drawcollision_one() function in my display function it only draws a static collision sprite. However when I set my screen=0.0001f and I put my drawcollision_one() in my display function it draws an animated collision sprite. Also when I use my screen=-0.0f variable and I put my drawcollision_one() function in my collision detection function it draws a static collision sprite. However when I use my screen=0.0001f variable it does not draw anything when the drawcollision_one() function is in my collision detection function. What I want is to draw the animated collision sprite when the collision detection function is used. Let me know if you need further explanation.I am using freeglut 3.0.0 and SOIL in my program.
  16. How can I write and read a `std::vector<std::string>` into binary file in C or C++? Withour using an external library.
  17. Hello, I have recently joined a game company, and we are using an own, old DX9 engine. It renders meshes with software, which is not only slow, but also got broken with some latest windows updates. The current code is; auto vb = _getVB(); auto ib = _getIB(); if (_node) ::device->SetStreamSource( 0, vb, 0, sizeof(AMVERTEX)); else ::device->SetStreamSource( 0, vb, 0, sizeof(MVERTEX)); ::device->SetIndices(ib); if(_node) ::device->SetSoftwareVertexProcessing(TRUE); if (_node) ::device->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, m_dwNodeCount ? TRUE : FALSE); ::device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, m_vbIndex, 0, m_data->m_count, m_meshIB[index]->_ib->m_dwPOS, m_mesh[index]->_count / 3); ::device->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); so the question is, what's the best way to do this correctly? When I don't use the software processing, it renders just let's say 1/10 of the whole mesh, rest of it are just lines going throughout the whole screen. It uses the _node to determine if there are nodes for animation. I'm kinda new to D3D9 aswell. So, how exactly do I approach this method of rendering? The animations are then done with WORLDMATRIX(i), so I guess that's the problem, since meshes without animations work without problems. So what do you think that would be the best approach to this, is it shaders? Because I can't really imagine me writing one for this I mean because of time, so if any of you know any solution that could work, I would be thankful. If any of you could help me, I could even pay you some small money. Thanks a lot.
  18. I'm staring programming stream today: twitch.tv/ibob_code Target audience is people with some programming experience (who know what are variables, loops, functions, etc...), though not necessarily any with C++. We'll be starting from scratch. I'll do at least 5 streams and then decide what to do. Let's see where this takes me.
  19. komires

    Matali Physics 4.3 Released

    We are pleased to announce the release of Matali Physics 4.3. The latest version introduces significant changes in support for DirectX 12 and Vulkan. Introduced changes equate the use of DirectX 12 and Vulkan with DirectX 11 and OpenGL respectively, significantly reducing the costs associated with application of low-level graphics APIs. From version 4.3, we recommend using DirectX 12 and Vulkan in projects that are developed in the Matali Physics environment. What is Matali Physics? Matali Physics is an advanced, multi-platform, high-performance 3d physics engine intended for games, virtual reality and physics-based simulations. Matali Physics and add-ons form physics environment which provides complex physical simulation and physics-based modeling of objects both real and imagined. Main benefits of using Matali Physics: Stable, high-performance solution supplied together with the rich set of add-ons for all major mobile and desktop platforms (both 32 and 64 bit) Advanced samples ready to use in your own games New features on request Dedicated technical support Regular updates and fixes You can find out more information on www.mataliphysics.com View full story
  20. komires

    Matali Physics 4.3 Released

    We are pleased to announce the release of Matali Physics 4.3. The latest version introduces significant changes in support for DirectX 12 and Vulkan. Introduced changes equate the use of DirectX 12 and Vulkan with DirectX 11 and OpenGL respectively, significantly reducing the costs associated with application of low-level graphics APIs. From version 4.3, we recommend using DirectX 12 and Vulkan in projects that are developed in the Matali Physics environment. What is Matali Physics? Matali Physics is an advanced, multi-platform, high-performance 3d physics engine intended for games, virtual reality and physics-based simulations. Matali Physics and add-ons form physics environment which provides complex physical simulation and physics-based modeling of objects both real and imagined. Main benefits of using Matali Physics: Stable, high-performance solution supplied together with the rich set of add-ons for all major mobile and desktop platforms (both 32 and 64 bit) Advanced samples ready to use in your own games New features on request Dedicated technical support Regular updates and fixes You can find out more information on www.mataliphysics.com
  21. Hi, i would like to learn how to code Tetris, or, well, at least something that looks like Tetris. I would like to start my project in C++ Builder ( Embarcadero ). As a beginner, i did what i could. I made the windows with everything that passed through my mind: Buttons, images, sound, collect data from player like name, etc etc. I did my researches and i studied Tetris algorithm but i see no connection on how to apply it in C++ Builder. Where should i start with the graphics? What should blocks be made of? What should the game "stage" be made of? Some people told me to use a StringGrid and to color the cells, other told me to use a matrix, but i don't really know where and how to start. I honestly want to create my own classes and work with them. But i don't even know how to create a class in C++ Builder. I know what a class is, i use them in C++ with the console, but i don't understand the concept of C++ Builder and how it works with classes. There is so much auto generated code and it is so different from what i'm used to ( for 4 years i have only programmed in console, i'm a student, by the way ). For example, are buttons and labels and etc classes? If yes, where i can see their code to get inspired? How can i create my own class? I'm thinking about making a class for each piece, or a class for all of them, but i think that is better to make a class for each individual piece because they are different, right? But first i would really like find out how does classes work in C++ Builder and how to create my own. Thank you for your time and i wish you all good ! P.S: Sorry for my bad English.
  22. Hi, I started implementing 2D board game. I have concept of how to write rules, controlls etc, but i dont want to write another all-in-app. So i decided to do it "right". I divided my code into reuseable modules - ResourceManager, Renderer, Core, Math (for now). All modules use SDL2. ResourceManager(RM) - loads textures, audio etc without duplicating them in memory. Resources are gathered in TextureResource, AudioResource (...) objects, handled by std::shared_ptr. For textures I have prepared Texture class that wraps SDL_Texture and I RM serves this Texture objs for Core module. Core - The main game module, contains game loop, gameobject / component implementation and event handling. Core requests for data from RM and sends them to right components. Renderer - Creates window and knows about render range (in core represented by camera). Takes info about texture, position, rotation and scale to render images (just this for now). Its time for my questions: is this architecture good? After I end this board game I want to extend renderer module for example for rendering 3D objects. Loading resources while ingame is good idea? I mean single textures, models, sounds etc. As I said, for handling resources I am using shared_ptr, is it good cleaning cache every (for example) 3 minutes? By cleaning i mean removing not used resources (counter =1). And the hardest thing for me right now - take a look at this flow: Core create a T1 token Component Renderer2D is connected to T1. Core requests a texture /textures/T1.png from RM. RM checks if /textures/T1.png is in map, if not, loads it. RM returns a std::shared_ptr<Texture> to Core. Core assign texture to T1 Renderer2D component. Now i want to pass this object to renderer. But I wont pass all gameObjects and checks which have renderer2D component (i also cant, because only Core know what is gameObject and component). So i had an idea: I can create Renderable interface (in Renderer module) and inherit from it in the renderer2D component. Renderable will contain only pointers to position data. Now i am able to pass renderer2D component pointer to Renderer and register it. Is this good way to handle this? Or im overcomplicating things? If point above is right I had last question - registering object in Renderer module. I dont want to iterate over all objects and check if I can render them (if they are in render range). I wanted to place them in "buckets" of - for example - screen size. Now calculating collisions should be faster - i would do this only for objects in adjacent buckets. But for 2D game i have to render objects in correct order using Z index. Objects have to be placed in correct bucket first, then sorted by Z in range of bucket. But now i have problem with unregistering objects from Renderer module. I think I got lost somewhere in this place... Maybe You can help me? Of course it this is correct way to handle this problem. I would love to read your comments and tips about what can I do better or how can i solve my problems. If i didnt mention something but You see something in my approach, write boldly, I will gladly read all Your tips :).
  23. Sol_HSA

    SoLoud Audio Engine 20181119 Release

    SoLoud audio engine 2018119 has been released, and available at http://soloud-audio.com SoLoud is an easy to use, free, portable c/c++ audio engine for games. First release after 2 year burnout hiatus Hilights: FLAC, MP3 and various wav file formats through dr_flac, dr_mp3 and dr_wav Split SDL and SDL2 dll backends due to SDL2 doing stupid things unless told not to Removed modplug, added libmodplug dll interface Loop point support for all audio sources Wav files can now load from raw data Multi-speaker support Queues Many new small examples Piano demo now has padsynth Sanity test: over 200 tests to check if changes break playback Asserts playBackground helper interface to play audio without panning countAudioSource call to see how many instances of an audio source are playing PS Vita homebrew platform support Wave shaper, robotize filters Added more options to speech synth playback Removed many dynamic allocations Switched FFT implementations (again) Countless bug fixes and tweaks View full story
  24. Sol_HSA

    SoLoud Audio Engine 20181119 Release

    SoLoud audio engine 2018119 has been released, and available at http://soloud-audio.com SoLoud is an easy to use, free, portable c/c++ audio engine for games. First release after 2 year burnout hiatus Hilights: FLAC, MP3 and various wav file formats through dr_flac, dr_mp3 and dr_wav Split SDL and SDL2 dll backends due to SDL2 doing stupid things unless told not to Removed modplug, added libmodplug dll interface Loop point support for all audio sources Wav files can now load from raw data Multi-speaker support Queues Many new small examples Piano demo now has padsynth Sanity test: over 200 tests to check if changes break playback Asserts playBackground helper interface to play audio without panning countAudioSource call to see how many instances of an audio source are playing PS Vita homebrew platform support Wave shaper, robotize filters Added more options to speech synth playback Removed many dynamic allocations Switched FFT implementations (again) Countless bug fixes and tweaks
  25. I'm creating a 2D game engine using Vulkan. I've been looking at how to draw different textures (each GameObject can contain its own texture and can be different from others). In OpenGL you call glBindTexture and in vulkan I have seen that there are people who say that you can create a descriptor for each texture and call vkCmdBindDescriptorSets for each. But I have read that doing this has a high cost. The way I'm doing it is to use only 1 descriptor for the Sampler2D and use a VkDescriptorImageInfo vector where I add each VkDescriptorImageInfo for each texture and assign the vector in pImageInfo. VkWriteDescriptorSet samplerDescriptorSet; samplerDescriptorSet.pNext = NULL; samplerDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; samplerDescriptorSet.dstSet = descriptorSets[i]; samplerDescriptorSet.dstBinding = 1; samplerDescriptorSet.dstArrayElement = 0; samplerDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; samplerDescriptorSet.descriptorCount = static_cast<uint32_t>(samplerDescriptors.size()); samplerDescriptorSet.pImageInfo = samplerDescriptors.data(); //samplerDescriptors is the vector Using this, I can skip creating and binding a descriptor for each texture but now I need an array of Samplers in fragment shader. I can't use sampler2DArray because each texture have different sizes so I decided to use an array of Samplers2D (Sampler2D textures[n]). The problem with this is that I don't want to set a max number of textures to use. I found a way to do it dynamically using: #extension GL_EXT_nonuniform_qualifier : enable layout(binding = 1) uniform sampler2D texSampler[]; I never used this before and don't know if is efficient or not. Anyways there is still a problem with this. Now I need to set the number of descriptor count when I create the descriptor layout and again, I don't want to set a max number you can use: VkDescriptorSetLayoutBinding samplerLayoutBinding = {}; samplerLayoutBinding.binding = 1; samplerLayoutBinding.descriptorCount = 999999; <<<< HERE samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; samplerLayoutBinding.pImmutableSamplers = nullptr; samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; Having said that. How can I solve this? Or which is the correct way to do this efficiently? If you need more information, just ask. Thanks in advance!
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!