To clarify I am using React-Three-Fiber
I would like to create a bunch of points on the canvas, beforehand I was using buffered arrays of colors and positions to plot the points. Here is my attempt at getting it work with buffered positions and using shaderMaterial along with a fragmentShader
<points>
<bufferGeometry attach="geometry">
<bufferAttribute
attach="attributes-position"
count={positions.length / 3}
array={positions}
itemSize={3}
usage={THREE.DynamicDrawUsage}
/>
</bufferGeometry>
<shaderMaterial fragmentShader={fragmentShader}/>
</points>
I am able to use the shader with other geometries so I know the mistake is in the way I am trying to use points. Using pointsMaterial or meshStandardMaterial worked fine, could anyone help me understand how to go about using shaders with points in R3F?
I´m using React Three Fiber with "Drei" and want to use the the billboards. But I could only figure out how to change the color of the billboard, but not how to add a texture.
I tried it like that, but can't find any documentation on billboards and don`t know what arguments i can pass.
<Billboard map={textureBillboard}/>
Here you see how to change color, but not how to add a texture:
https://drei.react-spring.io/?path=/story/abstractions-billboard--billboard-st
Hope someone can help me.
thanks
you can add texture as a meshBasicMaterial:
<Billboard
position={[0,7,1]}
args = {[44,30]}>
<meshBasicMaterial attach="material" map = {billboardTexture}/>
</Billboard>
OpenGL glutWireCube works but glutWireCylinder doesn't.
glutWireCylinder throws an 'undefined' error. How can this be?
What am I doing wrong?
That function is not defined because GLUT does not have a function named glutWireCylinder(). This is based on the official GLUT documentation here:
https://www.opengl.org/documentation/specs/glut/spec3/spec3.html
If you don't mind using legacy features, the GLU (GL Utility) library has a function for drawing cylinders (see man page for details).
// setup
GLUquadric* quadric = gluNewQuadric();
gluQuadricDrawStyle(quadric, GLU_LINE);
// drawing
gluCylinder(radius, radius, height, 32, 8);
// cleanup
gluDeleteQuadrc(quadric);
If you don't want to use deprecated libraries, writing code to draw a cylinder is easy to write yourself. My answer here shows how to draw a circle, which gets you most of the way to drawing a cylinder: How to draw a circle using VBO in ES2.0.
I'm finally upgrading a very old universal game app I have to play nice with newer OSs and device sizes - I've got everything updated and targeting iOS 6.1 right now but when I run it on the iPhone 5, my actual in game view, which is rendered using open GL into an EAGLView, is positioned very strangely and shows a lot of clipping (see screenshot).
On the "normal" devices that were around when we first created this, everything appears as expected.
In my view controller, I basically load a nib with the right size set for the different devices - iPad and non 4" devices get a 1024x768 view and the 4" device gets a new 1136x640 view.
Then, in my viewDidLoad, I set up my view's self.view.contentScaleFactor to [UIScreen mainsScreen] scale], I then do some view sizing like so (roughly):
if(iPad){
[self.view setFrame:CGRectMake(0, 0,1024,768)];
[self.view setCenter:CGPointMake(384,512)];
DefaultViewScale=1.2;
}else if(WideScreen){
[self.view setFrame:CGRectMake(0, 0, 568, 320)];
[self.view setCenter:CGPointMake(160, 293)];
DefaultViewScale = 1.0f;
}else{
[self.view setFrame:CGRectMake(0, 0,480,320)];
[self.view setCenter:CGPointMake(160,240)];
DefaultViewScale=1.0f;;
}
Lastly, I apply a transform to scale the view by a factor defined above which I've just hand tweaked and then rotated it since the app is Landscape-Left only.
[self.view
setTransform:
CGAffineTransformConcat(CGAffineTransformMakeScale(DefaultViewScale,DefaultViewScale),
CGAffineTransformMakeRotation(-M_PI_2))];
I then initialize a new EAGLContext (openGL ES 1),
[(EAGLView *)self.view setContext:context];
[(EAGLView *)self.view setFramebuffer];
setFramebuffer is mostly:
[EAGLContext setCurrentContext:context];
// Create default framebuffer object.
glGenFramebuffers(1, &defaultFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
glViewport(0, 0, framebufferWidth, framebufferHeight);
There's some more boilerplate EAGLView code but note that I'm setting the glViewport to whatever gl tells me it's width and height is which is grabbed from the UIView's layer size.
And finally it sets up the projection matrix:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, self.view.frame.size.width , 0, self.view.frame.size.height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND_SRC);
glEnableClientState(GL_VERTEX_ARRAY);
glDisable(GL_DEPTH_TEST);
// Set the colour to use when clearing the screen with glClear
glClearColor(51.0/255.0,135.0/255.0,21.0/255.0, 1.0f);
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
This is not my strongest area of knowledge, so let me know if I've missed something and I can get you more info if needed. If anyone has an "a ha" or a similar experience, I'd appreciate some tips in the right direction.
Thanks
Short answer, start using GLKView instead of EAGLView.
First, a good way of getting to know the best practice for setting up e.g. an OpenGL context in the most recent version of iOS is to create a new project using the "OpenGL Game" template and look at for reference.
The most significant difference is the GLKView (introduced in iOS 5.0), which greatly simplifies things for you. It will take care of most of the things you now do manually, including setting up the viewport.
Start by replacing use of the EAGLView with the GLKView (make sure to reference GLKit.framework in your project).
Remove the call to the setFramebuffer method. GLKit takes care of this for you.
Remove the [self.view setTransform:] call. If your app is full-screen OpenGL, there is no need to use view transforms. (And it not, it is likely that it is still not needed).
Set the frame of the view to the bounds of the screen (e.g. by letting it autoresize). You can probably do this in the XIB.
Make sure to call [context setCurrentContext] in your viewDidLoad somewhere.
That should more or less be it. Also make sure to set the context property of the GLKView to the OpenGL context, just as for the EAGLView.
I suggest ensuring that your launch images are up-to-date.
OpenGL is definitely not my area of expertise, but I had a similar issue when upgrading a flash game to iOS 6. I did not supply appropriate launch images for the retina displays of the new iPhone etc, and my app was run in 'compatibility mode' with margins at the top and bottom of the screen. Admittedly, you don't quite have these margins, but it's possible that it's messing with how big your app thinks its screen is. Might be worth checking out.
Why is your "DefaultViewScale=1.2" on an iPad? If the app is fullscreen, it shouldn't be scaled anymore since it's 1024x768. Are you rescaling something there?
In my OpenGL Apps I just have a EAGLView that is always fullscreen and then read the sizes from the framebufferWidth/height.
If you have a UIViewController, with the HUD-Elements correctly set up, you wouldn't need to do any [self.view setTransform..]. I have the feeling you're making life more complicated for yourself, then it should be!
Just add the EAGLView with "UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth" as the lowest subview of your ViewControllers main view. And set up the rotation code correctly (keep in mind the iOS5 calls so shouldAutoRotateToInterfaceOrientation:.. are deprecated).
It looks like the transformation you're doing is after setting the frame of the view, and may therefor change the bounds. I would suggest breaking in your draw method and checking the bounds of both the view and its layer.
Remember that the frame is set from the perspective of the parent, while the bounds is in local coordinates. From UIView.h:
do not use frame if view is transformed since it will not correctly
reflect the actual location of the view. use bounds + center instead.
I've been trying to get a HUD texture to display for a simulator for a while now, without success.
First I bind the texture like this:
glGenTextures(1,&hudTexObj);
gHud = getPPM("textures/purplenebula/hud.ppm",&n,&m,&s);
glBindTexture(GL_TEXTURE_2D,hudTexObj);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,n,m,0,GL_RGB,GL_UNSIGNED_INT, gHud);
And then I attempt to map it to a QUAD, which results in the whole quad being a single brown color, and I want it to use all the texels. Here's how I map:
glBindTexture(GL_TEXTURE_2D,hudTexObj);
glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0);
glVertex2f(0,0);
glTexCoord2f(0.0,1.0);
glVertex2f(0,m);
glTexCoord2f(1.0,1.0);
glVertex2f(n,m);
glTexCoord2f(1.0,0.0);
glVertex2f(n,0);
glEnd();
The weird thing is that I've been able to get the exact above code to display the texture in a program of its own, yet when I put it into my main program it fails. Could it have to do with the texture matrix? I'm dumbfounded at this point.
Stupidly, I had enabled automatic tex coord generation far away in another part of the code. So if you see one texel's color covering a whole image, that is the likely cause.