Move glVertex Position

Started by
8 comments, last by marcClintDion 10 years, 10 months ago
Hi,
I usually only turn to forums when I'm completely and utterly stuck on a problem, and guess what? I'm completely and utterly stuck! Each time I think I've figured out a way for my code to work, I rush to my keyboard and my ideas are quickly shot down.
My question is, how do I actively re-position a trianglestrip as the program is running?
I'll be honest, I have pretty much no clue as to how to do this without reloading both the image and texture. The code I was previously using, used a timer that refreshed the screen every 0.05s and each time it did so, it was re-allocating and re-drawing my texture. Not the most efficient way to move an image.
This is the code I'm currently using in order to display the image and set it's position (coding in Obj-C):

-(void)addSprite{ // This code works btw, image is drawn on screen and positioned accordingly 
self.player = [[GLSprite alloc] initWithFile:@"logo2" fileFormat:@"png"];
self.player.positionX = 100;
[self.player render];
}
This is the code I'm trying to use to loop the render function in order to redraw it (am I even correct in doing this?). This code doesn't work at all (image doesn't show up) but it's a rough attempt at what I'm trying to do.

[NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval) 0.05 target:self selector:@selector(update) userInfo:nil repeats:YES];

-(void)update{
myInt += 1;
if (myInt < 2) {
// Calls alloc once
self.player = [[GLSprite alloc] initWithFile:@"logo2" fileFormat:@"png"];
NSLog(@"ALLOC"); 
}
// Render, render, render that image
self.player.positionX += 10; // Increments x coordinate every 0.05s (will eventually revert xPos to be dependant on mouse) 
[self.player render];
NSLog(@"RENDER"); 
}
And finally, here's the implementation of the functions from the above code:

-(id)initWithFile:(NSString *)imageName fileFormat: (NSString *) format{
if ((self = [super init])) {
[GLSprite getWindowSize];

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
 [NSNumber numberWithBool:YES],
 GLKTextureLoaderOriginBottomLeft,
 nil];

NSString *imageURL, *dirImage;
imageURL = [NSString stringWithFormat:@"images/%@", imageName];
dirImage = [[NSBundle mainBundle] pathForResource:imageURL ofType:format];

NSError *error;
self.texture = [GLKTextureLoader textureWithContentsOfFile:dirImage options:options error:&error];
if (error) {
NSLog(@"Error loading texture from image: %@",error);
}
}
return self;
} 

-(void)render{
x = (self.texture.width / window.x);
y = (self.texture.height / window.y);

self.initPositionX = (self.positionX / window.x) * 2;
self.initPositionY = (self.positionY / window.y) * 2;

xCoord[0] = 0 - x; yCoord[0] = 0 - y;
xCoord[1] = 0 + x; yCoord[1] = 0 - y;
xCoord[2] = 0 - x; yCoord[2] = 0 + y;
xCoord[3] = 0 + x; yCoord[3] = 0 + y;

NSLog(@"Render: %f", self.initPositionX);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(0.0, 0.0); glVertex2d(xCoord[0] + self.initPositionX, yCoord[0] + self.initPositionY);
glTexCoord2d(1.0, 0.0); glVertex2d(xCoord[1] + self.initPositionX, yCoord[1] + self.initPositionY);
glTexCoord2d(0.0, 1.0); glVertex2d(xCoord[2] + self.initPositionX, yCoord[2] + self.initPositionY);
glTexCoord2d(1.0, 1.0); glVertex2d(xCoord[3] + self.initPositionX, yCoord[3] + self.initPositionY);
glEnd();
}
I'm most likely completely wrong in what I'm trying to achieve so any help would be great, thanks!
Advertisement

Maybe you could follow this link and start with something basic that fits your needs then add your draw code to it. There's a startup project for just about every category. I suspect these people will be able to help sort things out for you. http://www.raywenderlich.com/tutorials

