我开始工作时遇到了一些问题。目标是画一个二十面体。我最终会将它细分为一个球体,但现在我很困惑为什么它不被绘制。我对OpenGL和C ++都很陌生,但已经使用Java 2年了(......虽然第一年我很难算我的位置:P)
二十面体代码基于此。 http://www.gamedev.net/topic/623118-icosphere-generation-code-not-working-properlyhelp/
IcoSphereCreator icoGen;
MeshGeometry3D ico;
ico.Vertexs = vertexs;
ico.TriangleIndices = indices;
ico.GenerateVertexArray();
这会生成一个Point3D数组。然后我将其复制到一个数组中,我将其用作顶点数组(是的,这非常混乱:/)。
static GLfloat vertArray[60];
for(int i = 0;i < ico.VertexArraySize;i = i+3){
vertArray[i] = ico.VertexArray[i].x;
vertArray[i+1] = ico.VertexArray[i].y;
vertArray[i+2] = ico.VertexArray[i].z;
}
for(int i = 0;i < sizeof(vertArray)/sizeof(vertArray[0]);i++){
std::cout << vertArray[i];
std::cout << " l ";
}
输出验证顶点数组是否有60个正确的元素。
我在这里创建缓冲区。
GLuint vertexbufferico;
glGenBuffers(1, &vertexbufferico);
glBindBuffer(GL_ARRAY_BUFFER, vertexbufferico);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertArray), vertArray, GL_STATIC_DRAW);
GLuint normalbufferico;
glGenBuffers(1, &normalbufferico);
glBindBuffer(GL_ARRAY_BUFFER, normalbufferico);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertArray), vertArray, GL_STATIC_DRAW);
这是我将属性传递到着色器代码的地方。
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbufferico);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0, (void*)0);//Attrib,size,type,normalised,stride,offset
/// 3rd attribute buffer : normals
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, normalbufferico);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);//Attrib,size,type,normalised,stride,offset
// Draw the Icosaherdon !
glDrawArrays(GL_TRIANGLES, 0, 60);
目前输出无效 - 只是一个空窗口。
似乎是同一个过程(在我脑海中)正确地从顶点,uv坐标和法线数组中绘制一个立方体。
我已经在这里呆了几天了,现在我已经到了我认为我没有看到非常简单的事情的阶段。
这是完整的代码。它真的被黑客攻击了 - 在我得到这个功能之后,花了很多时间来改善结构等等。该程序基于我从http://www.opengl-tutorial.org/学到的东西。
int main( void )
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Tutorial 04 - Colored Cube", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Create and compile our GLSL program from the shaders
GLuint programCube = LoadShaders( "cube.vertexshader", "cube.fragmentshader" );
GLuint programSphere = LoadShaders( "sphere.vertexshader", "sphere.fragmentshader" );
// Get a handle for our "MVP" uniform
GLuint MatrixIDCube = glGetUniformLocation(programCube, "MVP");
GLuint ViewMatrixIDCube = glGetUniformLocation(programCube, "V");
GLuint ModelMatrixIDCube = glGetUniformLocation(programCube, "M");
GLuint MatrixIDSphere = glGetUniformLocation(programSphere, "MVP");
GLuint ViewMatrixIDSphere = glGetUniformLocation(programSphere, "V");
GLuint ModelMatrixIDSphere = glGetUniformLocation(programSphere, "M");
// Load the texture using any two methods
//GLuint Texture = loadBMP_custom("uvtemplate.bmp");
GLuint Texture = loadDDS("img3.DDS");
// Get a handle for our "myTextureSampler" uniform
GLuint TextureID = glGetUniformLocation(programCube, "myTextureSampler");
// Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
// A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f
};
// Two UV coordinatesfor each vertex. They were created withe Blender.
static const GLfloat g_uv_buffer_data[] = {
0.000059f, 1.0f-0.000004f,
0.000103f, 1.0f-0.336048f,
0.335973f, 1.0f-0.335903f,
1.000023f, 1.0f-0.000013f,
0.667979f, 1.0f-0.335851f,
0.999958f, 1.0f-0.336064f,
0.667979f, 1.0f-0.335851f,
0.336024f, 1.0f-0.671877f,
0.667969f, 1.0f-0.671889f,
1.000023f, 1.0f-0.000013f,
0.668104f, 1.0f-0.000013f,
0.667979f, 1.0f-0.335851f,
0.000059f, 1.0f-0.000004f,
0.335973f, 1.0f-0.335903f,
0.336098f, 1.0f-0.000071f,
0.667979f, 1.0f-0.335851f,
0.335973f, 1.0f-0.335903f,
0.336024f, 1.0f-0.671877f,
1.000004f, 1.0f-0.671847f,
0.999958f, 1.0f-0.336064f,
0.667979f, 1.0f-0.335851f,
0.668104f, 1.0f-0.000013f,
0.335973f, 1.0f-0.335903f,
0.667979f, 1.0f-0.335851f,
0.335973f, 1.0f-0.335903f,
0.668104f, 1.0f-0.000013f,
0.336098f, 1.0f-0.000071f,
0.000103f, 1.0f-0.336048f,
0.000004f, 1.0f-0.671870f,
0.336024f, 1.0f-0.671877f,
0.000103f, 1.0f-0.336048f,
0.336024f, 1.0f-0.671877f,
0.335973f, 1.0f-0.335903f,
0.667969f, 1.0f-0.671889f,
1.000004f, 1.0f-0.671847f,
0.667979f, 1.0f-0.335851f
};
static const GLfloat g_normal_buffer_data[] = {
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f};
#define X .525731112119133606
#define Z .850650808352039932
Point3D vdata[] = {(-X, 0.0, Z),(X, 0.0, Z),(-X, 0.0, -Z),(X, 0.0, -Z),(0.0, Z, X),(0.0, Z, -X)
,(0.0, -Z, X),(0.0, -Z, -X),(Z, X, 0.0),(-Z, X, 0.0),(Z, -X, 0.0),(-Z, -X, 0.0)};
std::vector<Point3D> vertexs (vdata, vdata + sizeof(vdata) / sizeof(vdata[0]) );
vertexs.assign(vdata,vdata+sizeof(vdata) / sizeof(vdata[0]));
static int tindices[]={1,4,0, 4,9,0, 4,5,9, 8,5,4, 1,8,4,
1,10,8, 10,3,8, 8,3,5, 3,2,5, 3,7,2,
3,10,7, 10,6,7, 6,11,7, 6,0,11, 6,1,0,
10,1,6, 11,0,9, 2,11,9, 5,2,9, 11,2,7};
std::vector<int> indices (tindices, tindices + sizeof(tindices) / sizeof(tindices[0]) );
indices.assign(tindices,tindices+sizeof(tindices) / sizeof(tindices[0]));
//static GLfloat icoVert[(sizeof(tindices)/sizeof(tindices[0]))*3];
// for (int i=0; i<sizeof(tindices)/sizeof(tindices[0]); ++i) {
// icoVert[(3*i)+0] = vdata[tindices[i]][0];
// icoVert[(3*i)+1] = vdata[tindices[i]][1];
// icoVert[(3*i)+2] = vdata[tindices[i]][2];
//}
//
// static GLfloat icoNorm[(sizeof(tindices)/sizeof(tindices[0]))*3];
// for (int i=0; i<sizeof(tindices)/sizeof(tindices[0]); ++i) {
// icoVert[(3*i)+0] = vdata[tindices[i]][0];
// icoVert[(3*i)+1] = vdata[tindices[i]][1];
// icoVert[(3*i)+2] = vdata[tindices[i]][2];
//}
IcoSphereCreator icoGen;
MeshGeometry3D ico;
ico.Vertexs = vertexs;
ico.TriangleIndices = indices;
ico.GenerateVertexArray();
static GLfloat vertArray[60];
for(int i = 0;i < ico.VertexArraySize;i = i+3){
vertArray[i] = ico.VertexArray[i].x;
vertArray[i+1] = ico.VertexArray[i].y;
vertArray[i+2] = ico.VertexArray[i].z;
}
for(int i = 0;i < sizeof(vertArray)/sizeof(vertArray[0]);i++){
std::cout << vertArray[i];
std::cout << " l ";
}
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint uvbuffer;
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_uv_buffer_data), g_uv_buffer_data, GL_STATIC_DRAW);
GLuint normalbuffer;
glGenBuffers(1, &normalbuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_normal_buffer_data), g_normal_buffer_data, GL_STATIC_DRAW);
GLuint vertexbufferico;
glGenBuffers(1, &vertexbufferico);
glBindBuffer(GL_ARRAY_BUFFER, vertexbufferico);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertArray), vertArray, GL_STATIC_DRAW);
GLuint normalbufferico;
glGenBuffers(1, &normalbufferico);
glBindBuffer(GL_ARRAY_BUFFER, normalbufferico);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertArray), vertArray, GL_STATIC_DRAW);
// Get a handle for our "LightPosition" uniform
glUseProgram(programCube);
glUseProgram(programSphere);
GLuint LightIDCube = glGetUniformLocation(programCube, "LightPosition_worldspace");
GLuint LightIDSphere = glGetUniformLocation(programSphere, "LightPosition_worldspace");
std::cout << "drawing";
do{
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(programCube);
// Compute the MVP matrix from keyboard and mouse input
computeMatricesFromInputs();
vec3 gPosition1(-1.5f, 0.0f, 0.0f);
vec3 gPosition2( 1.5f, 0.0f, 0.0f);
glm::mat4 ProjectionMatrix = getProjectionMatrix();
glm::mat4 ViewMatrix = getViewMatrix();
glm::mat4 TranslationMatrixSqu = translate(mat4(), gPosition1);
glm::mat4 TranslationMatrixIco = translate(mat4(), gPosition2);
glm::mat4 ModelMatrixSqu = glm::mat4(1.0)*TranslationMatrixSqu;
glm::mat4 ModelMatrixIco = glm::mat4(1.0)*TranslationMatrixIco;
glm::mat4 MVP1 = ProjectionMatrix * ViewMatrix * ModelMatrixSqu;
glm::mat4 MVP2 = ProjectionMatrix * ViewMatrix * ModelMatrixIco;
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture);
// Set our "myTextureSampler" sampler to user Texture Unit 0
glUniform1i(TextureID, 0);
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixIDSphere, 1, GL_FALSE, &MVP2[0][0]);
glUniformMatrix4fv(ModelMatrixIDSphere, 1, GL_FALSE, &ModelMatrixIco[0][0]);
glUniformMatrix4fv(ViewMatrixIDSphere, 1, GL_FALSE, &ViewMatrix[0][0]);
glm::vec3 lightPos = glm::vec3(4,4,4);
glUniform3f(LightIDSphere, lightPos.x, lightPos.y, lightPos.z);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbufferico);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0, (void*)0);//Attrib,size,type,normalised,stride,offset
/// 3rd attribute buffer : normals
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, normalbufferico);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);//Attrib,size,type,normalised,stride,offset
// Draw the Icosaherdon !
glDrawArrays(GL_TRIANGLES, 0, 60);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0); //Attrib,size,type,normalised,stride,offset
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(1,2, GL_FLOAT,GL_FALSE,0,(void*)0); //Attrib,size,type,normalised,stride,offset
// 3rd attribute buffer : normals
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,0, (void*)0); //Attrib,size,type,normalised,stride,offset
glDrawArrays(GL_TRIANGLES, 0, 36);
glDeleteTextures(1, &TextureID);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
// Cleanup VBO and shader
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &uvbuffer);
glDeleteTextures(1, &TextureID);
glDeleteVertexArrays(1, &VertexArrayID);
glDeleteProgram(programCube);
glDeleteProgram(programSphere);
// Close OpenGL window and terminate GLFW
glfwTerminate();
return 0;
}