i am starting out with opengles coming from old opengl.
i see there is no immediate mode anymore. so functions like glVertex glTexCoord are missing, right?
instead i have to use vertexarrays. right?
how can i modify the values of those arrays each frame?
for example, if i want to animate the texture coordinates, in old OpenGL i did:
glTexCoord2f(x*time, y*time);
how can i achieve a similar effect with vertex arrays?
thanks!
Just update the arrays you pass to gl*Pointer, and draw again.
If you use VBOs, you'll need to update the VBO contents also.
if all you want to do is scroll the texture, there are direct ways to modify the texture coordinates as they go through the pipeline.
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glTranslatef(...);
glMatrixMode(...);
In general, cases where actual texcoord data should really change (as in because you want to apply a non-uniform transformation to them) are rare.
Related
I tried the Instancedbuffergeometry, it works awesome,
Intersection is not happening in InstancedBufferGeometry, i checked in the threejs(r85) library, checkBufferGeometryIntersection function have the position value only, I think the offset and orientation value need to use with the position.
I have another doubt in it, i have used one rawshadermaterial only, then how i can highlight the selected geometry.
Can anyone guide in it.
Thanks in advance.
As far as the cpu is concerned (where you do the raycasting) those instances do not exist. You do however have your master geometry available. What you can do is, create another instance of BufferGeometry then create the same number of Mesh objects using that one instance of geometry. Use the same logic for instancing to place this into a scene. You don't render them, thus saving the overhead from multiple draw calls. You do have them available for intersection though as if it were normal geometry, because it is (you're just not rendering it).
As #pailhead already wrote, raycasting with instanced-geometries cannot work.
An alternative approach to achieve the same goal is to use so-called GPU picking. For this you render the scene into a framebuffer, using a special shader that will just output a unique color-value for every instance.
You can then sample the point under the cursor from that framebuffer and compute the instance-id from the color-value.
You can see an example for this technique here or here.
I want to draw some parallel lines. At first I used gl.LINES but the problem was that the rendered line was one pixel wide at any point on the screen, whether it was very close or very far from the camera.
So instead, I rendered thin rectangles:
As you can see, they now get thinner as they get farther from the camera, but now I get all these ugly aliasing artifacts. Is there a "correct" way to do this in OpenGL/WebGL?
There's a couple of ways to tackle this.
(1) As others have mentioned, just run with super or multisampling.
(2) Use a shader. If you are using Es2/WebGL you are doing that already. But instead of outputting a constant color, write a color plus an alpha that determines how close you are to the line. And then enable blending with that alpha.
One very easy way to do this is to just map a texture as an alpha channel on your rectangle.
Alternatively you can draw 2 quads instead of one and compute the distance in the shader. Then map the distance with a ramp function to alpha.
If you're using GLUT, you can try something like this-
glutInitDisplayMode(GLUT_MULTISAMPLE);// along with all the other flags
If you're not using GLUT, then you can find a very helpful topin on the subject here.
Every platform allows you to do multisampling after getting the OpenGL context.
Using the WebGL API, how can I get a value from the depth buffer, or in any other way determine 3D coordinates from screen coordinates (i.e. to find a location clicked on), other than by performing my own raycasting?
Several years have passed, these days the WEBGL_depth_texture extension is widely available... unless you need to support IE.
General usage:
Preparation:
Query the extension (required)
Allocate a separate color and depth texture (gl.DEPTH_COMPONENT)
Combine both textures in to a single framebuffer (gl.COLOR_ATTACHMENT0, gl.DEPTH_ATTACHMENT)
Rendering:
Bind the framebuffer, render your scene (usually a simplified version)
Unbind the framebuffer, pass the depth texture to your shaders and read it like any other texture:
texPos.xyz = (gl_Position.xyz / gl_Position.w) * 0.5 + 0.5;
float depthFromZBuffer = texture2D(uTexDepthBuffer, texPos.xy).x;
I don't know if it's possible to directly access the depth buffer but if you want depth information in a texture, you'll have to create a rgba texture, attach it as a colour attachment to an frame buffer object and render depth information into the texture, using a fragment shader that writes the depth value into gl_FragColor.
For more information, see the answers to one of my older questions: WebGL - render depth to fbo texture does not work
If you google for opengl es and shadow mapping or depth, you'll find more explanations and example source code.
From section 5.13.12 of the WebGL specification it seems you cannot directly read the depth buffer, so maybe Markus' suggestion is the best way to do it, although you might not neccessarily need an FBO for this.
But if you want to do something like picking, there are other methods for it. Just browse SO, as it has been asked very often.
Not really a duplicate but see also: How to get object in WebGL 3d space from a mouse click coordinate
Aside of unprojecting and casting a ray (and then performing intersection tests against it as needed), your best bet is to look at 'picking'. This won't give exact 3D coordinates, but it is a useful substitute for unprojection when you only care about which object was clicked on, and don't really need per-pixel precision.
Picking in WebGL means to render the entire scene (or at least, the objects you care about) using a specific shader. The shader renders each object with a different unique ID, which is encoded in the red and green channels, using the blue channel as a key (non-blue means no object of interest). The scene is rendered into an offscreen framebuffer so that it's not visible to the end user. Then you read back, using gl.readPixels(), the pixel or pixels of interest and see which object ID was encoded at the given position.
If it helps, see my own implementation of WebGL picking. This implementation picks a rectangular region of pixels; passing in a 1x1 region results in picking at a single pixel. See also the functions at lines 146, 162, and 175.
As of January 23, 2012, there is a draft WebGL extension to enable depth buffer reading, WEBGL_depth_texture. I have no information about its availability in implementations, but I do not expect it at this early date.
An OpenGL ES sequence like this can be used to render multiple objects in one pass:
glVertexPointer(...params..., vertex_Array );
glTexCoordPointer(...params..., texture_Coordinates_Array );
glBindTexture(...params..., one_single_texture_ID );
glDrawArrays( GL_TRIANGLES, number_Triangles );
Here, the vertex array and texture coordinates array can refer to innumerable primitives that can be described in one step to OpenGL.
But do all these primitives' texture coordinates have to reference the one, single texture in the glBindTexture command?
It would be nice to pass in an array of texture identifiers:
glBindTexture(...params..., texture_identifier_array[] );
Here, there would be a texture ID in the array for every primitive shape described in the preceding calls. So, each shape's texture coordinates would pertain to the texture identified in "texture_identifier_array[]".
I can see one option is to place all textures of interest one one large texture that can be referenced as a single entity in the drawing calls. On my platform, this creates an intermediate step with a large bitmap that might cause memory issues.
It would be best for me to be able to pass an array of texture identifiers to the OpenGL ES drawing calls. Can this be done?
No, that's not possible. You could perhaps emulate it by using a texture array and giving your vertices a texture index. Then in the fragment shader you could look up the right texture with the index, but I doubt that ES supports texture arrays. And even then I don't know if this really works. Or if a texture atlas solution would be much more efficient.
If you want to render multiple versions of the same geometry (what I doubt), you're looking for instanced rendering, which also isn't supported by on ES devices, I think.
So the way to go at the moment will be a texture atlas (multiple textures in one) or just calling glDrawArrays multiple times.
I know it's possible to repeat an entire texture by setting the wrap mode to GL_REPEAT, but is it somehow possible to repeat only a subregion of the texture? For example, when the texture is part of an atlas.
I'm targetting OpenGL ES 1.x, so shaders are out.
Unfortunatelly, it is not possible. The only thing you can do it to repeat side pixels (if the image is at the edge of a texture altals).
If you need tiling – probably the only solution here is generate is with geometry. Otherwise, just go with a separate texture.