Jump to content
  • Advertisement


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By Shaarigan
      Hello Forum,
      I reached a point in my rework of our build tool where I have to improve parsing different coding languages like C# and C++ to detect dependencies between files and projects. Maybe I will also add some kind of linting to the build tool. Unfortunately I'm fixed to an older version of C# to stay backwards compatible to older Visual Studio versions. This is the reason for not having the chance to use the Roslyn parser framework out of the box and I had to write my own "analyzer" to solve the task.
      That I'm now ready for refactoring, I want to make it into a real parser instead of Regex driven analyzer. For this task, I also had a look at parser utility libraries like Sprache and Pidgin to have some more convinience in declaring tokens and rules. I have written parsers on my own by hand many times before and they were always optimized to the special token/ rule and usecase. For example instead of just reading the next string and then comparing it to a keyword, then conditionally reset the stream or pass the token, I wrote something like this
      char[] buffer = new buffer[<max keyword length>]; bool MyKeywordRule(Stream data, TokenStream result) { if(data.Peek() != myKeywordFirstChar) return false; long cursor = data.Position; int count = data.Read(buffer, 0, Math.Min(myKeywordLength, data.Length - cursor)); if(count == myKeywordLength && buffer.Compare("keyword", myKeywordLength)) { result.Add(myToken); return true; } else { data.Position = cursor; return false; } } My hand written function is optimized in performance to first test the character, then fill a buffer with data that is as long as the keyword and finally test this for equality with the keyword. If I write this in Sprache or Pidgen, it will just read the stream, compare the result for the keyword and reset on failure, no early out will be performed or whatever speed optimization. If I want to test against a range of keywords or character sequences like for operators, in a generic solution it will read every statement of the sequence from the stream and test it while my hand written solution can fill the buffer once and test the result in a switch statement and early outs for the character count read.
      My question is if there exists a solution that can perform both, define rules in a convinient way like Sprache or Pidgin and on the other hand compete somehow with a hand written solution (it must not be as fast but in any way faster than simply replay the parts of a rule). I thought about a solution using C# Expressions where an operation for example my keyword, can be written as a sequence of pre-condition (testing the character), bootstrapping (reading the buffer for certain size) and validation (test if the buffer matches the keyword) and be merged together for example, so that a rule "A or B" dosen't test for a first then resets the stream and tests for B second but merges the pre-condition into
      IF not('A') and not('B') FAIL fills the buffer only once and then tests for equality in a switch-case statement. Or is it the best solution to keep writing such code by hand for each individual rule?
      Thank you in advance for your suggestions experts!
    • By amtri
      I need to write a shader where, for a specific pixel, as a fragment comes in I will sort a struct stored in memory based on the value of depth.
      For the sake of argument, let's assume I have an array of 10 entries per pixel of the struct containing {float depth; vec4 color}. As a new fragment comes in for a pixel I will use an insertion sort so I only keep the 10 front-most fragments and discard the rest.
      If OpenGL were sequential, this is a rather trivial operation: just program a proper insertion sort. However, my worry is that the same pixel may be processed in 2 different fragments simultaneously, so my insertion sort would fail because multiple threads would be accessing the same array.
      This leads me to 2 questions I'm hoping somebody has the insight to help out:
      1) Can I be assured that, despite OpenGL's parallelism, no two fragments for the same pixel will ever be processed simultaneously? In other words, can I be sure that if I'm working on a pixel, then parallelism means that on another thread OpenGL will not be working on the same pixel?
      2) If the answer to (1) above is no - that is, there are no guarantees - is there a way that would allow me do this in a safe way?
    • By Yarden2JR
      Hi there, everyone!
      I am programing a tessellation shader in OpenGL which computes the quartic Walton-Meek's Gregory patch. I am searching for a local G1 method with good shading/visual results. So I am trying this patch. I didn't get good (visual/shading) results with PN-Triangles.
      I've just had my first result with this WM patch, which isn't good as well. Perhaps the normal I am calculating is wrong. I will attach the equations I am using to compute the normal. Please, take a look there as I couldn't write in TeX here (I don't know why). Basically, they are the Bernstein polynomial, Bernstein-Bezier triangle and its derivatives. Then, I actually compute it through normalizing the cross product between the derivatives.
      If you want to take a look at the shader code, here it is (the first one is the tessellation control shader and the second one is the tessellation evaluation shader):
      #version 430 core layout (vertices = 3) out; in VertOut { vec3 normal; } vertOut[]; out TescOut { vec3 p0; vec3 p1; vec3 p2; vec3 p3; vec3 g0; vec3 g1; vec3 n; } tescOut[]; void main() { const float kTessLevel = 12.0; gl_TessLevelOuter[gl_InvocationID] = kTessLevel; gl_TessLevelInner[0] = kTessLevel; vec3 p0 = tescOut[gl_InvocationID].p0 = gl_in[gl_InvocationID].gl_Position.xyz; vec3 n = tescOut[gl_InvocationID].n = vertOut[gl_InvocationID].normal; const int nextInvID = gl_InvocationID < 2 ? gl_InvocationID + 1 : 0; vec3 edge = gl_in[nextInvID].gl_Position.xyz - p0; vec3 nNext = vertOut[nextInvID].normal; float d = length(edge), a = dot(n, nNext); vec3 gama = edge / d; float a0 = dot(n, gama), a1 = dot(nNext, gama); float ro = 6.0 * (2.0 * a0 + a * a1)/(4.0 - a * a); float sigma = 6.0 * (2.0 * a1 + a * a0)/(4.0 - a * a); vec3 v[4] = vec3[4] ( p0, p0 + (d / 18.0) * (6.0 * gama - 2.0 * ro * n + sigma * nNext), gl_in[nextInvID].gl_Position.xyz - (d / 18.0) * (6.0 * gama + ro * n - 2.0 * sigma * nNext), edge = gl_in[nextInvID].gl_Position.xyz ); vec3 w[3] = vec3[3] ( v[1] - v[0], v[2] - v[1], v[3] - v[2] ); vec3 A[3] = vec3[3] ( cross(n, normalize(w[0])), vec3(0.0), cross(nNext, normalize(w[2])) ); A[1] = normalize(A[0] + A[2]); vec3 l[5] = vec3[5] ( v[0], 0.25 * (v[0] + 3.0 * v[1]), 0.25 * (2.0 * v[1] + 2.0 * v[2]), 0.25 * (3.0 * v[2] + v[3]), v[3] ); vec3 p1 = tescOut[gl_InvocationID].p1 = l[1]; vec3 p2 = tescOut[gl_InvocationID].p2 = l[2]; vec3 p3 = tescOut[gl_InvocationID].p3 = l[3]; barrier(); const int previousInvID = gl_InvocationID > 0 ? gl_InvocationID - 1 : 2; vec3 D[4] = vec3[4] ( tescOut[previousInvID].p3 - 0.5 * (p0 + p1), vec3(0.0), vec3(0.0), tescOut[nextInvID].p1 - 0.5 * (p3 + tescOut[nextInvID].p0) ); float mi[2] = float[2](dot(D[0], A[0]), dot(D[3], A[2])); float lambda[2] = float[2](dot(D[0], w[0])/dot(w[0], w[0]), dot(D[3], w[2])/dot(w[2], w[2])); tescOut[gl_InvocationID].g0 = 0.5 * (l[1] + l[2]) + (2.0/3.0) * (lambda[0] * w[1] + mi[0] * A[1]) + (1.0/3.0) * (lambda[1] * w[0] + mi[1] * A[0]); tescOut[gl_InvocationID].g1 = 0.5 * (l[2] + l[3]) + (1.0/3.0) * (lambda[0] * w[2] + mi[1] * A[2]) + (2.0/3.0) * (lambda[1] * w[1] + mi[1] * A[1]); } #version 430 core layout(triangles, equal_spacing, ccw) in; in TescOut { vec3 p0; vec3 p1; vec3 p2; vec3 p3; vec3 g0; vec3 g1; vec3 n; } tescOut[]; out TeseOut { vec3 normal; vec3 viewPosition; } teseOut; uniform mat4 mvp; uniform mat4 modelView; uniform mat4 normalMatrix; uniform bool isNormalLinearlyInterpolated; #define uvw gl_TessCoord const float u = uvw.x, u2 = u * u, u3 = u2 * u, u4 = u2 * u2; const float v = uvw.y, v2 = v * v, v3 = v2 * v, v4 = v2 * v2; const float w = uvw.z, w2 = w * w, w3 = w2 * w, w4 = w2 * w2; #define p400 tescOut[0].p0 #define p310 tescOut[0].p1 #define p220 tescOut[0].p2 #define p130 tescOut[0].p3 #define G01 tescOut[0].g0 #define G02 tescOut[0].g1 #define p040 tescOut[1].p0 #define p031 tescOut[1].p1 #define p022 tescOut[1].p2 #define p013 tescOut[1].p3 #define G11 tescOut[1].g0 #define G12 tescOut[1].g1 #define p004 tescOut[2].p0 #define p103 tescOut[2].p1 #define p202 tescOut[2].p2 #define p301 tescOut[2].p3 #define G21 tescOut[2].g0 #define G22 tescOut[2].g1 #define B400 u4 #define B040 v4 #define B004 w4 #define B310 (4.0 * u3 * v) #define B031 (4.0 * v3 * w) #define B103 (4.0 * u * w3) #define B220 (6.0 * u2 * v2) #define B022 (6.0 * v2 * w2) #define B202 (6.0 * u2 * w2) #define B130 (4.0 * u * v3) #define B013 (4.0 * v * w3) #define B301 (4.0 * u3 * w) #define B211 (12.0 * u2 * v * w) #define B121 (12.0 * u * v2 * w) #define B112 (12.0 * u * v * w2) #define B300 u3 #define B030 v3 #define B003 w3 #define B210 (3.0 * u2 * v) #define B021 (3.0 * v2 * w) #define B102 (3.0 * w2 * u) #define B120 (3.0 * u * v2) #define B012 (3.0 * v * w2) #define B201 (3.0 * w * u2) #define B111 (6.0 * u * v * w) vec3 interpolate3D(vec3 p0, vec3 p1, vec3 p2) { return gl_TessCoord.x * p0 + gl_TessCoord.y * p1 + gl_TessCoord.z * p2; } void main() { vec4 pos = vec4(interpolate3D(tescOut[0].p0, tescOut[1].p0, tescOut[2].p0), 1.0); vec3 normal = normalize(interpolate3D(tescOut[0].n, tescOut[1].n, tescOut[2].n)); if (u != 1.0 && v != 1.0 && w != 1.0) { vec3 p211 = (v * G12 + w * G21)/(v + w); vec3 p121 = (w * G02 + u * G11)/(w + u); vec3 p112 = (u * G22 + v * G01)/(u + v); vec3 barPos = p400 * B400 + p040 * B040 + p004 * B004 + p310 * B310 + p031 * B031 + p103 * B103 + p220 * B220 + p022 * B022 + p202 * B202 + p130 * B130 + p013 * B013 + p301 * B301 + p211 * B211 + p121 * B121 + p112 * B112; pos = vec4(barPos, 1.0); vec3 dpdu = p400 * B300 + p130 * B030 + p103 * B003 + p310 * B210 + p121 * B021 + p202 * B102 + p220 * B120 + p112 * B012 + p301 * B201 + p211 * B111 ; vec3 dpdv = p310 * B300 + p040 * B030 + p013 * B003 + p220 * B210 + p031 * B021 + p112 * B102 + p130 * B120 + p022 * B012 + p211 * B201 + p121 * B111 ; normal = normalize(cross(dpdu, dpdv)); } gl_Position = mvp * pos; pos = modelView * pos; teseOut.viewPosition = pos.xyz / pos.w; teseOut.normal = (normalMatrix * vec4(normal, 0.0)).xyz; } There are also some screenshots attached of my current results. Please, take a look. In the "good ones" images, the normals are computed by linear interpolation, while in the bad ones the normals are computed through the equations I said previously and are shown in the code.
      So, how can I correctly compute the normals? Thanks in advance!

    • By PatrickGG
      I done with my very first Interactive film, and it all worked until i build it. If I download the game file on a another computer, the video starts to lag or play in slow-motion. I've tried many differents things.
      The video file is a H.264, and it is 24Fps.
      The audio is directly from the video source.
      It plays on Awake, and the playback speed value is set to 1. It's not playing on a texture or antything (Vsync is disabled, and Wait For First Frame is enabled, I tried to set the Target frame - Didn't work) Game:
      I use a simple sceneloader script, when someone make a chose. So when you click on a button it starts another scene, with a new Video Player.

      And for some reason when i build it on the computer i used to make it, it runs smoothly. It's just when i transfer the game on to another computer via dropbox, Google drive or USB, it starts to lag...
      Pls help, i really want this to work.

      Any help will be much appreciated, and if your solution works, I will put your name in the Credits haha.

      Link to see my broken game...
      https://www.youtube.com/watch?v=5UiUrHnyqmw&feature=youtu.be Jaa Godmorgen II.webm
    • By Stocke
      I looked into flow field pathfinding(after reading about steering behaviours) and it seems that it's mostly used for RTS games. I understand why, but wouldn't it also work for an action game with a single player character? It wouldn't be efficient, sure but it makes using steering behaviours easier to use. I could precalculate obstacles based on static colliders in the scene. And I can calculate the a vector towards the player for seek behaviours every frame. And reuse that for every enemy.
      I could then use inverse of the vectors for flee behaviours and make that avoid obstacles as well. 
      If I wanted to steer a character perpendicular to the player, maybe I could rotate the vector in the field 90 degrees to obtain that? 
      Of course this approach would not be valid for other behaviours. Like for pursuit you would need to calculate another vector field for the future position of the player. Unless there is some mathematical way to shift a flow field if the center(where the arrows converge) moves.
      I dunno how you would add local avoidance. Maybe keep track of enemy positions on another vector field and take that into consideration.
      A* is no doubt efficient and popular. But it does not work well if the agent has target velocities instead of target positions (like from using steering behaviours). And A* also has the problem of being too good(perfect paths => too robotic). 
      Anyways, that's enough rambling from me. What do you think?
  • 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!