我正在尝试使用NSOpenGL
山狮在 OpenGL 中绘制一个非常简单的带有红色背景的蓝色正方形。代码很简单,应该可以工作,我假设这是我设置上下文的问题。
这是我的 GLView 界面:
#import <Cocoa/Cocoa.h>
#import <OpenGL/gl.h>
#import <GLKit/GLKit.h>
typedef struct {
char *Name;
GLint Location;
} Uniform;
@interface MyOpenGLView : NSOpenGLView {
Uniform *_uniformArray;
int _uniformArraySize;
GLKMatrix4 _projectionMatrix;
GLKMatrix4 _modelViewMatrix;
IBOutlet NSWindow *window;
int height, width;
}
-(void)drawRect:(NSRect)bounds;
@end
实施:
GLfloat square[] = {
-0.5, -0.5,
0.5, -0.5,
-0.5, 0.5,
0.5, 0.5
};
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
-(void)awakeFromNib {
NSString *vertexShaderSource = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"VertexShader" ofType:@"vsh"] encoding:NSUTF8StringEncoding error:nil];
const char *vertexShaderSourceCString = [vertexShaderSource cStringUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%s",vertexShaderSourceCString);
NSString *fragmentShaderSource = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"FragmentShader" ofType:@"fsh"] encoding:NSUTF8StringEncoding error:nil];
const char *fragmentShaderSourceCString = [fragmentShaderSource cStringUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%s",fragmentShaderSourceCString);
NSOpenGLContext *glContext = [self openGLContext];
[glContext makeCurrentContext];
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSourceCString, NULL);
glCompileShader(fragmentShader);
GLint compileSuccess;
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE) {
GLint logLength;
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &logLength);
if(logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetShaderInfoLog(fragmentShader, logLength, &logLength, log);
NSLog(@"Shader compile log:\n%s", log);
free(log);
}
exit(1);
}
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSourceCString, NULL);
glCompileShader(vertexShader);
GLuint program = glCreateProgram();
glAttachShader(program, fragmentShader);
glAttachShader(program, vertexShader);
glLinkProgram(program);
glUseProgram(program);
const char *aPositionCString = [@"a_position" cStringUsingEncoding:NSUTF8StringEncoding];
GLuint aPosition = glGetAttribLocation(program, aPositionCString);
glVertexAttribPointer(aPosition, 2, GL_FLOAT, GL_FALSE, 0, square);
glEnable(aPosition);
GLint maxUniformLength;
GLint numberOfUniforms;
char *uniformName;
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numberOfUniforms);
glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformLength);
_uniformArray = malloc(numberOfUniforms * sizeof(Uniform));
_uniformArraySize = numberOfUniforms;
for (int i =0; i <numberOfUniforms; i++) {
GLint size;
GLenum type;
GLint location;
uniformName = malloc(sizeof(char*)*maxUniformLength);
glGetActiveUniform(program, i, maxUniformLength, NULL, &size, &type, uniformName);
_uniformArray[i].Name = uniformName;
location = glGetUniformLocation(program, uniformName);
_uniformArray[i].Location = location;
}
_modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 0.0f);
_projectionMatrix = GLKMatrix4MakeOrtho(-1, 1, -1.5, 1.5, -1, 1);
}
- (void)drawRect:(NSRect)bounds {
glClearColor(1.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, 480, 360);
for (int i = 0; i <_uniformArraySize; i++) {
if (strcmp(_uniformArray[i].Name, "ModelViewProjectionMatrix")==0) {
// Multiply the transformation matrices together
GLKMatrix4 modelViewProjectionMatrix = GLKMatrix4Multiply(_projectionMatrix, _modelViewMatrix);
glUniformMatrix4fv(_uniformArray[i].Location, 1, GL_FALSE, modelViewProjectionMatrix.m);
}
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glFlush();
}
我非常简单的片段着色器:
void main() {
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}
简单的顶点着色器:
attribute vec4 a_position;
uniform mat4 ModelViewProjectionMatrix;
void main() {
gl_Position = a_position * ModelViewProjectionMatrix;
}
我没有编译错误,只是一个红色的屏幕,没有蓝色的方块。有人可以帮我找出问题所在。不过,我确实收到了警告,指出 Gl.h 和 gl3.h 都包括在内。我想使用 OpenGL 2