Reputation: 1147
I just started to learn about OpenGL and this is my first program to draw a cube. I'm quite lost here as I was able to draw a rectangle by specifying coordinates for the rectangle in 2d, but I can't draw the cube by specifying coordinates in (x, y, z) format. What am I missing here?
Here is the code:
#include <GL/glew.h>
#include <GL/gl.h>
#include <math.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
// Open an OpenGL window
GLFWwindow* window;
/****Step 1: define vertices in (x, y, z) form****/
// Coordinates to draw a cube
const GLdouble coordinates[8][3] = {
{-0.5, -0.5, -0.5},
{0.5, -0.5, -0.5},
{0.5, -0.5, 0.5},
{-0.5, -0.5, 0.5},
{-0.5, 0.5, 0.5},
{-0.5, 0.5, -0.5},
{0.5, 0.5, -0.5},
{0.5, 0.5, 0.5}
};
/************************/
int main( void ) {
if (!glfwInit()){
fprintf(stderr, "Failed to initialize GLFW.\n");
return -1;
}
// Create a windowed mode window and its OpenGL context
window = glfwCreateWindow(700, 500, "Hello World", NULL, NULL);
if (window == NULL) {
fprintf(stderr, "glfw failed to create window.\n");
//glfwTerminate();
return -1;
}
// Make the window's context current
glfwMakeContextCurrent(window);
glewInit();
if (glewInit() != GLEW_OK){
fprintf(stderr, "Failed to initialize GLEW: %s.\n", glewGetErrorString(glewInit()));
return -1;
}
// 4x anti aliasing
glfwWindowHint(GLFW_SAMPLES, 4);
int cube_size = sizeof(coordinates)/sizeof(coordinates[0]);
/**Step 2: send this cube vertices to OpenGL through a buffer**/
GLuint vertexBuffer; // Declare vertex buffer
glGenBuffers(1, &vertexBuffer); // generating 1 buffer, put resulting identifier in this buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, cube_size*12, coordinates, GL_STATIC_DRAW);
/************************/
std::cout << sizeof(coordinates)/sizeof(coordinates[0]);
/**Step 3: Main loop for OpenGL draw the shape**
/* Main loop */
do{
glClearColor(1.0, 0.1, 0.1, .0);
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_LINE_LOOP, 0, cube_size);
glDisableVertexAttribArray(0);
// Swap front and back rendering buffers
glfwSwapBuffers(window);
//Poll for and process events
glfwPollEvents();
} // check if the ESC key was pressed or the window was closed
while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0);
/***********************************************/
// Close window and terminate GLFW
glfwDestroyWindow(window);
glfwTerminate();
// Exit program
exit( EXIT_SUCCESS );
}
Upvotes: 0
Views: 6579
Reputation: 51893
In addition to other answers ... well there can be more options what is wrong
wrong matrices
You have to be looking at the object actually so you need pointing Z axis of camera towards the object (+Z or -Z ... depends on projection used). If you use perspective then your object must be inside <Znear,Zfar>
range
You are passing 8 points of cube
That is not enough as cube has 6 sides each with 4 lines ... that is bit more points to pass in this way. If you got a decent OpenGL driver then you can use indices (element array) but then you should use only GLuint
and Quads
for element array ... because some gfx drivers had problems with odd points primitives and different data types (especially ATI in the past...). If you got nVidia then you should be fine but to avoid future compatibility problems later ...
something left enabled/disabled
enabled textures usually draws all in black, cull face can skip if mesh is not OK or camera is inside ... Also check glDepthFunc
and viewing Z direction (or try disable GL_DEPTH_TEST
)
shader
You are using VBO/VAO but no shader in your code what so ever. If you do not want to use shaders then for nVidia compatible HW use default layout locations (but that is dirty incompatible trick and should not be used for public Apps...). Use glVertexPointer,glColorPointer,...
instead or write easy shader emulating fixed functionality of what you need supported.
mine C++ example:
//------------------------------------------------------------------------------
//--- Open GL VAO example ------------------------------------------------------
//------------------------------------------------------------------------------
#ifndef _OpenGL_VAO_example_h
#define _OpenGL_VAO_example_h
//------------------------------------------------------------------------------
GLuint vbo[4]={-1,-1,-1,-1};
GLuint vao[4]={-1,-1,-1,-1};
const GLfloat vao_pos[]=
{
// x y z
-1.0,-1.0,-1.0,
+1.0,-1.0,-1.0,
+1.0,+1.0,-1.0,
-1.0,+1.0,-1.0,
-1.0,-1.0,+1.0,
+1.0,-1.0,+1.0,
+1.0,+1.0,+1.0,
-1.0,+1.0,+1.0,
};
const GLfloat vao_col[]=
{
// r g b
0.0,0.0,0.0,
1.0,0.0,0.0,
1.0,1.0,0.0,
0.0,1.0,0.0,
0.0,0.0,1.0,
1.0,0.0,1.0,
1.0,1.0,1.0,
0.0,1.0,1.0,
};
const GLuint vao_ix[]=
{
0,1,2,3,
4,5,6,7,
0,1,5,4,
1,2,6,5,
2,3,7,6,
3,0,4,7,
};
//---------------------------------------------------------------------------
void vao_init()
{
GLuint i;
glGenVertexArrays(4,vao);
glGenBuffers(4,vbo);
glBindVertexArray(vao[0]);
i=0; // vertex
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_pos),vao_pos,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
i=1; // indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(vao_ix),vao_ix,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,4,GL_UNSIGNED_INT,GL_FALSE,0,0);
i=2; // normal
i=3; // color
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_col),vao_col,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
// glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
}
//---------------------------------------------------------------------------
void vao_exit()
{
glDeleteVertexArrays(4,vao);
glDeleteBuffers(4,vbo);
}
//---------------------------------------------------------------------------
void vao_draw()
{
glBindVertexArray(vao[0]);
// glDrawArrays(GL_LINE_LOOP,0,8); // lines ... no indices
glDrawElements(GL_QUADS,24,GL_UNSIGNED_INT,0); // indices (choose just one line not both !!!)
glBindVertexArray(0);
}
//------------------------------------------------------------------------------
#endif
//------------------------------------------------------------------------------
//--- end. ---------------------------------------------------------------------
//------------------------------------------------------------------------------
This is how it looks like:
glDrawArrays
glDrawElements
vao_init()
after GL initialization (extensions included)vao_exit()
before GL destructionvao_draw()
inside draw loopMine matrices are like this:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,float(scr.xs)/float(scr.ys),0.1,100.0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0,0.0,-10.0);
where:
scr.xs,scr.ys
is the GL window resolutionmodelview
is rotating in timer to animate the cube ...znear=0.1
, zfar=100.0
, FOV angle is 60 degreesznear
camera projection planeDraw call is like this:
glDisable(GL_CULL_FACE);
glDisable(GL_TEXTURE_2D);
vao_draw();
[Notes]
In example the faces are not with strict polygon winding so do not enable CULL_FACE
!!! Also the texture disabling is necessary (in mine App) due to leftover from mine GL engine ... This is just dirty no shader present example so I used nVidia's default layout positions so on different HW you need the shader also ... see bullet #4
Upvotes: 1
Reputation: 10675
You have a type mismatch in your program. In this declaration:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
you are saying to OpenGL to interpret your data as float, but your coordinates points are declared double.
I suggest you to change GLdouble to GLfloat at coordinate type declaration.
By the way, with those points you will not get a cube, but only a partial sketch of it
Upvotes: 4
Reputation: 1572
It seems like your camera is located inside the box so the face gets culled. Try pushing the box to a more distant z position.
Upvotes: 0