0
我想繪製一些使用OpenGL與VAO和VBO對象的東西。要做到這一點,我只需要分類NSOpenGLView
。默認情況下,使用OpenGL v2.1,所以,我放了一個PixelFormat
,編寫代碼,並解決了所有打印錯誤。目前該應用運行良好,但沒有任何東西在窗口繪製,即使glClearColor
也沒有效果。請幫助我找到並解決問題。我的操作系統是帶有OpenGL v4.1的Mac v10.12。OpenGL在Mac上沒有繪製任何東西,Objective-C
MyOpenGLView.m,第1部分:
#import "MyOpenGLView.h"
#include <OpenGL/gl3.h>
#include "error.h"
static const char *vertexShaderSource =
"#version 410\n"
"in vec3 posAttr;\n"
"in vec3 colAttr;\n"
"out vec3 col;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position.xyz = posAttr;\n"
" gl_Position.w = 1.0;\n"
" col = colAttr;\n"
"}\n";
static const char *fragmentShaderSource =
"#version 410\n"
"in vec3 col;\n"
"out vec4 color;\n"
"void main() {\n"
" color.rgb = col;\n"
" color.a = 1.0;\n"
//" color = vec4(1,1,1,1);\n"
"}\n";
// Shader properties
GLuint m_posAttr;
GLuint m_colAttr;
GLuint program;
// Arrays of positions and colors
float fTriangle[9];
float fTriangleColor[9];
// Low-level VBOs and VBAs
GLuint uiVBO[2];
GLuint uiVAO[1];
GLuint makeShader(GLenum type, const char *source) {
GLuint shader;
shader = glCreateShader(type);
GetError();
glShaderSource(shader, 1, &source, NULL);
GetError();
glCompileShader(shader);
GetError();
#if defined(DEBUG)
GLint logLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
GetError();
if (logLength > 0) {
GLchar *log = malloc((size_t)logLength);
glGetShaderInfoLog(shader, logLength, &logLength, log);
GetError();
NSLog(@"Shader compilation failed with error:\n%s", log);
free(log);
}
#endif
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
GetError();
if (0 == status) {
glDeleteShader(shader);
GetError();
NSLog(@"Shader compilation failed from code!");
assert(0);
}
return shader;
}
MyOpenGLView.m,第2部分:
//// General staff
@implementation MyOpenGLView
- (void)awakeFromNib {
// Positions and colors of figures
fTriangle[0] = -0.4f; fTriangle[1] = 0.1f; fTriangle[2] = 0.0f;
fTriangle[3] = 0.4f; fTriangle[4] = 0.1f; fTriangle[5] = 0.0f;
fTriangle[6] = 0.0f; fTriangle[7] = 0.7f; fTriangle[8] = 0.0f;
fTriangleColor[0] = 1.0f; fTriangleColor[1] = 0.0f; fTriangleColor[2] = 0.0f;
fTriangleColor[3] = 0.0f; fTriangleColor[4] = 1.0f; fTriangleColor[5] = 0.0f;
fTriangleColor[6] = 0.0f; fTriangleColor[7] = 0.0f; fTriangleColor[8] = 1.0f;
NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAOpenGLProfile,
NSOpenGLProfileVersion4_1Core,
0
};
NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
if (!pf) {
NSLog(@"No OpenGL pixel format");
}
NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil];
[self setPixelFormat:pf];
[self setOpenGLContext:context];
NSLog(@"%s", glGetString(GL_VERSION));
GetError();
GLuint vertexShader = makeShader(GL_VERTEX_SHADER, vertexShaderSource);
GLuint fragmentShader = makeShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
program = glCreateProgram();
GetError();
glAttachShader(program, vertexShader);
GetError();
glAttachShader(program, fragmentShader);
GetError();
glLinkProgram(program);
GetError();
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
GetError();
if (0 == status) {
NSLog(@"Failed to link shader program");
assert(0);
}
m_posAttr = glGetAttribLocation(program, "posAttr");
GetError();
m_colAttr = glGetAttribLocation(program, "colAttr");
GetError();
glGenVertexArrays(1, &uiVAO[0]);
glGenBuffers(2, &uiVBO[0]);
GetError();
}
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
GetError();
glBindVertexArray(uiVAO[0]);
GetError();
glBindBuffer(GL_ARRAY_BUFFER, uiVBO[0]);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), fTriangle, GL_STATIC_DRAW);
glEnableVertexAttribArray(m_posAttr);
GetError();
glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, 0);
GetError();
glBindBuffer(GL_ARRAY_BUFFER, uiVBO[1]);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), fTriangleColor, GL_STATIC_DRAW);
glEnableVertexAttribArray(m_colAttr);
GetError();
glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, 0);
GetError();
glDrawArrays(GL_TRIANGLES, 0, 3);
GetError();
glDisableVertexAttribArray(m_posAttr);
glDisableVertexAttribArray(m_colAttr);
glFlush();
GetError();
}
- (void)dealloc {
glDeleteProgram(program);
glDeleteBuffers(2, uiVBO);
glDeleteVertexArrays(1, uiVAO);
GetError();
}
@end
error.h:
//// Prints OpenGL errors
#ifndef __ERROR_H__
#define __ERROR_H__
#include <stdlib.h>
#include <assert.h>
#ifdef DEBUG
#define GetError()\
{\
for (GLenum Error = glGetError(); (GL_NO_ERROR != Error); Error = glGetError())\
{\
switch (Error)\
{\
case GL_INVALID_ENUM: printf("\n%s\n\n", "GL_INVALID_ENUM" ); assert(0); break;\
case GL_INVALID_VALUE: printf("\n%s\n\n", "GL_INVALID_VALUE" ); assert(0); break;\
case GL_INVALID_OPERATION: printf("\n%s\n\n", "GL_INVALID_OPERATION"); assert(0); break;\
case GL_OUT_OF_MEMORY: printf("\n%s\n\n", "GL_OUT_OF_MEMORY" ); assert(0); break;\
default: break;\
}\
}\
}
#else
#define GetError()
#endif /* DEBUG */
#endif /* __ERROR_H__ */
我看到的第一件事就是你必須在** glClear之前調用glClearColor **。否則它不起作用。下一步:在VAO設置代碼之後綁定VAO - >當VAO綁定時沒有存儲在VAO中的信息 - >所有設置均被重置。下一步:你不應該在每一幀重新創建VAO和VBO。它們應該生成一次,然後在繪圖方法中使用。 – BDL
既然有太多不同的東西看起來不對,你應該考慮尋找一個好的教程。 – BDL
@BDL謝謝!我會盡力解決它並更新問題。我搜索了很好的教程,但我只找到了舊教程。我試圖按照[這一個](https://github.com/beelsebob/Cocoa-GL-Tutorial) –