xcode 函数“glBindVertexArrayOES”的隐式声明在 c99 中无效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25250305/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Implicit Declaration of function 'glBindVertexArrayOES' is invalid in c99
提问by Eoin Lavery
So I am building a system monitoring app for iPhone and iPad. Anytime I try to compile the application I am getting an error that says "Implicit Declaration of function 'glBindVertexArrayOES' is invalid in c99"
所以我正在为 iPhone 和 iPad 构建一个系统监控应用程序。每当我尝试编译应用程序时,都会收到一条错误消息,提示“函数‘glBindVertexArrayOES’的隐式声明在 c99 中无效”
#import "AMUtils.h"
#import "AppDelegate.h"
#import "GLCommon.h"
#import "GLLineGraph.h"
#import "GLDataLine.h"
@interface GLDataLine()
@property (nonatomic, weak) GLLineGraph *graph;
@property (nonatomic, assign) GLuint glVertexArrayDataLine;
@property (nonatomic, assign) GLuint glBufferDataLine;
@property (nonatomic, assign) VertexData_t *dataLineData;
@property (nonatomic, assign) NSUInteger dataLineDataSize;
@property (nonatomic, assign) GLuint dataLineDataValidSize; /* Valid buffer index count */
@property (nonatomic, assign) GLuint dataLineDataCurrIdx; /* Current index to be written new values to */
@property (nonatomic, assign) GLfloat dataLineDataNextX; /* Each added data element gets it's own unique X position */
/* dataLineData is a circular array and so in order to utilize GL_LINE_STRIP without creating an
* impression of GL_LINE_LOOP we declare 2 matrixes.
* The first translates 0 - dataLineDataCurrIdx verticies.
* The second translates dataLineDataCurrIdx+1 - dataLineDataValidSize-1 verticies. */
@property (nonatomic, assign) GLKVector3 dataLinePosition1;
@property (nonatomic, assign) GLKVector3 dataLinePosition2;
@property (nonatomic, assign) GLuint glVertexArrayLineLegend;
@property (nonatomic, assign) GLuint glBufferLineLegend;
@property (nonatomic, strong) GLKTextureInfo *lineLegendTextTexture;
@property (nonatomic, strong) GLKTextureInfo *lineLegendIconTexture;
@property (nonatomic, assign) GLfloat zoom;
- (void)setupVBO;
- (void)renderDataLine;
- (void)tearDownGL;
@end
@implementation GLDataLine
@synthesize color;
@synthesize graph;
@synthesize glVertexArrayDataLine=_glVertexArrayDataLine;
@synthesize glBufferDataLine=_glBufferDataLine;
@synthesize dataLineData=_dataLineData;
@synthesize dataLineDataSize=_dataLineDataSize;
@synthesize dataLineDataValidSize=_dataLineDataValidSize;
@synthesize dataLineDataCurrIdx=_dataLineDataCurrIdx;
@synthesize dataLineDataNextX=_dataLineDataNextX;
@synthesize dataLinePosition1=_dataLinePosition1;
@synthesize dataLinePosition2=_dataLinePosition2;
@synthesize glVertexArrayLineLegend=_glVertexArrayLineLegend;
@synthesize glBufferLineLegend=_glBufferLineLegend;
@synthesize lineLegendTextTexture;
@synthesize lineLegendIconTexture;
@synthesize zoom;
static const GLfloat kDataLineShiftSize = 0.25;
static const VertexData_t lineLegendData[] = {
{{ 0.0, 0.0, kModelZ }, { 0.0, 0.0 }},
{{ 1.0, 0.0, kModelZ }, { 1.0, 0.0 }},
{{ 0.0, 1.0, kModelZ }, { 0.0, 1.0 }},
{{ 1.0, 1.0, kModelZ }, { 1.0, 1.0 }}
};
#pragma mark - public
- (id)initWithColor:(UIColor*)aColor forGraph:(GLLineGraph*)aGraph
{
if (self = [super init])
{
self.color = aColor;
self.graph = aGraph;
self.dataLineDataValidSize = 0;
self.dataLineDataCurrIdx = 0;
self.dataLineDataSize = (self.graph.graphRight - self.graph.graphLeft) / kDataLineShiftSize;
_dataLineData = malloc(self.dataLineDataSize * sizeof(VertexData_t));
self.zoom = 1.0;
[self resetLineData];
[self setupVBO];
}
return self;
}
- (void)dealloc
{
[self tearDownGL];
free(_dataLineData);
}
- (void)addLineDataValue:(double)value
{
GLfloat vX = self.dataLineDataNextX++;
GLfloat vY = [AMUtils percentageValueFromMax:self.graph.graphTop-self.graph.graphBottom min:0.0 percent:value];
BOOL bufferSizeIncreased = NO;
if (self.dataLineDataValidSize == 0)
{
self.dataLineData[0].positionCoords.x = vX;
self.dataLineData[0].positionCoords.y = vY;
self.dataLineData[0].positionCoords.z = kModelZ;
self.dataLineDataCurrIdx++;
self.dataLineDataValidSize++;
bufferSizeIncreased = YES;
}
else
{
self.dataLineData[self.dataLineDataCurrIdx].positionCoords.x = vX;
self.dataLineData[self.dataLineDataCurrIdx].positionCoords.y = vY;
self.dataLineData[self.dataLineDataCurrIdx].positionCoords.z = kModelZ;
if (self.dataLineDataCurrIdx == 0)
{
// Previous data add wrapped the lines.
// It's best to set last value Y to current Y or otherwise the line might have a gap.
// It is quite an ugly solution because the previous data will be lost, but I can't
// figure anything better now.
self.dataLineData[self.dataLineDataSize-1].positionCoords.y = vY;
}
self.dataLineDataCurrIdx++;
if (self.dataLineDataValidSize < self.dataLineDataSize)
{
self.dataLineDataValidSize++;
bufferSizeIncreased = YES;
}
}
// Check if we need to wrap the circular data line buffer.
if (self.dataLineDataCurrIdx >= self.dataLineDataSize)
{
// First we move the first data position vector to the second in order to keep the old values moving.
// It is assumed that the old values which dataLinePosition2 was moving before this assignment
// are already offscreen.
self.dataLinePosition2 = self.dataLinePosition1;
// Then re-init the first data position vector to starting position.
GLfloat xTranslate = self.graph.graphRight;
self.dataLinePosition1 = GLKVector3Make(xTranslate, self.graph.graphBottom, kModelZ);
self.dataLineDataNextX = 0;
self.dataLineDataCurrIdx = 0;
}
else
{
// Shift data line translation matrixes.
GLKVector3 shift = GLKVector3Make(-kDataLineShiftSize, 0.0, 0.0);
self.dataLinePosition1 = GLKVector3Add(self.dataLinePosition1, shift);
self.dataLinePosition2 = GLKVector3Add(self.dataLinePosition2, shift);
}
glBindBuffer(GL_ARRAY_BUFFER, self.glBufferDataLine);
if (bufferSizeIncreased)
{
glBufferData(GL_ARRAY_BUFFER,
self.dataLineDataValidSize * sizeof(VertexData_t),
_dataLineData, GL_DYNAMIC_DRAW);
}
else
{
glBufferSubData(GL_ARRAY_BUFFER, 0,
self.dataLineDataValidSize * sizeof(VertexData_t),
_dataLineData);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
- (void)addLineDataArray:(NSArray*)dataArray
{
}
- (void)resetLineData
{
GLfloat xTranslate = self.graph.graphRight;
self.dataLinePosition1 = GLKVector3Make(xTranslate, self.graph.graphBottom, kModelZ);
self.dataLinePosition2 = GLKVector3Make(xTranslate, self.graph.graphBottom, kModelZ);
self.dataLineDataValidSize = 0;
self.dataLineDataCurrIdx = 0;
self.dataLineDataNextX = 0;
}
- (void)setLineDataLegendText:(NSString*)text
{
// Apparently GLKTextureInfo leaks memory if you don't delete textures explicitly.
if (self.lineLegendTextTexture)
{
GLuint texture = self.lineLegendTextTexture.name;
glDeleteTextures(1, &texture);
}
UIImage *tex = [GLCommon imageWithText:text font:[UIFont fontWithName:@"Verdana" size:22.0] color:self.color];
self.lineLegendTextTexture = [GLKTextureLoader textureWithCGImage:tex.CGImage options:nil error:nil];
}
- (void)setDataLineLegendIcon:(UIImage*)image
{
NSError *error = nil;
self.lineLegendIconTexture = [GLKTextureLoader textureWithCGImage:image.CGImage options:nil error:&error];
if (lineLegendIconTexture == nil)
{
AMLogError(@"GLKTextureLoader failed to load texture: %@", [error localizedDescription]);
}
}
- (void)render
{
if (self.dataLineDataValidSize == 0)
{
// No verticies to draw.
return;
}
[self renderDataLine];
}
- (void)renderLegend:(NSUInteger)lineIndex
{
/*
* Icon
*/
if (self.lineLegendIconTexture)
{
GLfloat x = self.graph.graphRight - 6.5 - (lineIndex * 9.0);
GLfloat y = self.graph.graphBottom - 1.2;
GLfloat xScale = 1.0 * (self.lineLegendIconTexture.width / self.lineLegendIconTexture.height);
GLfloat yScale = 1.0;
This is the next line of code which gives me an error
这是下一行代码,它给了我一个错误
glBindVertexArrayOES(self.glVertexArrayLineLegend);
Then this is the rest of the code
然后这是剩下的代码
GLKVector3 position = GLKVector3Make(x, y, 0.0);
GLKVector3 rotation = GLKVector3Make(0.0, 0.0, 0.0);
GLKMatrix4 scale = GLKMatrix4MakeScale(xScale, yScale, 1.0);
GLKMatrix4 modelMatrix = [GLCommon modelMatrixWithPosition:position rotation:rotation scale:scale];
self.graph.effect.transform.modelviewMatrix = modelMatrix;
self.graph.effect.texture2d0.enabled = GL_TRUE;
self.graph.effect.texture2d0.target = GLKTextureTarget2D;
self.graph.effect.texture2d0.name = self.lineLegendIconTexture.name;
self.graph.effect.texture2d0.envMode = GLKTextureEnvModeReplace;
[self.graph.effect prepareToDraw];
glDrawArrays(GL_TRIANGLE_STRIP, 0, sizeof(lineLegendData) / sizeof(VertexData_t));
}
/*
* Text
*/
if (self.lineLegendTextTexture)
{
GLfloat x = self.graph.graphRight - 5.0 - (lineIndex * 9.0);
GLfloat y = self.graph.graphBottom - 1.0;
GLfloat xScale = self.lineLegendTextTexture.width * kFontScaleMultiplierW;
GLfloat yScale = self.lineLegendTextTexture.height * kFontScaleMultiplierH;
glBindVertexArrayOES(self.glVertexArrayLineLegend);
GLKVector3 position = GLKVector3Make(x, y, 0.0);
GLKVector3 rotation = GLKVector3Make(0.0, 0.0, 0.0);
GLKMatrix4 scale = GLKMatrix4MakeScale(xScale, yScale, 1.0);
GLKMatrix4 modelMatrix = [GLCommon modelMatrixWithPosition:position rotation:rotation scale:scale];
self.graph.effect.transform.modelviewMatrix = modelMatrix;
self.graph.effect.texture2d0.enabled = GL_TRUE;
self.graph.effect.texture2d0.target = GLKTextureTarget2D;
self.graph.effect.texture2d0.name = self.lineLegendTextTexture.name;
self.graph.effect.texture2d0.envMode = GLKTextureEnvModeReplace;
[self.graph.effect prepareToDraw];
glDrawArrays(GL_TRIANGLE_STRIP, 0, sizeof(lineLegendData) / sizeof(VertexData_t));
}
}
- (NSUInteger)maxDataLineElements
{
return self.dataLineDataSize;
}
- (void)setDataLineZoom:(GLfloat)aZoom
{
self.zoom = aZoom;
}
#pragma mark - private
- (void)setupVBO
{
/*
* Data line.
*/
{
This next line also throws up the same c99 error
下一行也抛出相同的 c99 错误
glGenVertexArraysOES(1, &_glVertexArrayDataLine);
And the other code is as follows:
另一个代码如下:
glBindVertexArrayOES(self.glVertexArrayDataLine);
glGenBuffers(1, &_glBufferDataLine);
glBindBuffer(GL_ARRAY_BUFFER, self.glBufferDataLine);
glBufferData(GL_ARRAY_BUFFER, self.dataLineDataValidSize * sizeof(VertexData_t), _dataLineData, GL_DYNAMIC_DRAW);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData_t),
NULL + offsetof(VertexData_t, positionCoords));
glEnableVertexAttribArray(GLKVertexAttribPosition);
GL_CHECK_ERROR();
}
/*
* Line legend.
*/
{
glGenVertexArraysOES(1, &_glVertexArrayLineLegend);
glBindVertexArrayOES(self.glVertexArrayLineLegend);
glGenBuffers(1, &_glBufferLineLegend);
glBindBuffer(GL_ARRAY_BUFFER, self.glBufferLineLegend);
glBufferData(GL_ARRAY_BUFFER, sizeof(lineLegendData), lineLegendData, GL_STATIC_DRAW);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData_t),
NULL + offsetof(VertexData_t, positionCoords));
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData_t),
NULL + offsetof(VertexData_t, textureCoords));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
}
}
- (void)renderDataLine
{
GLfloat yScale = 1.0 / self.zoom;
/*
* Render the first batch starting from 0 to self.dataLineDataCurrIdx.
*/
{
GLfloat yScale = 1.0 / self.zoom;
glBindVertexArrayOES(self.glVertexArrayDataLine);
GLKVector3 position = self.dataLinePosition1;
GLKVector3 rotation = GLKVector3Make(0.0, 0.0, 0.0);
GLKMatrix4 scale = GLKMatrix4MakeScale(kDataLineShiftSize, yScale, 1.0);
GLKMatrix4 modelMatrix = [GLCommon modelMatrixWithPosition:position rotation:rotation scale:scale];
self.graph.effect.transform.modelviewMatrix = modelMatrix;
self.graph.effect.useConstantColor = YES;
self.graph.effect.texture2d0.enabled = NO;
const CGFloat *components = CGColorGetComponents(self.color.CGColor);
self.graph.effect.constantColor = GLKVector4Make(components[0], components[1], components[2], CGColorGetAlpha(self.color.CGColor));
[self.graph.effect prepareToDraw];
DeviceSpecificUI *ui = [AppDelegate sharedDelegate].deviceSpecificUI;
glLineWidth(ui.GLdataLineWidth);
glDrawArrays(GL_LINE_STRIP, 0, self.dataLineDataCurrIdx);
GL_CHECK_ERROR();
}
/*
* Render the second batch starting from self.dataLineDataCurrIdx+1 to the end.
*/
if (self.dataLineDataValidSize > self.dataLineDataCurrIdx)
{
glBindVertexArrayOES(self.glVertexArrayDataLine);
GLKVector3 position = self.dataLinePosition2;
GLKVector3 rotation = GLKVector3Make(0.0, 0.0, 0.0);
GLKMatrix4 scale = GLKMatrix4MakeScale(kDataLineShiftSize, yScale, 1.0);
GLKMatrix4 modelMatrix = [GLCommon modelMatrixWithPosition:position rotation:rotation scale:scale];
self.graph.effect.transform.modelviewMatrix = modelMatrix;
self.graph.effect.useConstantColor = YES;
const CGFloat *components = CGColorGetComponents(self.color.CGColor);
self.graph.effect.constantColor = GLKVector4Make(components[0], components[1], components[2], CGColorGetAlpha(self.color.CGColor));
self.graph.effect.texture2d0.enabled = NO;
[self.graph.effect prepareToDraw];
DeviceSpecificUI *ui = [AppDelegate sharedDelegate].deviceSpecificUI;
glLineWidth(ui.GLdataLineWidth);
glDrawArrays(GL_LINE_STRIP, self.dataLineDataCurrIdx, self.dataLineDataValidSize - self.dataLineDataCurrIdx);
GL_CHECK_ERROR();
}
}
- (void)tearDownGL
{
// Apparently GLKTextureInfo leaks memory if you don't delete textures explicitly.
if (self.lineLegendIconTexture)
{
GLuint texture = self.lineLegendIconTexture.name;
glDeleteTextures(1, &texture);
}
if (self.lineLegendTextTexture)
{
GLuint texture = self.lineLegendTextTexture.name;
glDeleteTextures(1, &texture);
}
if (self.glBufferDataLine)
{
glDeleteBuffers(1, &_glBufferDataLine);
}
if (self.glBufferLineLegend)
{
glDeleteBuffers(1, &_glBufferLineLegend);
}
if (self.glVertexArrayDataLine)
{
And the final c99 error comes here in this next line:
最后的 c99 错误出现在下一行:
glDeleteVertexArraysOES(1, &_glVertexArrayDataLine);
And this is the last piece of code after that:
这是之后的最后一段代码:
}
if (self.glVertexArrayLineLegend)
{
glDeleteVertexArraysOES(1, &_glVertexArrayLineLegend);
}
GL_CHECK_ERROR();
}
@end
So as you can guess I have no clue how this issue is to be solved. Im hoping someone here can help? Many thanks in advance!
所以你可以猜到我不知道如何解决这个问题。我希望这里有人可以提供帮助?提前谢谢了!
回答by Gwynne Raskind
This is usually solved by importing the appropriate OpenGLES
header, i.e.:
这通常通过导入适当的OpenGLES
标头来解决,即:
#import <OpenGLES/ES2/glext.h>
or
或者
#import <OpenGLES/ES1/glext.h>
Depending on which version of OpenGL you're using.
取决于您使用的 OpenGL 版本。
回答by Tajinder singh
I have faced the same issue.
我遇到了同样的问题。
The easiest way to resolve this problem is by adding #import < OpenGLES/ES2/glext.h > line in .pch file.
解决此问题的最简单方法是在 .pch 文件中添加 #import < OpenGLES/ES2/gleext.h > 行。