Jump to content
  • Advertisement

amtri

Member
  • Content Count

    128
  • Joined

  • Last visited

Everything posted by amtri

  1. Hello, 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? Thanks.
  2. Joe, You say If I understand you correctly, what you are describing is the equivalent of a "mutex" per pixel. What you are suggesting is the equivalent of "lock", sort everything for the pixel, then "unlock". The methods I've seen with atomic variables are such that, while the call is being made, that atomic variable is replaced with a new value. But when the call returns any other thread can start modifying the variable - or, in other words, the variable is locked during the call and unlocked the moment the call returns. So by the time I start my sort the variable is no longer locked. Is there a shader call I can make to a variable to lock it and another one to unlock it? Also, on a side note: the linked list approach suffices for me provided I have enough memory. Rather than doing 2 passes I do just one and, if the memory is full, I drop everything else and set a flag that the memory was exhausted. Users then have the option to increase the memory and redraw the scene. Most of the time they will only have to do this once. Then they can draw, rotate, etc. the image without worrying. Yes; when the scene changes, say, with a rotation, everything changes, but I've noticed that if one allocates, say, 20-30% more than the initially required value, they rarely run out of memory later. My issue here is when I cannot allocate the needed memory. In that case, I want to make sure I allow a fixed number of fragments per pixel so that every pixel has a "decent" image. But that requires an insertion sort - hence, the problem I'm running into. If there's a way to lock a per-pixel variable, do the insertion sort, then unlock the per-pixel variable, then I'm all set. If you know how to do this please let me know. Thanks.
  3. I should have mentioned: I'm looking for a single-pass algorithm, if at all possible. I can accomplish the single pass with the linked list approach, but would like to have an optional K-storage-per-pixel approach, also in a single pass. Just haven't been able to figure out how I can do this.
  4. Joe, Order-independent transparency is what I'm after (as you may have guessed by the link you pointed me to). I have coded the linked-list approach. But this has a downside that I may be left with pixels with many fragments and others with few - or none - because I may have run out of memory. So the idea is to use K entries per pixels - as described in the paper. What is not clear to me in this approach is how to use the atomics in this case. For the linked list, the atomic is in the tail value for each pixel and the global counter in my linked list. So let's assume I have a x*y buffer of atomics that serves as my counter of fragments per pixel (if that's the way to do it). As another fragment comes in I can check the counter. If less than K => insertion sort; if equal to K, insertion sort and drop the last. But if two threads are working on the same pixel, would I need to define my entire storage as atomic? That would be a performance killer (I imagine). Could you point me to some (pseudo) shader code that would allow me to store up to K entries per pixel in a safe way? Thanks
  5. Hello,   I'm trying to understand a basic principle on how OpenGL works when the compilation/linking is done with one version of OpenGL, but the program actually runs on a different version.   I understand that if the runtime version of OpenGL is greater than the one it was built in this is not a problem: OpenGL is backward compatible so the program will run on a machine where a newer version of OpenGL is installed.   My problem is the other way around. My program is heavily dependent on advanced shader technology. So I have function calls such as glUniform... throughout the code.   So let's assume I built my program on a machine with the latest version of OpenGL. Now I'm going to take it to a machine running an older version. Quite possibly, a function such as glUniform... is not even present there. Given that nobody distributes software with OpenGL - either DLLs on Windows or shared libraries on Linux - will my program simply crash if I run it on a machine with an older version of OpenGL?   I'm used to building applications that rely on other libraries - but their shared libraries are usually shipped along with the application. But I don't think OpenGL follows this practice: people usually have OpenGL on their machines and use their own version.   Can somebody explain to me how this works in the general case? For example, can I just query OpenGL at runtime for the version number and simply skip calls that rely on newer versions? Will the application even load properly?   Thanks.
  6. Hi cgrant,   I think my confusion right now is just one question: regardless how the code was compiled and on what platform, and with what version of OpenGL, is GL_VERSION (major and minor) obtained at runtime reliable ways (at runtime!) do bracket the source with "if" statements to skip over code that compiled properly but should not be called because the runtime version of opengl does not support it?   In other words, if my running machine only supports GL 1.1, can I reliably count on the fact that glGetString(GL_VERSION) will tell me that the runtime version is 1.1 and that I should skip some code that uses functionality in GL > 1.1?   I'm just hoping that glGetString(GL_VERSION) has no relation to the version used for compiling the code.   Thanks.
  7. Thanks to all for the responses.   So basically this is what I'm planning on doing:   1) When compiling I'll use #ifdef GL_VERSION_X_Y to make sure the compilation works properly.   2) When running it, let's say that glGetString(GL_VERSION) is supported. I understand that GLEW may have a bug in this function; but if I have a reliable way of parsing this string to get the major and minor version numbers, then these will be the ones available at runtime. Let's say I define an integer iversion = 10*major + minor. Then I can use #ifdef GL_VERSION_3_1 if(iversion >= 31) { /* my happy OpenGL 3.1 code here */ } #endif Of course, this is all predicated on two facts: (1) I can construct iversion reliably; and (2) iversion created at runtime by extracting the version through gl calls will give me the supported runtime version of gl - regardless of how it was compiled.   Am I correct?
  8. Osbios,   Messy all right...   Following the link that Waterlimon posted I learned that glGetString(GL_VERSION) is deprecated and has been removed in 3.1. So in order to find out the version I'm using at runtime I need to first know the version (!) so I know which function to call. I can certainly use #ifdef GL_VERSION_3_1 to decide which function to call depending on the compiler being used. But then I need to retrieve the runtime version to decide what to do.   For the moment we use no extensions, only the #ifdef GL_VERSION_X_Y at compile time, and glGetString(GL_VERSION) at runtime. I'm sure in the near future this will need to change...
  9. Hi mhagain,   Thanks.   Unfortunately, what we distribute is a library that gets embedded into an end-user application that may go to thousands of end users. And I have no control over what end users are still using (you'd be surprised!).   So I have to assume the worst - even if that means people may still be at GL 1 (ok... maybe not that far back). But my source is full of #ifdef GL_VERSION_X_Y so that the end-user application can be compiled regardless of the version of GL they choose to use, and their end users can run it also regardless of what they have on their machine.
  10. One more thing - although I'm not sure this is the place for the question:   I'm using GLEW on Windows, and include the GLEW DLL with the distribution.   Suppose I build with the latest version of GLEW then I try to run on a machine that is so old that the graphics card is unable to support the version I include in my distribution. Would glewInit() fail? Or - because the DLL is from the latest version of GLEW - could I see that glGetString returns a version I believe would work (because it is my GLEW DLL they are using), but the call could still fail?   In other words, I'm trying to protect myself from a crash. I have no problem reporting that a feature is not supported, but I cannot have the application crash. If glewInit() fails that's no problem because I will report this as an error.   Thanks again.
  11. Hi Waterlimon,   Thanks! Very clear.   So, if I understand this correctly, I can build my application on, say, OpenGL 4.2. Then, at runtime, use glGetString (GL_VERSION), parse the string to determine the version, and avoid calling functions that probably won't be available.   For example, #ifdef GL_VERSION_4_2 /* use 4.2 functionality here */ if(parsedversion(glGetString(GL_VERSION)) >= 42) { /* use the functionality here */ } #endif where "parsedversion" is some simple function that just parses the string with the version and generates an equivalent integer I can use for comparison purposes.   Of course, I could have a  "} else {" statement for a fall back approach to the functionality in case 42 is not available on the running machine. But, at this point, all I want is to make sure it won't crash.   If everything is about call a function with a null pointer, then the above code should prevent the crash. Correct?   Thanks!
  12. Hello,   I have been asked to take a series of images defined as simple bitmaps and encode them into a h264 file. I did manage to download and build the h264 libraries, but I'm having a tough time sorting through the documentation or examples to come up with a simple way of doing this through their API (I am required to use the h264 API directly).   Can somebody point me to some simple examples on how to do this?   Thanks.
  13. amtri

    How to encode h264 video

    Stainless,   Isn't CUDA specific to NVIDIA graphics? Or am I missing something here? I'm supposed to assume that the only library I have is the original h264 library. Having to rely on CUDA would restrict usage to those using NVIDA graphics.   Am I correct?
  14. amtri

    How to encode h264 video

    Thanks fastcall22! I'll take a look at that thread.   Much appreciated!
  15. Yet another update: I changed the texture type to GL_TEXTURE_RECTANGLE. This way I can directly use gl_FragCoord.xy when passing data to the textures. I'm using the defaults, so I assume gl_FragCoord.xy will have values like 0.5, 1.5, 2.5, etc.   I store all my display data on display lists. I draw my display list once and save the color and depth buffer by create a frame buffer with GL_TEXTURE_RECTANGLE textures for both - one color, and one depth. The filters on both textures are set to GL_NEAREST.   I query the depth texture using   float depth = texture (depthtex,gl_FragCoord.xy).r;   My expectation is that this call should always find the exact same texel in my texture; so it writes the color and depth on one pass and reads with the exact same coordinates on the next path.   But, unfortunately, this is not the case. I "solved" my problem by using a tolerance such as   if(depth >= gl_FragCoord.z - 0.00001) discard;   on the second time I draw. The image looks perfect - pointing to the fact that this was indeed my problem. But   1) Why do I not get the exact same values on the second pass as the first pass, or... why does my comparison fails at times?\   2) Can I get better results by using different texture parameters?   Thanks.
  16. Hello,   I have a shader where I create several frame buffers and perform N passes through my display list. In the first pass I simply store the image and depth; in the second and all subsequent passes in the fragment shader I compare the current depth with the previously saved one and discard if it's in front of it. Then I blend all images in a final post-processing phase at swap time.   This all works fine, except for when there's z-clipping going on. I saved both the color and depth textures associated with each frame buffer and save all of them to a bmp file so I can see what's going on. I have just a few intersecting cones being displayed. In the area where z-clipping occurs both the depth and the color textures seem to have garbage defined on them.   I'm wondering whether there's something I'm not aware of regarding the data coming in. For example, I assume that gl_FragCoord.z is always between 0 and 1, and anything that's being clipped won't even go through the fragment shader. Is this the case? Or is z-clipping done after the fragment shader? In this case, should I expect gl_FragCoord.z < 0 or > 1 to be allowed?   I'm attaching the saved color texture. The solid colors are what I expect to see. The fuzzy area is exactly where the z-clipping plane is passing through. Any thoughts?   Thanks.
  17. After some more reading I suspect my problem has to do with the fact that I created a 2D texture to store the depth and then I'm comparing the depth value from a previous pass (stored in the texture) with gl_FragCoord.z. But in order to retrieve the previous value I need to pass to texture2D the texture coordinates between 0 and 1, and this rounding-off depending on screen size may just be returning to me the incorrect pixel. And with depth values probably extremely close to each other the comparison is failing, thus giving me the bad image I'm seeing.   This is all speculation, but if I'm right now I have more concrete questions that I'm hoping somebody can help me with:   1) Is there a way to query a sampler2D in the fragment shader given the center pixel location values - gl_FragCoord.xy? Of course, these will not go from 0 to 1, but from 0 to width and 0 to height. Given that gl_FragCoord will have values such as (1.5,3.5), I can easily pick the exact pixel. But if I need to map gl_FragCoord to texture coordinates between 0 and 1 I'm bound to run into this round-off issue.   2) My depth peeling algorithm requires multiple passes through my display list. This means that, at the same time, I need to both retrieve the depth and save it on another texture on pass, AND I need to accurately compare the depth to gl_FragCoord.z. I am using only sampler2D. Maybe I should be using sampler2DShadow instead to store my depth value. But from what I understand, querying the sampler2D using texture coordinates I get the floating point depth back; and querying a sampler2DShadow with a vec3 value returns only 0 or 1, depending on the result of the comparison.   What exactly should I be using in my fragment shader so I can both compare and store the depth value accurately?   3) Depending on the answer to the question above, what parameters should I be setting in the depth texture on the client side?   Thanks.
  18. Hello,   I have clipping planes working in my shader using gl_ClipDistance. I pass the equation of every clipping plane to my vertex shader and compute the dot product with my untransformed coordinates. It works fine.   Now I ran into a machine where the call   glGetString (GL_SHADING_LANGUAGE_VERSION)   returns 130. Yet, gl_ClipDistance is an undefined variable. This brings up my first question:   1) Shouldn't gl_ClipDistance always be defined for GLSL version 130? I'm using a Linux 64-bit machine with glew 1.10.0.   But I want to get this working, so I decided to alternatively use gl_ClipVertex instead on that machine. The problem is I'm getting no image - kind of like everything is always being clipped out. Given that my glClipPlane is setting the plane equation in untransformed coordinates (i.e., same as gl_Vertex), I'm simply setting gl_ClipVertex = gl_Vertex.   In my gl_ClipDistance implementation I'm taking the dot product of gl_Vertex with the 4 numbers that define the equation in glClipPlane. It works fine. But somehow I think my clipping plane equations are not being properly passed down. I even tried setting "#version 120" in the shader, but with no effect.   Can anybody shed some light onto this?   Thanks.
  19. One more piece of information: I am drawing the 1D texture first, then the 2D texture.   If I reverse the order, then my 2D texture works fine, but my 1D texture does not.   And I know for a fact that my uniform flag indicating which texture I'm using is being passed down correctly, and it is using sampler1D for the 1D texture and sampler2D for the 2D texture. But, for some reason, after the first texture is drawn - either 1D or 2D - the second one in the same unit is not drawn.   Not clear why this is the case...
  20. Hello,   I would like to highlight edges based solely on z-buffer discontinuities. I can imagine this as an image posprocessing step after the frame and z-buffers are complete.   I have two questions:   1) What is a reasonable filter to use to detect edge pixels?   2) Can this be implemented in a shader? One of my questions here is whether I can access neighboring pixel information in the fragment shader.   Thanks.
  21. I've made some more progress on my own, and ran into a more concrete issue: I have both a 1D and a 2D texture on unit 0 (GL_TEXTURE0). I use one or the other by using glEnable/glDisable.   In my shader I have a sampler2D and a sampler1D. Both are assigned to unit 0.   Whenever I switch from the 1D/2D textures I send a uniform flag indicating which texture is being used. If it's the 1D texture I use texture1D using as first argument the sampler1D variable, and as second argument gl_TexCoord[0].s; if it's the 2D texture I use texture2D using as first argument the sampler2D variable, and as second argument gl_TexCoord[0].st.   My problem is that the 2D texture does not show.   By setting the output color in the fragment shader to vec4(gl_TexCoord[0].s,gl_TexCoord[0].t,0.,1.) I can tell that the 2D texture coordinates are correct. So my problem is that somehow switching to texture2D(sampler2D,...) after displaying the using texture1D(sampler1D,...) is not working.   If I turn off the shader program then the images are displayed as expected, so the client program is correct.   Any thoughts? Have I misunderstood how a single unit is to be used with multiple textures?   Thanks.
  22. I could really use some help with what I believe is very basic. I created a framebuffer object, attached a depth and a color texture to it, and drew 2 triangles along with the text "Hello World" on top. I then took the 2 textures, extracted the data from them just to check that they were correct. They were: in one I see the RGB values, and in the other I see a single floating point number with values as expected given my triangles.   Then I bind the "0" framebuffer and draw 2 triangles to the screen with the color texture; not a problem. I see the image just as expected, so I'm confident that my textures are ok (at least the color one since I'm drawing with it).   Now comes the part I don't understand: all I'm trying to do is to use a shader to display the same image: no manipulation at this point as I'm getting my feet wet with textures.   This is what my vertex shader looks like: void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_TexCoord[0] = gl_MultiTexCoord0; } And this is my fragment shader: uniform sampler2D colortex; void main() { gl_FragColor = texture2D(colortex,gl_TexCoord[0].st); } The shader program compiles and links with no errors.   In the client code I have GLuint colortexloc = glGetUniformLocation (prog,"colortex"); glUniform1i (colortexloc,0); Everything else is the same. I expected the image to be displayed just as before. Can somebody point towards something that's obviously wrong or missing? If I comment out the "glUseProgram" call then the image is properly displayed again. So it does look like a problem with the trivial shader code above.   Any help is appreciated. Thanks!
  23.   It's not as simple as it sounds. My image consists of hundreds of thousands of triangles, many of them in the exact same orientation but just slightly parallel to each other. Sometimes I may have dozens of layers of closely spaced parallel surfaces and it's difficult to see them. They are all oriented the same way, with the same normal, so the best way to distinguish them is to highlight their edges. I could, in theory, just draw the line segment defining the feature edges, but that would take longer than just doing an image processing with a shader - which is why I'm going the shader route.
  24. OK. I got the color and the depth each written to a different texture in an FBO. For the color texture I use glTexImage2D (GL_TEXTURE_2D,0,GL_RGBA,400,400,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL); glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,geom_color,0); and for the depth texture I use glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT24,400,400,0,GL_DEPTH_COMPONENT,GL_FLOAT,0); glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,geom_depth,0); At the end I bind the 0 frame buffer and draw 2 triangles that cover the entire window, using the color texture to draw them. Everything works fine.   Now I would like to use a shader to post-process my geometry. I have 2 textures: one with the color and one with the depth. I want to use both in the shader: I will look at the value of the depth using a filter to detect an edge (something I've already done outside of a shader and I know it works well) and, depending on the value of the filter, I will use either the color from the color texture or just set the color to black to highlight the edge (I'm not worried about the edge algorithm now).   My question is: how do I setup the shader to use 2 textures at the same time. I'm truly confused by this: one texture contains a vec4; the other a single float; and both are used in the shader at the same time.   If somebody could give me some pointers on what needs to be done in the client and the shader to use these 2 textures at the same time I would appreciate it.   Thanks.
  25. Lorenzo,   You are right: I could simply draw the labels on top of the postprocessed true geometry.   The problem is that I do not control the order in which graphics data comes in. It could be geometry/geometry/label/label, or it could be geometry/label/geometry/label, etc. So what I will do is to direct the geometry to one FBO, the labels to another, and in this way not worry about the order in which they come in.   When everything is done I post-process the true geometry, then add the FBO with the labels on top of the final post processed image.   I thought about enforcing some ordering for when geometry and label data is sent, but I simply have no control over it in the entire application; there's just too much going on in other parts of the code, so I need to accomodate it.   At swap time I'll combine them.   Thanks!
  • 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!