Hi, everyone:
I am new to opengl and was trying to draw a 3D box, and everything went well when I drew in the glut display callback function directly. But inspired by the object oriented idea, I decided to create a “box” class
and made this class object draw itself. However, this turned out to be not working.
As a comparison, I will list these two version of codes. First, the properly working code (glut display callback function):
void display(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//create shaders and link to a program
Shader boxShader("shaders/shader.vert.glsl", "shaders/shader.frag.glsl");
GLfloat vert[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vert), vert, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
int imgWidth, imgHeight;
GLubyte *image = nullptr;
loadImage("resource/container.jpg", image, imgWidth, imgHeight);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgWidth, imgHeight, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
boxShader.useShaderProgram();
mat4 modelTrans;
modelTrans = glm::rotate(modelTrans, 20.0f, vec3(0.0f, 1.0f, 0.0f));
glUniformMatrix4fv(glGetUniformLocation(boxShader.program, "modelTrans"), 1,
GL_FALSE, glm::value_ptr(modelTrans));
mat4 viewTrans;
viewTrans = glm::translate(viewTrans, vec3(0.0f, 0.0f, -5.0f));
glUniformMatrix4fv(glGetUniformLocation(boxShader.program, "viewTrans"), 1,
GL_FALSE, glm::value_ptr(viewTrans));
mat4 projectionTrans;
projectionTrans = glm::perspective(45.0f, 8.0f / 6.0f, 0.1f, 100.0f);
glUniformMatrix4fv(glGetUniformLocation(boxShader.program, "projectionTrans"), 1,
GL_FALSE, glm::value_ptr(projectionTrans));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(boxShader.program, "myTexture"), 0);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
glutSwapBuffers();
}
The above code worked correctly. Then I tried to created a Box class:
class Box
{
public:
Box();
~Box();
void draw();
friend void loadImage(std::string filenameString,
GLubyte*& imgData, int &imgWidth, int &imgHeight);
private:
GLfloat *vertexAttrib;
GLuint VAO, VBO, texture;
//void transformation(Shader boxShader);
};
and in the box draw() method, which is almost the same as the above code in display function, I impleted:
void Box::draw(){
Shader boxShader("shaders/shader.vert.glsl", "shaders/shader.frag.glsl");
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexAttrib), vertexAttrib, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
int imgWidth, imgHeight;
GLubyte *image = nullptr;
loadImage("resource/container.jpg", image, imgWidth, imgHeight);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgWidth, imgHeight, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
boxShader.useShaderProgram();
mat4 modelTrans;
modelTrans = glm::rotate(modelTrans, 20.0f, vec3(0.0f, 1.0f, 0.0f));
modelTrans = glm::rotate(modelTrans, 20.0f, vec3(1.0f, 0.0f, 0.0f));
glUniformMatrix4fv(glGetUniformLocation(boxShader.program, "modelTrans"), 1,
GL_FALSE, glm::value_ptr(modelTrans));
mat4 viewTrans;
viewTrans = glm::translate(viewTrans, vec3(0.0f, 0.0f, -5.0f));
glUniformMatrix4fv(glGetUniformLocation(boxShader.program, "viewTrans"), 1,
GL_FALSE, glm::value_ptr(viewTrans));
mat4 projectionTrans;
projectionTrans = glm::perspective(45.0f, 8.0f / 6.0f, 0.1f, 100.0f);
glUniformMatrix4fv(glGetUniformLocation(boxShader.program, "projectionTrans"), 1,
GL_FALSE, glm::value_ptr(projectionTrans));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(boxShader.program, "myTexture"), 0);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
Finally, I created a box object in the glut display callback function and call its draw method, but this doesn’t work. I have been thinking about this problem and debugging for many days but still couldn’t figure it out!
I’m guesing sth might be wrong with the opengl object scope, but I’m not sure.
Could anyone please take a look and give some suggestions?
Thanks in advance for any help!!!
Best,
David.