使用OpenGL在iPad上绘制应用程序 [英] Drawing app on iPad using OpenGL

查看:228
本文介绍了使用OpenGL在iPad上绘制应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用OpenGL为iPad创建绘图应用程序(文本)。我已经看过Apple的示例GLPaint,我的应用程序现在基于该代码。我的应用程序应该只是用于绘制文本,而不是用于绘制图片。

I'm creating a drawing app ( text ) for the iPad using OpenGL. I've already had a look at Apple's example GLPaint, and my app is now based on that code. My app should be just for drawing text, not for painting pictures.

好吧,我的应用程序有效,我可以写一些文本。但写作并不是很好,写作并不好玩。绘制路径不是平滑的,它是有角度的,因为我从一个点到另一个点绘制一条线。并且路径到处都有相同的宽度。我的想法是:当你快速写作时,线条比你写作慢的时候要薄。它应该像用真笔写作一样。

Well, my App works, I can write some text. But the writing isn't really good, it doesn't make fun to write. The drawing path isn't smooth, it's angularly because I'm drawing a line from one point to another. And the path has everywhere the same width. My idea is: when you're writing fast the line is thinner than when you're writing slow. It should be the same experience like writing with a real pen.

如何让路径看起来更顺畅?如何根据书写速度改变线条的宽度?

How can I make the path look much smoother? How can I vary the width of the line depending on the speed of writing?

在这里你可以看到我的意思:

Here you can see what I mean:

推荐答案

平滑绘图的最佳方法是使用bezeir曲线。这是我的代码。这是我在苹果开发网站上找到的修改版本,但我不记得原始链接:

The best way to smooth the drawing is use a bezeir curve. Here is my code. It is a modified version I found on apple's dev site, but I don't remember the original link:

CGPoint drawBezier(CGPoint origin, CGPoint control, CGPoint destination, int segments)
{
 CGPoint vertices[segments/2];
 CGPoint midPoint;
 glDisable(GL_TEXTURE_2D);
 float x, y;

 float t = 0.0;
 for(int i = 0; i < (segments/2); i++)
 {
  x = pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x;
  y = pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y;
  vertices[i] = CGPointMake(x, y);
  t += 1.0 / (segments);

 }
 //windowHeight is the height of you drawing canvas.
 midPoint = CGPointMake(x, windowHeight - y);
 glVertexPointer(2, GL_FLOAT, 0, vertices);
 glDrawArrays(GL_POINTS, 0, segments/2);
 return midPoint;
}

这将根据三点进行抽奖。控件是中点,您需要返回。新的中点将与之前的不同。此外,如果您浏览上面的代码,它只会绘制一半的行。下一个笔划将填充它。这是必需的。我调用这个函数的代码(上面是C语言,这是在Obj-C中):

That will draw based on three points. The control is the midpoint, which you need to return. The new midpoint will be different than the previous. Also, if you go through the above code, it will only draw half the line. The next stroke will fill it in. This is required. my code for calling this function (the above is in C, this is in Obj-C):

   //Invert the Y axis to conform the iPhone top-down approach
   invertedYBegCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i] CGPointValue].y;
   invertedYEndCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i+1] CGPointValue].y;
   invertedYThirdCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i+2] CGPointValue].y;
   //Figure our how many dots you need
   count = MAX(ceilf(sqrtf(([[currentStroke objectAtIndex:i+2] CGPointValue].x - [[currentStroke objectAtIndex:i] CGPointValue].x) 
         * ([[currentStroke objectAtIndex:i+2] CGPointValue].x - [[currentStroke objectAtIndex:i] CGPointValue].x) 
         + ((invertedYThirdCoord - invertedYBegCoord) * (invertedYThirdCoord - invertedYBegCoord))) / pointCount), 1);

   newMidPoint = drawBezier(CGPointMake([[currentStroke objectAtIndex:i] CGPointValue].x, invertedYBegCoord), CGPointMake([[currentStroke objectAtIndex:i+1] CGPointValue].x, invertedYEndCoord), CGPointMake([[currentStroke objectAtIndex:i+2] CGPointValue].x, invertedYThirdCoord), count);

   int loc = [currentStroke count]-1;
   [currentStroke insertObject:[NSValue valueWithCGPoint:newMidPoint] atIndex:loc];
   [currentStroke removeObjectAtIndex:loc-1];

该代码将根据倒置的iPad点获得中点,并将控制设置为目前的观点。

That code will get the mid point based on inverted iPad points, and set the 'control' as the current point.

这将平滑边缘。现在关于线宽,您只需要找到该绘图的速度。找到你的线的长度是最容易的。这可以使用组件数学轻松完成。我没有任何代码,但此处是来自物理场所的组件数学的入门读物。或者您可以简单地将(上方)计数除以某个数字,以找出您需要的线厚度(计数使用组件数学)。

That will smooth out the edges. Now regarding the line width, you just need to find the speed of that drawing. It is easiest just to find the length of your line. This is easily done using component mathematics. I don't have any code for it, but here is a primer for component mathmatics from a physics site. Or you can simply divide (above) count by some number to find out how thick you need the line to be (count uses component mathematics).

我将点数据存储在一个名为currentStroke的数组,如果不明显的话。

I store point data in an array called currentStroke, in case it wasn't obvious.

这应该是你所需要的。

编辑:

要存储积分,您应该使用touchesBegin和touchesEnd:

To store points, you should use touchesBegin and touchesEnd:

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    self.currentStroke = [NSMutableArray array];
    CGPoint point = [ [touches anyObject] locationInView:self];
    [currentStroke addObject:[NSValue valueWithCGPoint:point]];
    [self draw];

}

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    CGPoint point = [ [touches anyObject] locationInView:self];
    [currentStroke addObject:[NSValue valueWithCGPoint:point]];
    [self draw];
}


- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint point = [ [touches anyObject] locationInView:self];
    [currentStroke addObject:[NSValue valueWithCGPoint:point]];
    [self draw];
}

这几乎就是整个绘图应用程序。如果您正在使用GL_Paint,那么您已经在使用此系统构建的点精灵。

That is pretty much an entire drawing application there. If you are using GL_Paint, then you are already using point sprites, which this system is build on.

这篇关于使用OpenGL在iPad上绘制应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