Noob question: change start drawing position

Hello, I am a total noob with OpenGL and I could use some help. I have this program that renders a line and I move that line with data passed in. This is a realtime waveform. I have two questions.

  1. How can I start drawing the line near the right edge instead of center as it does now?
  2. How can I tweak the scale so that I get more waves into the view even if I make the view wider?

I tried changing the backingWidth of the viewPort by dividing by 2 and that squeezed my waves together but shorted my real estate. I’ve changing many properties of the class to start drawing to the far right but it always starts in dead center. I appreciate any help someone could give.

Here is the code.

#define USE_DEPTH_BUFFER 1

#define GRID_LINES_HORZ 30
#define GRID_LINES_VERT 30

float Smooth(float start, float end, float amount)
{
// Clamp to 0-1;
amount = (amount > 1.0f) ? 1.0f : amount;
amount = (amount < 0.0f) ? 0.0f : amount;

// Cubicly adjust the amount value.
amount = (amount * amount) * (3.0f - (2.0f * amount));

return (start + ((end - start) * amount));

}

// You must implement this method

  • (Class)layerClass {
    return [CAEAGLLayer class];
    }
  • (void)loadTexture
    {

    CGImageRef spriteImage;
    CGContextRef spriteContext;
    GLubyte *spriteData;
    size_t width, height;

    // Creates a Core Graphics image from an image file
    spriteImage = [UIImage imageNamed:@“dot.png”].CGImage;
    // Get the width and height of the image
    width = CGImageGetWidth(spriteImage);
    height = CGImageGetHeight(spriteImage);
    // Texture dimensions must be a power of 2. If you write an application that allows users to supply an image,
    // you’ll want to add code that checks the dimensions and takes appropriate action if they are not a power of 2.

    if(spriteImage) {
    // Allocated memory needed for the bitmap context
    spriteData = (GLubyte *) malloc(width * height * 4);
    // Uses the bitmatp creation function provided by the Core Graphics framework.
    spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
    // After you create the context, you can draw the sprite image to the context.
    CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), spriteImage);
    // You don’t need the context at this point, so you need to release it to avoid memory leaks.
    CGContextRelease(spriteContext);

      // Use OpenGL ES to generate a name for the texture.
      glGenTextures(1, &texture);
      // Bind the texture name. 
      glBindTexture(GL_TEXTURE_2D, texture);
      // Speidfy a 2D texture image, provideing the a pointer to the image data in memory
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
      // Release the image data
      free(spriteData);
      
      // Set the texture parameters to use a minifying filter and a linear filer (weighted average)
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
      
      // Enable use of the texture
      glEnable(GL_TEXTURE_2D);
      // Set a blending function to use
      glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
      // Enable blending
      glEnable(GL_BLEND);
    

    }
    }

//The GL view is stored in the nib file. When it’s unarchived it’s sent -initWithCoder:

  • (id)initWithCoder:(NSCoder*)coder {

    if ((self = [super initWithCoder:coder])) {

      // Get the layer
      CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
      
      dataPoints = [[NSMutableArray alloc] init];
      
    
      eaglLayer.opaque = YES;
      eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
      
      context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
      
      if (!context || ![EAGLContext setCurrentContext:context]) {
          [self release];
          return nil;
      }
      
      [self loadTexture];
      
      animationInterval = 1.0 / 30.0;
      curveStart = 0;
      squeeze = 1;
      maxCurvePoint = MAX_CURVE_POINT_NO;
      
      [self buildDemoData];
    

    }
    return self;
    }

// Sets up an array of values to use as the sprite vertices.
const GLfloat spriteVertices[] = {
-0.7f, -0.7f,
0.7f, -0.7f,
-0.7f, 0.7f,
0.7f, 0.7f,
};

// Sets up an array of values for the texture coordinates.
const GLshort spriteTexcoords[] = {
0, 0,
1, 0,
0, 1,
1, 1,
};

float scale(float min, float max, float point) {
return (point-min)/(max-min);
}