Consider it pure joy, my brothers and sisters, whenever you face trials of many kinds, 3 because you know that the testing of your faith produces perseverance. 4 Let perseverance finish its work so that you may be mature and complete, not lacking anything.

Thanks for the link Marc, I've had a little browse through some of their OpenGL projects and they seem to rely quite heavily on using GLKit for a lot of their code. Not a bad thing, just I'm not too familiar with it. I'll perhaps play around with it later on today, in the meantime if anyone is able to chip in, it'd be much appreciated. My problem isn't really language specific, I'm just trying to figure out a way to move the vertexes whilst the programs running, be that in c, c++ or obj-c.

Start small. Try something like the following. Just try to move one vertex. //======================================================================================== GLfloat moveVertex[] = {0, 0}; //_Global variable or whatever you prefer. -(void)render { moveVertex[0] -= 0.01; //_x moveVertex[1] += 0.01; //_y glBegin(GL_TRIANGLE_STRIP); glTexCoord2d(moveVertex[0], moveVertex[1]); glVertex2d(xCoord[0] + self.initPositionX, yCoord[0] + self.initPositionY); glTexCoord2d(1.0, 0.0); glVertex2d(xCoord[1] + self.initPositionX, yCoord[1] + self.initPositionY); glTexCoord2d(0.0, 1.0); glVertex2d(xCoord[2] + self.initPositionX, yCoord[2] + self.initPositionY); glTexCoord2d(1.0, 1.0); glVertex2d(xCoord[3] + self.initPositionX, yCoord[3] + self.initPositionY); glEnd(); }

//==================================================================================================================

If you are planning on sticking with the 1.1 spec then just ignore the next two paragraphes.

You're right about that page, I should have been more specific. I recently used the following one to upgrade my texture loader for iOS, it doesn't use GLKit.

OpenGL ES 2.0 for iPhone Tutorial Part 2: Textures <- Down at the bottom under advanced openGL, it's really not advanced at all, just a model and a texture.

I meant to say something about avoiding the GLKit stuff. Sorry about that.

//==================================================================================================================

The following is what I started my iOS framework on. I think it's pretty straight forward. I was totally new to Apple, objective C, and the ES 2.0 spec at the time and I found it easy enough to follow.

http://developer.apple.com/library/ios/#samplecode/GLEssentials/Introduction/Intro.html

The matrix math code in this example is the most straight forward of all the matrix math libraries I've found anywhere. It's definitely the best for starting off.

//==================================================================================================================

I found a good way to learn the ropes is to comment out the features that you don't want until you are left with only what you want to focus on. Start by removing the code from the render function, then remove the init and shut down stuff, then the globals. For instance you might start by removing the reflection render code. Then trace back everything that is being accessed by the reflections rendering and remove that as well. Re-compile everytime you remove something to make sure the app still runs, then remove some more. Eventually, you'll be down to the basic essence of most programs and you'll have learned a lot about what does what in the process.

Consider it pure joy, my brothers and sisters, whenever you face trials of many kinds, 3 because you know that the testing of your faith produces perseverance. 4 Let perseverance finish its work so that you may be mature and complete, not lacking anything.

Thanks Marc, great tips there, I really appreciate it. I'll have a 'lil look into GLEssentials and see what I can do.

As for the code, I didn't explain myself very well, sorry. My problem doesn't lie in positioning the vertex as such but instead being able to reposition it after it's initially displayed, e.g// Everytime a number increments, or the mouse moves in a certain direction, the glVertex changes position and is re-rendered on the screen. The positioning I can handle, but I don't know how to constantly keep the triangle strip updating to adjust to the new coordinates- at the moment I can render the image, but for example, if I then altered moveVertex, it'd have no effect on the image's position. Any ideas how to fix this and keep the strip+texture updating?

In the mean time, I plan to go look through the example code from GLEssentials, thanks again for the help

