I'm following this article, using sokol_gfx with opengl core 3.3 profile. The grid renders, is transparent, is rendered after other objects in the scene, and blending is enabled.
When the camera is close to objects the grid will render behind them, however, as the camera moves away the grid will render in front of the objects. Also, when the camera is close to objects the grid doesnt render behind them when it should, it penetrates the object a little and then becomes transparent.
Here is an image showing the grid rendering on top of an object it should not, but also rendering behind an object it should. Both of the cubes are above the grid, it should be rendering behind both of them.
Depth
And here is an image showing the grid rendering past where it should. The bottom of the cube is on the same plane as the grid, the grid should stop at the edge of the cube, not go in a little ways and then stop.
Too much grid
Depth calculation from grid fragment shader:
float compute_depth (vec3 position) {
vec4 clip_space_position = frag_projection * frag_view * vec4 (position.xyz, 1.0);
return (clip_space_position.z / clip_space_position.w);
}
The full project is located here
I had the same issue. The problem is that the article is written for Vulkan, which handles the depth differently from OpenGL.
After reading GLSL gl_FragCoord.z Calculation and Setting gl_FragDepth I managed to solve the issue by modifying the fragment shader like this:
float compute_depth (vec3 position) {
vec4 clip_space_position = frag_projection * frag_view * vec4 (position.xyz, 1.0);
return 0.5 + 0.5 * (clip_space_position.z / clip_space_position.w);
}
Related
I've encountered a problem while programming on C with SDL2. I have rendered to a texture simple images of squares that are transparent in the center. But when I draw the texture on which they are rendered they are not see-through. I've tried even changing the transparency of the rendered texture with SDL_SetTextureAlphaMod() but it isn't changing anything. If I change the alpha on the textures that are being rendered(the squares). They get dimmer but still they cover anything behind them. So I'm open to suggestions.
This is an image where I have lowered the alpha on the squares textueres:http://imgur.com/W8dNbBY
First off, you have two methods in SDL2 if you want to have a transparent image.
Method 1: (Static Method)
Use an image editing software and directly change the alpha value there, it will carry on to SDL2.
Method 2: (Dynamic Method)
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);//This sets the texture in blendmode
alpha = xx //this section should be where you alter the alpha value. You can make fade in-fade out effects, etc... Just put the changes here.
SDL_SetTextureAlphaMod(texture, alpha); //sets the alpha into the texture
SDL_RenderCopy(renderer, texture, NULL, &rect); //Redraws the image with a fresh, new alpha ~
I have installed GLUT and Visual Studio 2010 and found some tutorials on OpenGL basics (www.opengl-tutorial.org) and 2D graphics programming. I have advanced knowledge in C but no expirience with graphics programming...
For project (astronomy - time scales) , i must create one object in center of window and make other 5 objects (circles,dots...) to rotate around centered object with respect to some equations (i can implement them and solve). Equations is for calculating coordinates of that 5 objects and all of equations have parameter t (as time). For creating animation i will vary parameter t from 0 to 2pi with some step and get coordinates in different moments. If task was to print new coordinates of objects it would be easy to me but problem is how to make animation of graphics. Can i use some functions of OpenGL for rotation/translation ? How to make an object to move to desired location with coordinates determined by equation? Or i can redraw object in new coordinates every millisecond? First thing i thought was to draw all objects, calculate new coordinates, clear screen and draw all objects in new coordinates and repeat that infinitely..(it would be primitive but will work?)
Here is screen shot of that objects - http://i.snag.gy/ht7tG.jpg . My question is how to make animation by calculating new coordinates of objects each step and moving them to new location. Can i do that with basics in OpenGL and good knowledge of C and geometry? Any ideas from what to start? Thanks
Or i can redraw object in new coordinates every millisecond? First
thing i thought was to draw all objects, calculate new coordinates,
clear screen and draw all objects in new coordinates and repeat that
infinitely..
This is indeed the way to go. I would further suggest that you don't bother with shaders and vertex buffers as is the OpenGL 3/4 way. What would be easiest is called "immediate mode", deprecated by OpenGL 3/4 but available in 1/2/3. It's easy:
glPushMatrix(); //save modelview matrix
glTranslatef(obj->x, obj->y, obj->z); //move origin to object center
glBegin(GL_TRIANGLES); //start drawing triangles
glColor3f(1.0f, 0.0f, 0.0f); //a nice red one
glVertex3f(0.0, +0.6f, 0.0f);
glVertex3f(-0.4f, 0.0f, 0.0f);
glVertex3f(+0.4f, 0.0f, 0.0f); //almost equilateral
glEnd();
glPopMatrix(); //restore modelview matrix/origin
Do look into helper libraries glu (useful for setting up the camera / the projection matrix) and glut (should make it very easy to set up a window and basic controls and drawing).
It would probably take you longer to set it up (display a rotating triangle) than to figure out how to use it. In fact, here's some code to help you get started. Your first challenge could be to set up a 2D orthogonal projection matrix that projects along the Z-axis, so you can use the 2D functions (glVertex2).
First thing i thought was to draw all objects, calculate new coordinates, clear screen and draw all objects in new coordinates and repeat that infinitely..(it would be primitive but will work?)
That's exactly how it works. With GLUT, you set a display function that gets called when GLUT thinks it's time to draw a new frame. In this function, clear the screen, draw the objects and flush it to the screen. Then just instruct GLUT to draw another frame, and you're animating!
Might want to keep track of the time inbetween frames so you can animate things smoothly, but I'm sure you can figure that part out.
OpenGL is really just a drawing library. It doesn't do animation, that's up to you to implement. Clear/draw/flush is the commonly used approach for it though.
Note: with 'flush' I mean glFlush(), although GLUT in multi-buffer mode requires glutSwapBuffers()
The red book explains the proper way to draw models that can first be translated, rotated, scaled and so on: http://www.glprogramming.com/red/chapter03.html
Basically, you load the identity, perform transforms/rotations/scales (which one you want first matters - again the book explains it), draw the model as though it was at the origin at normal scale and it'll be placed in its new position. Then you can load identity and proceed with the next one. Every frame of an animation, you glClear() and recalculate/redraw everything. (It sounds expensive, but there's usually not much you can cache between draws).
I have a sheet of black shapes surrounded by transparency. I have successfully loaded this texture with GLKit and I can draw the shapes using GLKBaseEffect into rectangles. Is there a way to change the color of the black (ie non-transparent) pixels, so I can draw yellow shapes or blue shapes etc? Or do I need a custom shader to do this?
It seems like you'll need a custom shader (which I highly recommend working with) as you need to check individual texel color values, but here are some suggestions to try first:
You can pass color as per-vertex data in a vertex attribute array pointing to GLKVertexAttribColor. This will allow you to individually set the color of each vertex (and ultimately, faces) but it will be difficult to see where they line up against your texture.
You can try enabling the following property on your effect:
effect.colorMaterialEnabled = YES;
But, for both cases, if your texels are completely black then I don't think any changes in color will show.
I think a custom shader is definitely the way to go, as you'll need to do something like this:
highp vec4 finalColor;
highp vec4 textureColor = texture2D(uTexture, vTexel);
highp vec4 surfaceColor = uColor;
// If texel is non-transparent (check alpha channel)
if(textureColor.a > 0.001)
finalColor = surfaceColor;
else
finalColor = vec4(0.0, 0.0, 0.0, 0.0);
gl_FragColor = finalColor;
Where anything prefixed with u is a uniform variable passed into the shader.
To get fully colorized textures, use:
self.effect.texture2d0.envMode = GLKTextureEnvModeModulate;
Which tells OpenGL to take whatever color is in your texture and multiply it by whatever color the underlying geometry is. You can then use vertex coloring to get neat fades and whatnot.
NOTE: You'll want to change your texture from black to white (1, 1, 1, 1), so multiplication works correctly.
NOTE: Here are some other settings that you should already have in place:
self.effect.texture2d0.enabled = GL_TRUE;
self.effect.texture2d0.target = GLKTextureTarget2D;
self.effect.texture2d0.name = self.texture.name;
self.effect.colorMaterialEnabled = GL_TRUE;
NOTE: You can experiment with GLKTextureEnvModeDecal, too, which blends your texture on top of colored geometry (as when applying a decal), so the transparent parts of the texture show the geometry underneath.
I need to write an application with Silverlight 4 and need to show images like wrapped on cylinder. I need some HLSL code, as I wont to do that with Effects of Silverlight.
I don't wont to do that with 3D libarries for silverlight. I only need HLSL code for changing pixels.
I need for my image to look like this
Thanks.
This seems to be the effect you want, you may wish to change the 0.2 value to increase or decrease the effect or make this adjustable in your shader but that's a simple change to do. I'd recommend Shazzam if your not using it for writing shaders for WPF or Silverlight.
sampler2D input : register(s0);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float y = uv.y+(sin(uv.x*3.14) * lerp(-1,1,uv.y) * 0.2);
if(y < 0 || y > 1)
return float4(0,0,0,0);
else
return tex2D(input,float2(uv.x,y));
}
While you could do this with HLSL if you really wanted to, you'd normally do it by creating a mesh in the shape you want, then applying the picture to the mesh as a texture.
In WPF, I want to use a pixel shader to modify a composite image i.e. a new image overlaid on top of a previously shaded image. The new image comes in as a largely transparent image except where there is data (think mathematical functions - sine wave, etc). Anyway this process needs to repeat pretty rapidly - compose the currently shaded texture with a new image and then shade the composite image. The problem is that I don't know how to access the previously shaded texture from within my shader.
Basically, you need to add a Texture2D variable in your shader, then set that parameter as the texture you need to access before drawing the new one (i'm unsure of that process in WPF). You do something like this:
//blahblahblah variables here
Texture2D PreviousTexture;
Sampler PreviousTextureSampler = Sampler2D { Texture = PreviousTexture; };
//blahblahblah code here
then you can sample the texture with a tex2D call.