float scaleByMid(float min, float max, float point) {

float mid = max - ((max - min) /2); 
return ((point - mid) / (max - mid)); 

}

  • (void)drawView {

    // Replace the implementation of this method to do your own custom drawing

    GLfloat lineVertices[maxCurvePoint2];
    GLfloat lineVerticesGrid[GRID_LINES_HORZ
    GRID_LINES_VERT4];
    GLfloat lineVerticesGridTexCoords[GRID_LINES_HORZ
    GRID_LINES_VERT*4];
    float currLevel = curve[(maxCurvePoint+curveStart-1)%maxCurvePoint];

    int i;
    for (i=0; i<maxCurvePoint; i++) {
    lineVertices[i*2] = i/(maxCurvePoint/2.0)-1.0; // X
    lineVertices[i*2+1] = curve[(i+curveStart)%maxCurvePoint]; // Y
    }

    for (i=0; i<GRID_LINES_HORZ; i++) {
    float yval = 4.0*i/GRID_LINES_HORZ-2.0;
    lineVerticesGrid[i*4] = -2.0; // X
    lineVerticesGrid[i*4+1] = yval; // Y
    lineVerticesGrid[i*4+2] = 2.0; // X
    lineVerticesGrid[i*4+3] = yval; // Y
    lineVerticesGridTexCoords[i*4] = -2.3/1.4; // X
    lineVerticesGridTexCoords[i*4+1] = (yval-currLevel)/1.4; // Y
    lineVerticesGridTexCoords[i*4+2] = 1.7/1.4; // X
    lineVerticesGridTexCoords[i*4+3] = (yval-currLevel)/1.4+0.7; // Y
    }

    for (i=0; i<GRID_LINES_VERT; i++) {
    int j = (GRID_LINES_HORZ+i)4;
    float xval = 4.0
    i/GRID_LINES_VERT-2.0;
    lineVerticesGrid[j] = 4.0i/GRID_LINES_VERT-2.0; // X
    lineVerticesGrid[j+1] = -2.0; // Y
    lineVerticesGrid[j+2] = 4.0
    i/GRID_LINES_VERT-2.0; // X
    lineVerticesGrid[j+3] = 2.0; // Y
    lineVerticesGridTexCoords[j] = (xval-0.7)/1.4; // X
    lineVerticesGridTexCoords[j+1] = currLevel/1.4+1.4+0.5; // Y
    lineVerticesGridTexCoords[j+2] = (xval-0.7)/1.4+0.7; // X
    lineVerticesGridTexCoords[j+3] = currLevel/1.4-1.4+0.5; // Y
    }

    [EAGLContext setCurrentContext:context];

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);
    //glEnable(GL_LINE_SMOOTH);
    glEnable(GL_POINT_SMOOTH);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glScalef(0.8, 0.8, 1.0);
    glTranslatef(-0.2, 0, 0);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_TEXTURE_2D);

    glVertexPointer(2, GL_FLOAT, 0, spriteVertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glTexCoordPointer(2, GL_SHORT, 0, spriteTexcoords);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glPushMatrix();
    glTranslatef(1.0, currLevel, -0.01);

    glColor4f(0.0, 0.0, 0.0, 1.0); //SpotLight - Should be kinda light

    /*
    if([colorTheme isEqualToString:@“blue”]) //SpotLight - Should be kinda light
    glColor4f(0.0, 0.0, 0.0, 1.0);
    else if ([colorTheme isEqualToString:@“red”])
    glColor4f(0.5, 0.0, 0.0, 1.0);
    else if ([colorTheme isEqualToString:@“green”])
    glColor4f(0.0, 0.5, 0.0, 1.0);
    else if ([colorTheme isEqualToString:@“orange”])
    glColor4f(255.f/255.f, 101/255.f, 3/255.f, 1.0);
    else
    glColor4f(0.0, 0.0, 0.0, 1.0); */

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glPopMatrix();

    glVertexPointer(2, GL_FLOAT, 0, lineVerticesGrid);
    glEnableClientState(GL_VERTEX_ARRAY);

    glTexCoordPointer(2, GL_FLOAT, 0, lineVerticesGridTexCoords);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glLineWidth(1.0);

    glColor4f(0.0, 0.0, 0.0, 1.0);//Grid Lines behind spotlight…Very faint

    /*
    if([colorTheme isEqualToString:@“blue”]) //Grid Lines behind spotlight…Very faint
    glColor4f(0.0, 0.0, 0.0, 1.0);
    else if ([colorTheme isEqualToString:@“red”])
    glColor4f(0.4, 0.0, 0.0, 1.0);
    else if ([colorTheme isEqualToString:@“green”])
    glColor4f(0.0, 0.4, 0.0, 1.0);
    else if ([colorTheme isEqualToString:@“orange”])
    glColor4f(255.f/255.f, 204/255.f, 7/255.f, 1.0);
    else
    glColor4f(0.0, 0.0, 0.0, 1.0); */

    glDrawArrays(GL_LINES, 0, (GRID_LINES_HORZ+GRID_LINES_VERT)*2);

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);

    glVertexPointer(2, GL_FLOAT, 0, lineVertices);
    glEnableClientState(GL_VERTEX_ARRAY);

    glLineWidth(9.0);
    glPointSize(9.0);

    if([colorTheme isEqualToString:@“blue”]) //Wave line before cursor outside color… little faint
    glColor4f(0.0, 0.5, 1.0, 0.2);
    else if ([colorTheme isEqualToString:@“red”])
    glColor4f(0.5, 0.0, 0.0, 0.2);
    else if ([colorTheme isEqualToString:@“green”])
    glColor4f(0.0, 0.5, 0.0, 0.2);
    else if ([colorTheme isEqualToString:@“orange”])
    glColor4f(255.f/255.f, 194/255.f, 12/255.f, 0.2);
    else
    glColor4f(0.0, 0.0, 0.0, 1.0);

    glDrawArrays(GL_LINE_STRIP, 0, maxCurvePoint);
    glTranslatef(0, 0, .01);
    glDrawArrays(GL_POINTS, 0, maxCurvePoint);
    glPointSize(15.0);
    glDrawArrays(GL_POINTS, maxCurvePoint-1, 1);

    glTranslatef(0, 0, .01);

    glLineWidth(3.0);
    glPointSize(3.0);

    //Wave line before cursor inside
    if([colorTheme isEqualToString:@“blue”])
    glColor4f(0.0, 0.5, 1.0, 0.7);
    else if ([colorTheme isEqualToString:@“red”])
    glColor4f(0.5, 0.0, 1.0, 0.7);
    else if ([colorTheme isEqualToString:@“red”])
    glColor4f(0.0, 0.5, 1.0, 0.7);
    else if ([colorTheme isEqualToString:@“orange”])
    glColor4f(255.f/255.f, 220/255.f, 11/255.f, 0.7);
    else
    glColor4f(0.0, 0.0, 0.0, 1.0);

    glDrawArrays(GL_LINE_STRIP, 0, maxCurvePoint);
    glTranslatef(0, 0, .01);
    glDrawArrays(GL_POINTS, 0, maxCurvePoint);
    glPointSize(9.0);
    glDrawArrays(GL_POINTS, maxCurvePoint-1, 1);

    glTranslatef(0, 0, .01);

    glLineWidth(1.0);
    glPointSize(1.0);
    glColor4f(1.0, 1.0, 1.0, 1.0);
    glDrawArrays(GL_LINE_STRIP, 0, maxCurvePoint);
    glPointSize(5.0);
    glDrawArrays(GL_POINTS, maxCurvePoint-1, 1);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];

    if (demoMode){

      if (randomMode)
         curve[ curveStart ] =  ((rand()%32768)/32768.0)*0.4-0.2;
      else
      	curve[ curveStart ] =  ekgMap[ curveStart ]; // ((rand()%32768)/32768.0)*0.4-0.2;
    

    // DLog(@"%f", ekgMap[ curveStart ]);

    } else{

       if ([dataPoints count] ==0){
      	 
      	 curve[ curveStart ] =  0.0;
      	  			 
       }else {
      	 
      	 if (!inverted) {
      		 
      		 curve[curveStart] =  scaleByMid(self.min, self.max, [[dataPoints dequeue] floatValue]) /scaleFactor; //   [[dataPoints dequeue] floatValue] /scaleFactor;
      		 
      		// DLog(@"Queue Length: %d", [dataPoints count]);
      		 
      	 } else{
      	    
      		 float point = scaleByMid(self.min, self.max, [[dataPoints dequeue] floatValue]) /scaleFactor;
      		 curve[curveStart] =  (point -(point *2));
      		 
      		 
      	 }
       }
    

    }

    curveStart = (curveStart+1)%maxCurvePoint;

}

  • (void)addDataPoint:(id)point{

    float thisPoint = [point floatValue];
    //DLog(@“Last: %f”, lastPoint);
    //DLog(@“This: %f”, thisPoint);
    if (lastPoint != thisPoint){

      if (interpolate) {	
      
      	float step = (thisPoint - lastPoint) / (numberOfPoints + 1);
      	for (int i =0; i &lt; numberOfPoints; i++){
      		
      		//float value = lastPoint += step;
      		
      		float value = Smooth(lastPoint, thisPoint+=step, 0.5);
      		// DLog(@"Value: %f", value);
      		[dataPoints enqueue:[NSNumber numberWithFloat:value]];
      		
      	}
    
      	
      	
      	
      } else { //No interpolation but still smooth
      
       
      	float value = Smooth(lastPoint, thisPoint, 0.5);
          [dataPoints enqueue:[NSNumber numberWithFloat:value]];
    
      }
    

    } else { //Points are the same as the last, just plot

    [dataPoints enqueue:point];

    }

    lastPoint = [point floatValue];

}

  • (void)layoutSubviews {
    [EAGLContext setCurrentContext:context];
    [self destroyFramebuffer];
    [self createFramebuffer];
    [self drawView];
    }

  • (BOOL)createFramebuffer {

    glGenFramebuffersOES(1, &viewFramebuffer);
    glGenRenderbuffersOES(1, &viewRenderbuffer);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);

    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

    if (USE_DEPTH_BUFFER) {
    glGenRenderbuffersOES(1, &depthRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
    }

    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
    NSLog(@“failed to make complete framebuffer object %x”, glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
    return NO;
    }

    return YES;
    }

  • (void)destroyFramebuffer {

    glDeleteFramebuffersOES(1, &viewFramebuffer);
    viewFramebuffer = 0;
    glDeleteRenderbuffersOES(1, &viewRenderbuffer);
    viewRenderbuffer = 0;

    if(depthRenderbuffer) {
    glDeleteRenderbuffersOES(1, &depthRenderbuffer);
    depthRenderbuffer = 0;
    }
    }

  • (void)startAnimation {

    if (!animating) {

    	if (useDisplayLink) {
       
      	  if (self.displayLink == nil)	{
      			self.displayLink = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawView)];
      			[self.displayLink setFrameInterval:animationInterval];
      			[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
      		 
      	  }	
      	
       	
      	
      	
      } else{ //Fallback to time approach, slower but more compatible....
      		
      		self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
      		
      		
      }
      
      animating = TRUE;
    

    }

}

  • (void)stopAnimation {

    if (animating) {
    DLog(“Attempting to Stop Animation!!!”);

      if (useDisplayLink){
      	
      [self.displayLink invalidate];
      self.displayLink = nil;
    			
      } else{
      	
      	
      	self.animationTimer = nil;
      	
      }
      animating = FALSE;
    

    }
    }

  • (void)setAnimationTimer:(NSTimer *)newTimer {
    [animationTimer invalidate];
    animationTimer = newTimer;
    }

  • (void)setAnimationInterval:(NSTimeInterval)interval {

    animationInterval = interval;
    if (animationTimer) {
    [self stopAnimation];
    [self startAnimation];
    }
    }

  • (void)dealloc {

    [self stopAnimation];

    [dataPoints release];

    if ([EAGLContext currentContext] == context) {
    [EAGLContext setCurrentContext:nil];
    }

    [context release];
    [super dealloc];
    }

  • (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
    if(animating)
    [self stopAnimation];
    else
    [self startAnimation];
    }
    @end

Hello, I am a total noob with OpenGL

From the amount of code and the stuff going in it, i dont think so.

  1. Enclose the code in [ code] [/ code] blocks to make it easier for us to read.
  2. Post only the relevant code or the minimal code so that others may help. Try isolating the problem by making a minimalistic glut application and put the stuff in it rather than working on a code this huge.