Ios OpenGL循环不工作
我试着画一个圆圈,但不知怎么搞得一团糟Ios OpenGL循环不工作,ios,opengl-es,Ios,Opengl Es,我试着画一个圆圈,但不知怎么搞得一团糟 typedef struct { float Position[3]; float Color[4]; } Vertex; Vertex* Vertices; //vertices store information for each "point" used to draw a triangle GLubyte* Indices; //Used to reuse vertices //const GLushort Indices
typedef struct {
float Position[3];
float Color[4];
} Vertex;
Vertex* Vertices; //vertices store information for each "point" used to draw a triangle
GLubyte* Indices; //Used to reuse vertices
//const GLushort Indices[] = {
// 0, 1, 2,
// 2, 3,
// 3, 4
//};
int points = 181;
@interface CometGLViewController (){
float _curRed;
BOOL _increasing;
GLuint _vertexBuffer;
GLuint _indexBuffer;
GLuint _vertexArray;
float _rotation;
}
@property (strong, nonatomic) EAGLContext *context;
@property (strong, nonatomic) GLKBaseEffect *effect;
@end
@implementation CometGLViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
# pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!self.context) {
NSLog(@"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableMultisample = GLKViewDrawableMultisample4X;
[self setupVertices];
[self setupGL];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[self tearDownGL];
if ([EAGLContext currentContext] == self.context) {
[EAGLContext setCurrentContext:nil];
}
self.context = nil;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - GLKViewDelegate
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0, 0, 0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
[self.effect prepareToDraw];
glBindVertexArrayOES(_vertexArray);
glDrawElements(GL_TRIANGLES, points * 2 + 1, GL_UNSIGNED_BYTE, 0);
}
#pragma mark - GLKViewControllerDelegate
- (void)update
{
if (_increasing) {
_curRed += 1.0 * self.timeSinceLastUpdate;
} else {
_curRed -= 1.0 * self.timeSinceLastUpdate;
}
if (_curRed >= 1.0) {
_curRed = 1.0;
_increasing = NO;
}
if (_curRed <= 0.0) {
_curRed = 0.0;
_increasing = YES;
}
//Rotate
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 4.0f, 15.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -6.0f);
//_rotation += 90 * self.timeSinceLastUpdate;
//modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(_rotation), 0, 0, 1);
self.effect.transform.modelviewMatrix = modelViewMatrix;
}
#pragma mark - OpenGL stuff
- (void)setupGL {
[EAGLContext setCurrentContext:self.context];
glEnable(GL_CULL_FACE);
self.effect = [[GLKBaseEffect alloc] init];
// ----- Setup textures
// NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
// [NSNumber numberWithBool:YES],
// GLKTextureLoaderOriginBottomLeft,
// nil];
//
// NSError * error;
// NSString *path = [[NSBundle mainBundle] pathForResource:@"tile_floor" ofType:@"png"];
// GLKTextureInfo * info = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
// if (info == nil) {
// NSLog(@"Error loading file: %@", [error localizedDescription]);
// }
//
// self.effect.texture2d0.name = info.name;
// self.effect.texture2d0.enabled = true;
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
// ----- create new buffer, work with "vertexBuffer", glBufferData sends data for opengl usage
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * points, Vertices, GL_STATIC_DRAW);
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * (points * 2 + 1), Indices, GL_STATIC_DRAW);
// ----- Setup vertices attributes
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Color));
}
- (void)tearDownGL {
[EAGLContext setCurrentContext:self.context];
glDeleteBuffers(1, &_vertexBuffer);
glDeleteBuffers(1, &_indexBuffer);
glDeleteVertexArraysOES(1, &_vertexArray);
self.effect = nil;
}
- (void)setupVertices
{
Vertices = malloc(sizeof(Vertex) * points);
Vertex v = {{0, 0, 0}, {0, 0, 1, 1}};
Vertices[0] = v;
GLubyte ind[points *2 +1];
ind[0] = 0;
int indPos = 1;
for(int i = 1; i < points; ++i){
float theta = 2.0 * 3.1415926 * ( ((float)i-1)*2 / (float)points );
Vertex v = {{cosf(theta), sinf(theta), 0}, {1, 1, 0, 1}};
Vertices[i] = v;
ind[indPos] = i;
if(i != points-1)
ind[indPos + 1] = i+1;
else
ind[indPos +1] = 1;
indPos = indPos +2;
NSLog(@"%f und %f", cosf(theta), sinf(theta));
NSLog(@"%i und %i", i, i+1);
}
Indices = ind;
}
#pragma mark - Touch control
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.paused = !self.paused;
}
@end
typedef结构{
浮动位置[3];
浮色[4];
}顶点;
顶点*顶点//顶点存储用于绘制三角形的每个“点”的信息
GLubyte*索引//用于重用顶点
//常量短索引[]={
// 0, 1, 2,
// 2, 3,
// 3, 4
//};
积分=181;
@接口:GLViewController(){
浮动汇率;
布尔值增加;
GLuint_顶点缓冲区;
胶合指数缓冲;
胶合垂直排列;
浮动旋转;
}
@属性(强,非原子)EAGLContext*上下文;
@性质(强、非原子)GLKBaseEffect*效应;
@结束
@视图控制器的实现
-(id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil
{
self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
如果(自我){
//自定义初始化
}
回归自我;
}
#pragma标记-视图生命周期
-(无效)viewDidLoad
{
[超级视图下载];
self.context=[[EAGLContext alloc]initWithAPI:keagrenderingapiopengles2];
if(!self.context){
NSLog(@“未能创建ES上下文”);
}
GLKView*视图=(GLKView*)self.view;
view.context=self.context;
view.drawableMultisample=GLKViewDrawableMultisample4X;
[自我设置];
[自设置GL];
}
-(无效)视图卸载
{
[超级视频下载];
[自毁];
if([EAGLContext currentContext]==self.context){
[EAGLContext setCurrentContext:nil];
}
self.context=nil;
}
-(无效)未收到记忆警告
{
[超级记忆警告];
//处置所有可以重新创建的资源。
}
#pragma标记-GLKViewDelegate
-(void)glkView:(glkView*)视图drawInRect:(CGRect)rect
{
glClearColor(0,0,0,1.0);
glClear(GLU颜色缓冲位);
[自生效准备提款];
GLBindVertexarray(_vertexArray);
GLD元素(GLU三角形,点*2+1,GLU无符号字节,0);
}
#pragma标记-GLKViewControllerDelegate
-(作废)更新
{
如果(_增加){
_curRed+=1.0*self.timesInclastUpdate;
}否则{
_curRed-=1.0*self.timesInclastUpdate;
}
如果(\u curRed>=1.0){
_curRed=1.0;
_增加=否;
}
如果(_curRed您正在使用
GLubyte ind[points*3];
但是你有
int points = 360;
由于ubyte只有8位,您最多可以处理256个不同的顶点,这说明您没有得到一个完整的圆,只有256度。然而,我认为可能还有其他问题,因为我不明白这个错误如何解释您使用的屏幕截图中的所有问题…
GLubyte ind[points*3];
但是你有
int points = 360;
由于ubyte只有8位,您最多可以处理256个不同的顶点,这说明您没有得到一个完整的圆,只有256度。然而,我认为可能还有其他问题,因为我不明白这个错误如何解释您屏幕截图中的所有问题…对于您使用的基本模式,您的索引是错误的。
它们是按扇形顺序排列的,但随后您将GL\u TRIANGLE\u fan
作为基本类型传递给glpaurements(…)
。这不是冗余问题,这完全是错误的。您有3N个索引,这意味着与这些索引一起使用的唯一逻辑基本模式是GL\u TRIANGLES
目前,在调用glpaurements(…)
时,只需将GL_三角形
替换为GL_三角形
,即可解决此问题,但这不会获得针对三角形邻接进行优化的基本模式的好处。
我将在下面解释一个更好的解决方案,它将减少索引数组的必要大小,并正确使用GL\u TRIANGLE\u FAN
根据以下代码判断:
我可以得出结论,你的思路是正确的,只是你忘了扇形不是由每个三角形的3个索引定义的;扇形中的每个附加三角形共享一个公共中心顶点,并重复使用最后一个顶点。因此,索引的数量是N+2,其中N是三角形的数量
你要做的是用你的索引沿着圆的周长走,你将生成一个V-2三角形,其中V是圆周长上的顶点数。如果你纠正了你的索引,那么你应该得到一个很好的三角化圆(或者近似于一个的圆)
从视觉上看,三角形风扇就是这样工作的:
每个三角形共享中心顶点A
,并重新使用最后一个寻址的顶点。因此,定义ABC
后,每个后续三角形只需要1个点(例如D
,e
,F
)
另一种思考方式是,每个三角形与前面的三角形共享一条从中心顶点辐射的边;就像纸扇一样
更新:
我相信这会解决您的问题,索引的数量实际上会匹配一个适当扇形圆中的顶点数量。我对与上面顶点相关的三角形数量的讨论可能会产生一些混乱,三角形的数量实际上在代码中的任何地方都没有定义
- (void)setupVertices
{
Vertices = malloc(sizeof(Vertex) * points);
Vertex v = {{0, 0, 0}, {0, 0, 1, 1}};
Vertices[0] = v;
GLubyte ind[points];
ind[0] = 0;
int indPos = 1;
for(int i = 1; i < points; ++i){
float theta = 2.0 * 3.1415926 * ( ((float)i-1)*2 / (float)points );
Vertex v = {{cosf(theta), sinf(theta), 0}, {1, 1, 0, 1}};
Vertices[i] = v;
ind[indPos] = i;
NSLog(@"%f und %f", cosf(theta), sinf(theta));
NSLog(@"%i und %i", i, i+1);
}
Indices = ind;
}
-(无效)设置顶点
{
顶点=malloc(sizeof(顶点)*点);
顶点v={0,0,0},{0,0,1,1};
顶点[0]=v;
GLubyte ind[点];
ind[0]=0;
int indPos=1;
对于(int i=1;i
现在,当需要绘制扇形时,您将使用许多索引点。顺便说一句,您甚至不需要索引顶点渲染来高效地绘制扇形;索引都是连续的。gldrawArray(GL_Triange