#include <iostream>
#include <OpenGL/gl3.h>
#include <OpenGL/gl3ext.h>
#include <SDL2/SDL.h>
SDL_Window * window = NULL;
SDL_GLContext context = NULL;
const GLfloat vertices[3][4] = {
0.5f, 0.5f, 0.0f, // Top Right
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f // Top Left
};
const GLuint indices[3][2]= { // Note that we start from 0!
0, 1, 3, // First Triangle
1, 2, 3 // Second Triangle
};
const GLchar* vertexShaderSource = {"#version 330 core\n"
"layout (location = 0) in vec3 position;"
"void main(void)\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\n\0"};
//fragment
const GLchar* fragmentShaderSource = {"#version 330 core\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
"color = vec4(1.0, 0.5, 0.2, 1.0);\n"
"}\n\0"};
bool init ();
bool init(){
if (SDL_Init(SDL_INIT_VIDEO)<0){
std::cout << "Can't make SDL" << std::endl;
}
//what version we are using
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
//SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
window = SDL_CreateWindow("Rectangle", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 512, 512, SDL_WINDOW_OPENGL);
if (!window){
std::cout << "No window created" << std::endl;
window = NULL;
return false;
}
context = SDL_GL_CreateContext(window);
//double buffering - 24bit z buffer (might need changing for different systems)
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
//Makes buffer swap sync with VBLANK
SDL_GL_SetSwapInterval(1);
glViewport(0, 0, 512, 512);
return true;
};
int main(int argc, const char * argv[]) {
if (!init()) std::cout << "Failed to start up!" << std::endl;
//compiling the shaders
GLuint shaderProgram, fragmentShader, vertexShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
//error checking
GLchar info [512];
GLint success;
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if(!success){
glGetShaderInfoLog(fragmentShader, 512, NULL, info);
std::cout << "Did not compile fragment shader\n"<< info;
}
std::cout<< "vertex shader made" << std::endl;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
//error checking
GLchar infoLog [512];
GLint success2;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success2);
if(!success){
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "Did not compile vertex shader\n" << info;
}
std::cout << "fragment shader made" << std::endl;
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
//error checking
GLchar info3 [512];
GLint success3;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success3);
if(!success){
glGetProgramInfoLog(shaderProgram, 512, NULL, info3);
std::cout << "Did not link shaders\n" << info;
}
std::cout << "shaders linked" << std::endl;
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
//sets all the VAOs, VBOs, etcs
GLuint VAO;
glGenVertexArrays(1, &VAO);
GLuint VBO;
glGenBuffers(1, &VBO);
GLuint EBO;
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
bool loop = true;
while (loop) {
SDL_Event e;
while(SDL_PollEvent(&e)){
if (e.type == SDL_QUIT) loop = false;
if (e.type == SDL_KEYDOWN){
switch(e.key.keysym.sym){
case SDLK_ESCAPE:
loop = false;
break;
case SDLK_q:
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
SDL_GL_SwapWindow(window);
break;
case SDLK_y:
std::cout << glGetString(GL_VERSION) << std::endl;
}
std::cout << glGetError() << std::endl;
}
}
}
}
//generates error 1282 for some reason
我使用glGetError
查看错误是什么,它返回1282或GL_INVALID_OPERATION
。每当我尝试绘制时,都会导致图像出现故障(稍后会上传图片)。
问题绝对不是着色器,因为它们编译得很好。 我想这可能就是我如何设置VBO和VAO:
//sets all the VAOs, VBOs, etcs
GLuint VAO;
glGenVertexArrays(1, &VAO);
GLuint VBO;
glGenBuffers(1, &VBO);
GLuint EBO;
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
我直接从本教程https://learnopengl.com/#!Getting-started/Hello-Triangle
复制了所有这些内容可以在https://learnopengl.com/code_viewer.php?code=getting-started/hellotriangle2
找到本教程的源代码我将我的代码与教程进行了多次比较,检查我是否拥有所有正确的调用和参数,但我找不到任何错误。我很确定我正确地设置了它。有没有比我更有经验的人看到我做错了什么?
编辑:好的,所以我得到的行就是抛出错误的地方。我不知道我读错了,但我的代码中没有440行。这是第4行,第40个字符吗?在上下文完成后,我还移动了SetSwapInterval()
和SDL_GL_Doublebuffer
个函数。
编辑2 :好的,所以经过一些挖掘后,错误被抛出的线是439,(我有一堆注释掉的东西,这就是为什么这个数字太大了),在glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
之后。投诉是INVALID_OPERATION
。它还在第405行说INVALID_VALUE
- 我启动程序后glGenBuffers(1, &EBO);
之后的行,但没有再说。
编辑3 :经过多次检查后,肯定是glDrawElements()
造成这种情况,而不是其他任何内容。
答案 0 :(得分:0)
您错误地使用该命令来告诉如何在着色器中读取属性。
//WRONG
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (GLvoid*)0);
第五个参数是连续通用顶点属性之间的字节偏移量。您的顶点在缓冲区(VBO)中是连续的,因此不需要步幅:
//RIGHT
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glDrawElements在VBO中检测到索引大于1的无效位置:second position (1) + stride (3 floats) = end of buffer
并返回&#34;无效操作&#34;
着色器中的主要功能:
此函数不带参数,不返回值,必须是 声明为void:
使用:
void main()
代替void main(void)