By putting the following code in the Render function you are resetting it all to their initial positions every time the frame renders. This is why I specified that you make moveVertex[] a global variable. The following should be put in a initization function such as 'ViewDidLoad(), or you could put them in the same place that you put the texture intialization above in the 'calls alloc once' if() loop. I think the usual 'objective C' way to do things is to put moveVertex[] in the view controller.h. Personally, I would make it a Global variable. On a side note, is this an iOS app or Mac?

//------------------------------------------------------------//MOVE THE FOLLOWING OUT OF THE RENDER OR UPDATE FUNCTIONS TO THE INITIALIZATION FUNCTION

x = (self.texture.width / window.x); y = (self.texture.height / window.y); self.initPositionX = (self.positionX / window.x) * 2; self.initPositionY = (self.positionY / window.y) * 2; xCoord[0] = 0 - x; yCoord[0] = 0 - y; xCoord[1] = 0 + x; yCoord[1] = 0 - y; xCoord[2] = 0 - x; yCoord[2] = 0 + y; xCoord[3] = 0 + x; yCoord[3] = 0 + y;

Consider it pure joy, my brothers and sisters, whenever you face trials of many kinds, 3 because you know that the testing of your faith produces perseverance. 4 Let perseverance finish its work so that you may be mature and complete, not lacking anything.

Ah, I see your point, however in the above, defining x and y is just resetting the image dimensions, so that being called again shouldn't be a problem. As for the initPos variables, I'm redefining positionX beforehand in order to move the position of the object, so that being called again is needed in order to redraw the shape in the appropriate position, right? And to answer your question, I'm coding it for Mac at the moment- no real reason for it, just fancied doing it on such- I'll probably end up porting it to the iPhone eventually anyway.

I've been playing around with my code for the past few hours and I've somewhat solved my problem, well, kind of.

I was originally going to write a big explanation about what's wrong and what's working but I've recorded a video instead (linked here and below). Basically the NSRect function only gets called once initially, and every time the window size is repositioned thereafter. Placing the following code in the NSRect function works fine when resizing the window, but it's not exactly the way I want to move the image! haha


if (myInt < 1){
            self.player = [[GLSprite alloc] initWithFile:@"tmp" fileFormat:@"png"];
            [self.player render];
            myInt++;
    }
    else{
        self.player.positionX += 10;
        [self.player render];
    }

Alas, thinking I was close to figuring it out, I put the code into a separate function and called it at set intervals with an NSTimer. It didn't work. What instead happens is the image is drawn and drawn whilst being continuously repositioned- it's what happens in the second part of the video. Any ideas why it's doing that? Thanks again for the help though

Video:

(computer was lagging hard from quicktime, sorry for the slow recording)

Edit: Here's another example of the problem from using an NSTimer to call the above code (I've added mousetracking rather than an increasing integer):

Edit 2: A timer probably isn't the best way to invoke the image re-position, but I can't think of a better solution. Any ideas?

The second video cleared things up a bit. When I saw the red being drawn out in the first video I thought that you were not calling glClear(); but then I saw it in the DrawRect function so I assumed that the two left most vertices were not being moved creating the impression that you weren't clearing the screen. The second video makes it seem as if the DrawRect function is either not being called or it's not being called in the proper order. Try moving glClearColor() and glClear to the top of your Render Function. This will clear the draw screen every frame so you have a blank canvas for the textured model to be drawn at it's new position without the old draws from previous frames showing up as well.

Consider it pure joy, my brothers and sisters, whenever you face trials of many kinds, 3 because you know that the testing of your faith produces perseverance. 4 Let perseverance finish its work so that you may be mature and complete, not lacking anything.

Ah, perfect, that did the trick! I really can't thank you enough, I've spent far too long trying to figure all of this out. Let me know if you have a bitcoin address and I'll be sure to send a few mbtc your way, thanks again! smile.png

No payment necessary, thanks though. I glad it's working for you.

Consider it pure joy, my brothers and sisters, whenever you face trials of many kinds, 3 because you know that the testing of your faith produces perseverance. 4 Let perseverance finish its work so that you may be mature and complete, not lacking anything.

This topic is closed to new replies.

Advertisement