以下特定代码行出现错误:
glGenVertexArrays(1, &shapes[i].vao);
直到那时我的程序运行正常,然后控制台停止工作并崩溃。我正在尝试具有多个vao和vbo,以便可以在屏幕上具有多个对象。这是整个代码的其余部分:
#define GLM_FORCE_RADIANS
#include <iostream>
#include <fstream>
#include <string>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <GLFW/glfw3.h>
using namespace std;
struct vertex{
float x = 0;
float y = 0;
float z = 0;
float r = 0;
float g = 0;
float b = 0;
float a = 0;
};
struct shape{
public:
int numOfVertecies;
GLenum typeOfShape;
vertex* vertices;
GLuint vao;
GLuint vbo;
/*shape(){
numOfVertecies = 0;
vertices = {};
typeOfShape = GL_TRIANGLES;
}
mkshape(vertex* v,int n,GLenum t){
numOfVertecies = n;
vertices = v;
typeOfShape = t;
}
~shape(){
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
}
setDrawType(GLenum t){
typeOfShape = t;
}*/
};
string LoadVertexCode();
string LoadFragmentCode();
shape mkShape(vertex*,int,GLenum);
vertex mkVert(float,float,float,float,float,float,float);
static void key_callback(GLFWwindow*, int, int, int, int);
GLuint u_transform;
glm::mat4 tmat(1.0f);
GLuint colorChange;
bool ESCLoop = true;
float rotation = 0;
float xChange;
float yChange;
int main()
{
int numOfShapes;
cout << "Welcome to the shape maker. How many shapes would you like to make: ";
cin >> numOfShapes;
int sides;
float xCenter;
float yCenter;
float radius;
shape *shapes = new shape[numOfShapes];
shape *temp;
for(int i = 0; i< numOfShapes; i++)
{
cout << "How many sides would you like for shape " << i+1 <<": ";
cin >> sides;
cout << "Radius(center to vertex): ";
cin >> radius;
cout << "Center coordinate for X: ";
cin >> xCenter;
cout << "Center coordinate for Y: ";
cin >> yCenter;
vertex buffer[sides];
for(int j = 0;j<sides;j++)
{
buffer[j] = mkVert(cos((j/sides)*2*M_PI)*radius+xCenter,sin((j/sides)*2*M_PI)*radius+yCenter,0.0,1.0,1.0,0.0,1.0);
}
shapes[i] = mkShape(buffer,sides,GL_LINE_LOOP);
glGenVertexArrays(1, &shapes[i].vao);
glBindVertexArray(shapes[i].vao);
glGenBuffers(1, &shapes[i].vbo); //create the Vertex Buffer Object
glBindBuffer(GL_ARRAY_BUFFER, shapes[i].vbo); //bind the empty VBO
glBufferData(GL_ARRAY_BUFFER, shapes[i].numOfVertecies*7*sizeof(vertex), shapes[i].vertices, GL_STATIC_DRAW); //store vertex data on the graphics card in the VBO
glEnableVertexAttribArray(0);
//enable attribute 0
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)0 ); //configure attribute 0
glEnableVertexAttribArray(1);
glVertexAttribPointer( 1, 4, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)(3 * sizeof(float)) ); //configure attribute 0
glBindVertexArray(0);
}
/*vertex v1[] = {
mkVert(-0.5f, -0.43f, 0.0f, 0.8f, 0.09f, 0.45f, 1.0f),
mkVert( 0.0f, 0.43f, 0.0f, 0.2f, 0.75f, 0.0f, 1.0f),
mkVert( 0.5f, -0.43f, 0.0f, 1.0f, 0.314159265f, 0.16f, 1.0f)
};
vertex v2[] = { //array of vertex positions
mkVert(-0.5f, -0.1f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f),
mkVert( -0.6f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f),
mkVert( 0.85f, 0.43f, 0.0f,0.0f, 0.0f, 1.0f, 0.50f) //position
};
vertex v3[] = {
mkVert(0.0f,0.0f,0.0f,0.5f,0.5f,0.5f,1.0f),
mkVert(-1.0f,-0.5f,0.0f,0.1f,0.2f,0.5f,1.0f),
mkVert(1.0f,0.9f,0.0f,1.0f,0.0f,0.3f,1.0f)
};
shape shapes[] = {
mkShape(v1,3,GL_TRIANGLES),
mkShape(v2,3,GL_TRIANGLES),
mkShape(v3,3,GL_TRIANGLES)
};*/
int amountOFrames = 0;
glfwInit(); //Initalize GLFW
GLFWwindow* mWindow = glfwCreateWindow(800,800, "Big Gay!", NULL, NULL); //Create the window.
if(!mWindow){ //If the window isn't working, Error.
glfwTerminate();
cerr << "Window creation failed!" << endl;
return -1;
}
glfwMakeContextCurrent(mWindow); // Make the GLFW context to actually run the damn code.
if(!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)){ //If GLad(05) no work, Error.
glfwTerminate();
cerr << "GLAD failed to initialize!" << endl;
return -1;
}
///SET UP SHADERS
string vertexCode = LoadVertexCode();
string fragmentCode = LoadFragmentCode();
const GLchar* vertexCodeCSTR[1]; //convert C++ strings into arrays of C strings
const GLchar* fragmentCodeCSTR[1];
vertexCodeCSTR[0] = (GLchar*)(vertexCode.c_str());
fragmentCodeCSTR[0] = (GLchar*)(fragmentCode.c_str());
GLint vertexCodeLength[1]; //create arrays of string lengths
GLint fragmentCodeLength[1];
vertexCodeLength[0] = vertexCode.length();
fragmentCodeLength[0] = fragmentCode.length();
GLint vertexSuccess = 0; //set up variable to store compilation status
GLint fragmentSuccess = 0;
GLint programSuccess = 0;
GLuint mVertexShader = glCreateShader(GL_VERTEX_SHADER);
GLuint mFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(mVertexShader, 1, vertexCodeCSTR, vertexCodeLength);
glShaderSource(mFragmentShader, 1, fragmentCodeCSTR, fragmentCodeLength);
glCompileShader(mVertexShader);
glCompileShader(mFragmentShader);
glGetShaderiv(mVertexShader, GL_COMPILE_STATUS, &vertexSuccess);
glGetShaderiv(mFragmentShader, GL_COMPILE_STATUS, &fragmentSuccess);
if(vertexSuccess == GL_FALSE || fragmentSuccess == GL_FALSE)
{
cerr << "One or more shaders failed to compile!" << endl;
glfwTerminate();
return -1;
}
GLuint mProgram = glCreateProgram(); //create a "program", which links the vertex and fragment shaders
glAttachShader(mProgram, mVertexShader); //attach both shaders to the program
glAttachShader(mProgram, mFragmentShader);
glBindAttribLocation(mProgram, 0, "a_position"); //bind the position attribute location
glBindAttribLocation(mProgram, 1, "a_color");
glLinkProgram(mProgram); //link the program
glGetProgramiv(mProgram, GL_LINK_STATUS, &programSuccess); //check for linking success
if(programSuccess == GL_FALSE) //continue if the program linked successfully
{
cerr << "Program failed to link!" << endl;
glfwTerminate();
return -1;
}
glValidateProgram(mProgram); //validate the program
glGetProgramiv(mProgram, GL_VALIDATE_STATUS, &programSuccess);
if(programSuccess == GL_FALSE) //continue if the program linked successfully
{
cerr << "Program failed to validate!" << endl;
glfwTerminate();
return -1;
}
GLuint u_transform = glGetUniformLocation(mProgram, "u_transform");
colorChange = glGetUniformLocation(mProgram, "colorChange");
glUniform1f(colorChange, 0.0f);
glUseProgram(mProgram);
float colorChangef = 0.0;
float change = 0.0001;
xChange = 0;
yChange = 0;
tmat = glm::translate(glm::mat4(1.0f), glm::vec3(0.001, 0.0, 0.0)) * tmat;
float xPos = 0;
float yPos = 0;
while(!glfwWindowShouldClose(mWindow)&&ESCLoop) //animation loop
{
glClear(GL_COLOR_BUFFER_BIT);
glfwPollEvents();
xPos += xChange;
yPos += yChange;
tmat = glm::translate(glm::mat4(1.0f),glm::vec3(-xPos,-yPos,0.0)) * tmat;
tmat = glm::rotate(glm::mat4(1.0f), glm::radians(rotation+0.014f), glm::vec3(0.0, 0.0, 1.0)) * tmat;
tmat = glm::translate(glm::mat4(1.0f), glm::vec3(xChange+xPos, yChange+yPos, 0.0)) * tmat;
glUniformMatrix4fv(u_transform, 1, GL_FALSE, glm::value_ptr(tmat));
for(int i = 0;i < numOfShapes;i++)
{
glBindVertexArray(shapes[i].vao);
glDrawArrays(shapes[i].typeOfShape, 0, shapes[i].numOfVertecies); //Drawing
}
colorChangef += change;
if(colorChangef > 1)
change = -0.0006;
if(colorChangef < -1)
change = 0.0003;
glUniform1f(colorChange, colorChangef);
glfwSwapBuffers(mWindow);
glfwSetKeyCallback(mWindow, key_callback);
amountOFrames++;
}
glfwTerminate();
cout << "Frames: " << amountOFrames << endl;
return 0;
}
string LoadVertexCode(){
string vertexCode = "";
string line;
ifstream myfile;
myfile.open("vertexCode.txt", ios::in);
if (myfile.is_open())
{
while (getline(myfile,line))
{
cout << line + "\n";
vertexCode += line + "\n";
}
myfile.close();
}
else
{
myfile.close();
cout << "Unable to open first file";
return "";
}
return vertexCode;
}
string LoadFragmentCode(){
string line;
ifstream myfile;
string fragmentCode = "";
myfile.open("fragmentCode.txt", ios::in);
if (myfile.is_open())
{
while (getline(myfile,line))
{
cout << line + "\n";
fragmentCode += line + "\n";
}
myfile.close();
}
else
{
cout << "Unable to open second file";
return "";
}
return fragmentCode;
}
vertex mkVert(float x, float y, float z, float r, float g ,float b, float a){
vertex ret;
ret.x = x;
ret.y = y;
ret.z = z;
ret.r = r;
ret.g = g;
ret.b = b;
ret.a = a;
return ret;
}
shape mkShape(vertex* v,int n,GLenum t){
shape ret;
ret.numOfVertecies = n;
ret.typeOfShape = t;
ret.vertices = v;
return ret;
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){
if (key == GLFW_KEY_SPACE){
if(action == GLFW_PRESS)
{
cout << "Space Key pressed." << endl;
tmat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0,0.1, 0.0)) * tmat;
}
if(action == GLFW_RELEASE)
{
cout << "Space Key released." << endl;
tmat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0,-0.1, 0.0)) * tmat;
}
}
if(key == GLFW_KEY_ESCAPE)
if(action == GLFW_PRESS)
{
cout << "Escape" << endl;
ESCLoop = false;
}
if(key == GLFW_KEY_ENTER)
{
if(action == GLFW_PRESS)
{
cout << "Enter Pressed" << endl;
}
if(action == GLFW_RELEASE)
{
cout << "Enter Released" << endl;
}
}
if(key == GLFW_KEY_R)
{
if(action == GLFW_PRESS)
{
cout << "Rotate" << endl;
rotation = 0.04;
}
if(action == GLFW_RELEASE)
{
cout << "Stop Rotate" << endl;
rotation = 0;
}
}
if(key == GLFW_KEY_S)
{
if(action == GLFW_PRESS)
{
cout << "Extend" << endl;
tmat = glm::scale(glm::mat4(1.0f), glm::vec3(1.5f, 1.5f, 1.0f)) * tmat;
}
if(action == GLFW_RELEASE)
{
cout << "Shrink" << endl;
tmat = glm::scale(glm::mat4(1.0f), glm::vec3((2.0f/3), (2.0f/3), 1.0f)) * tmat;
}
}
if(key == GLFW_KEY_LEFT)
{
if(action == GLFW_PRESS)
{
cout << "Left" << endl;
xChange -= 0.001;
}
if(action == GLFW_RELEASE)
{
cout << "Stop Left" << endl;
xChange += 0.001;
}
}
if(key == GLFW_KEY_RIGHT)
{
if(action == GLFW_PRESS)
{
cout << "Right" << endl;
xChange += 0.001;
}
if(action == GLFW_RELEASE)
{
cout << "Stop Right" << endl;
xChange -= 0.001;
}
}
if(key == GLFW_KEY_UP)
{
if(action == GLFW_PRESS)
{
cout << "Up" << endl;
yChange += 0.001;
}
if(action == GLFW_RELEASE)
{
cout << "Stop Up" << endl;
yChange -= 0.001;
}
}
if(key == GLFW_KEY_DOWN)
{
if(action == GLFW_PRESS)
{
cout << "Down" << endl;
yChange -= 0.001;
}
if(action == GLFW_RELEASE)
{
cout << "Stop Down" << endl;
yChange += 0.001;
}
}
}