我正在尝试创建一个可以为我生成模型的Mesh类,然后在createTriangle
函数中调用该模型。但是,每当我尝试创建meshObj1
和meshObj2
然后将其推到meshVector
时,它都不想渲染吗?为什么会这样?
Mesh.h
#ifndef MESH_H
#define MESH_H
#include "GL/glew.h"
class Mesh {
public:
Mesh();
~Mesh();
void createMesh(GLfloat *vertices,unsigned int *indices,unsigned int numOfVertices,unsigned int numOfIndices);
void renderMesh();
void clearMesh();
private:
GLuint VAO,VBO,IBO;
GLsizei indexCount;
};
#endif
Mesh.cpp
#include "Mesh.h"
Mesh::Mesh() {
VAO = 0;
VBO = 0;
IBO = 0;
indexCount = 0;
}
Mesh::~Mesh() {
clearMesh();
}
void Mesh::createMesh(GLfloat* vertices,unsigned int* indices,unsigned int numOfIndices) {
indexCount = numOfIndices;
//Binding
glGenVertexArrays(1,&VAO);
glBindVertexArray(VAO);
//Information
//VBO Information
glGenBuffers(1,&VBO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices[0] * numOfVertices),vertices,GL_STATIC_DRAW);
//IBO Information
glGenBuffers(1,&IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices[0]) * numOfIndices,indices,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0);
glEnableVertexAttribArray(0);
//Unbinding
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glBindVertexArray(0);
}
void Mesh::renderMesh() {
//Binding
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IBO);
//Rendering
glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,0);
//Unbinding
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glBindVertexArray(0);
}
void Mesh::clearMesh() {
if (VAO != 0) {
glDeleteVertexArrays(1,&VAO);
VAO = 0;
}
if (VBO != 0) {
glDeleteBuffers(1,&VBO);
VBO = 0;
}
if (IBO != 0) {
glDeleteBuffers(1,&IBO);
IBO = 0;
}
indexCount = 0;
}
Main.cpp
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include <vector>
#include <memory>
#include "Mesh.h"
//Window dimensions
const GLint SCREEN_WIDTH = 1280,SCREEN_HEIGHT = 900;
GLuint shader,uniformModel,uniformProjection;
bool isMovingLeft = true;
float triOffset = 0.f;
float triMaxOffset = 0.7;
float triIncrement = 0.005;
std::vector<Mesh*> meshVector;
//Vertex shader
static const char* vShader = " \n\
#version 460 \n\
\n\
layout(location = 0) in vec3 pos; \n\
\n\
out vec4 vColor; \n\
\n\
uniform mat4 model; \n\
uniform mat4 projection; \n\
\n\
void main() { \n\
gl_Position = projection * model * vec4(pos,1.0); \n\
vColor = vec4(clamp(pos,0.f,1.f),1.f); \n\
}; \n\
";
//Fragment shader
static const char* fShader = " \n\
#version 460 \n\
\n\
in vec4 vColor; \n\
\n\
out vec4 color; \n\
\n\
void main() { \n\
color = vColor; \n\
}; \n\
";
void createTriangle() {
unsigned int indices[] = {
0,1,2,2
};
//Points of the triangle
GLfloat vertices[] = {
-1.f,-1.f,1.f,0.f
};
Mesh* meshObj1 = new Mesh();
meshObj1->createMesh(vertices,12,12);
meshVector.push_back(meshObj1);
Mesh* meshObj2 = new Mesh();
meshObj2->createMesh(vertices,12);
meshVector.push_back(meshObj2);
}
void addShader(GLuint theProgram,const char* shaderCode,GLenum shaderType) {
GLuint theShader = glCreateShader(shaderType);
const GLchar* theCode[1];
theCode[0] = shaderCode;
GLint codeLength[1];
codeLength[0] = strlen(shaderCode);
glShaderSource(theShader,theCode,codeLength);
glCompileShader(theShader);
//Getting error information for linking
GLint result = 0;
GLchar eLog[1024] = { 0 };
glGetShaderiv(theShader,GL_COMPILE_STATUS,&result);
if (result != GL_TRUE) {
glGetShaderInfoLog(theShader,sizeof(eLog),NULL,eLog);
std::cout << "Error compiling the " << shaderType << ' ' << eLog << '\n';
}
glAttachShader(theProgram,theShader);
}
void compileShaders() {
shader = glCreateProgram();
if (shader != GL_TRUE) {
std::cout << "Shader program error!\n";
}
//Adding shaders
addShader(shader,vShader,GL_VERTEX_SHADER);
addShader(shader,fShader,GL_FRAGMENT_SHADER);
//Getting error information for linking
GLint result = 0;
GLchar eLog[1024] = { 0 };
//Linking shader
glLinkProgram(shader);
//Shader linking status
glGetProgramiv(shader,GL_LINK_STATUS,&result);
if (result != GL_TRUE) {
glGetProgramInfoLog(shader,eLog);
std::cout << "Error linking program! " << eLog << '\n';
}
//Gets shader ID and then binds it with the variable inside shader
uniformModel = glGetUniformLocation(shader,"model");
uniformProjection = glGetUniformLocation(shader,"projection");
}
int main() {
//Initialize GLFW
if (glfwInit() != GLFW_TRUE) {
std::cout << "GLFW init failed\n";
glfwTerminate();
}
//Setup GLFW window properties
//OpenGL version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,4); //Large version
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,4); //Small version
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE); //Detects any old OpenGL code,this will throw an error
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,GL_TRUE); //Allows forward compatibility (between differnt OS)
//Creating window
GLFWwindow* window;
window = glfwCreateWindow(SCREEN_WIDTH,SCREEN_HEIGHT,"OpenGL Test Window",NULL);
glfwsetwindowpos(window,250,100);
if (window == NULL) {
std::cout << "GLFW window creation failed!\n";
glfwTerminate();
}
//Get buffer size information
int bufferWidth,bufferHeight;
glfwGetFramebufferSize(window,&bufferWidth,&bufferHeight);
//Set context for GLEW to use (can change between which window)
glfwMakeContextCurrent(window);
//Allow modern extension features
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::cout << "Glew init failed!\n";
glfwDestroyWindow(window);
glfwTerminate();
}
glEnable(GL_DEpth_TEST);
//Setup viewport size
glViewport(0,bufferWidth,bufferHeight);
createTriangle();
compileShaders();
glm::mat4 projection = glm::perspective(45.f,(GLfloat)bufferWidth / (GLfloat)bufferHeight,0.1f,100.f);
//Main game loop
while (!glfwWindowShouldClose(window)) {
//Get + Handle user input events
glfwPollEvents();
//Left-Right
if (isMovingLeft) {
triOffset += triIncrement;
}
else {
triOffset -= triIncrement;
}
if (abs(triOffset) >= triMaxOffset) {
isMovingLeft = !isMovingLeft;
}
//Clear window
glClearColor(0.f,1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEpth_BUFFER_BIT);
glUseProgram(shader);
//Matrix 4x4
glm::mat4 model(1.f);
model = glm::translate(model,glm::vec3(triOffset,-2.5f));
model = glm::scale(model,glm::vec3(0.4f,0.4f,1.f));
glUniformMatrix4fv(uniformModel,glm::value_ptr(model));
glUniformMatrix4fv(uniformProjection,glm::value_ptr(projection));
meshVector[0]->renderMesh();
model = glm::mat4(1.f);
model = glm::translate(model,glm::vec3(-triOffset,0.4,1.f));
meshVector[1]->renderMesh();
glUseProgram(0);
glfwSwapBuffers(window);
}
}
我希望两个金字塔形成彩色。