[英]OpenGL: drawing a cube
我剛剛開始學習OpenGL,這是我的第一個繪制立方體的程序。 我在這里很迷失,因為我能夠通過在2d中為矩形指定坐標來繪制矩形,但是我無法通過以(x,y,z)格式指定坐標來繪制立方體。 我在這里想念什么?
這是代碼:
#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 );
}
您的程序中有類型不匹配。 在此聲明中:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
您是在說OpenGL將數據解釋為float,但是坐標點被聲明為double。
我建議您在坐標類型聲明時將GLdouble更改為GLfloat。
順便說一句,有了這些點,您將不會得到立方體,而只會得到它的局部草圖
除了其他答案外……還有更多選擇可以解決問題
錯誤的矩陣
您必須實際查看對象,因此需要將相機的Z軸指向該對象(+ Z或-Z ...取決於所使用的投影)。 如果使用透視圖,則您的對象必須在<Znear,Zfar>
范圍內
您正在通過8分立方體
這是不夠的,因為多維數據集有6個面,每個面有4條線...以這種方式傳遞的點更多。 如果您有一個不錯的OpenGL驅動程序,則可以使用索引(元素數組),但應僅對元素數組使用GLuint
和Quads
...,因為某些gfx驅動程序存在奇數點基元和不同數據類型的問題(尤其是ATI中的ATI )過去...)。 如果您擁有nVidia,則應該可以,但是為了避免以后出現兼容性問題,...
啟用/禁用的功能
啟用的紋理通常以黑色全部繪制,如果網格不正常或相機位於內部,則剔除的面孔可以跳過...另外,請檢查glDepthFunc
並查看Z方向(或嘗試禁用GL_DEPTH_TEST
)
着色器
您正在使用VBO / VAO,但是您的代碼中卻沒有着色器。 如果您不想使用着色器,則對於兼容nVidia的硬件,請使用默認布局位置 (但這是骯臟的不兼容技巧,不應用於公共應用程序...) 。 使用glVertexPointer,glColorPointer,...
代替,或者編寫簡單的着色器來模擬您需要支持的固定功能。
我的C ++示例:
//------------------------------------------------------------------------------
//--- 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. ---------------------------------------------------------------------
//------------------------------------------------------------------------------
它是這樣的:
glDrawArrays
glDrawElements
vao_init()
(包括擴展名) vao_exit()
vao_draw()
我的矩陣是這樣的:
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);
哪里:
scr.xs,scr.ys
是GL窗口分辨率 modelview
在計時器中旋轉以對立方體進行動畫處理... znear=0.1
, zfar=100.0
, FOV角度為60度 znear
相機投影平面之前9.9個單位 抽獎電話是這樣的:
glDisable(GL_CULL_FACE);
glDisable(GL_TEXTURE_2D);
vao_draw();
[筆記]
例如,面沒有嚴格的多邊形纏繞,因此不要啟用CULL_FACE
! 另外,由於我的GL引擎的殘留,紋理禁用也是必需的(在我的App中)... 這只是一個骯臟的沒有着色器的示例,因此我使用了nVidia的默認布局位置,因此在不同的硬件上,您也需要着色器...請參見bullet #4
看來您的相機位於盒子內部,因此面部被剔除。 嘗試將盒子推到更遠的z位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.