diff --git a/.vs/shader2/v14/.suo b/.vs/shader2/v14/.suo index 7007d22..ae4de56 100644 Binary files a/.vs/shader2/v14/.suo and b/.vs/shader2/v14/.suo differ diff --git a/main.cpp b/main.cpp index 752af1c..5a8843f 100644 --- a/main.cpp +++ b/main.cpp @@ -3,14 +3,11 @@ #include "Glm/glm.hpp" #include "Glm/ext.hpp" #include +#include "misc.h" +#include "model.h" #pragma comment(lib,"opengl32.lib") #pragma comment(lib, "glew32.lib") -struct Vertex { - float pos[3]; - float color[4]; -}; - /** * @hwnd 发起消息的窗口 * @msg 消息类型 @@ -25,22 +22,6 @@ LRESULT CALLBACK GLWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return DefWindowProc(hwnd, msg, wParam, lParam);//其他消息调用window默认处理函数 } -char* LoadFileContent(const char *path) { - FILE* pFile = fopen(path, "rb"); - if (pFile) { - fseek(pFile, 0, SEEK_END); - int nLen = ftell(pFile); - char* buffer = new char[nLen+1]; - rewind(pFile); - fread(buffer, nLen, 1, pFile); - buffer[nLen] = '\0'; - fclose(pFile); - return buffer; - } - fclose(pFile); - return nullptr; -} - /** * 创建一个GPU程序 */ @@ -175,56 +156,32 @@ INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine glewInit(); /*创建program*/ - GLuint program = CreateGPUProgram("test.vs", "test.fs"); + GLuint program = CreateGPUProgram("res/shader/test.vs", "res/shader/test.fs"); - GLuint posLocation, colorLocation, MLocation, VLocation, PLocation; + GLuint posLocation, texcoordLocation, normalLocation, MLocation, VLocation, PLocation; posLocation = glGetAttribLocation(program, "pos"); - colorLocation = glGetAttribLocation(program, "color"); + texcoordLocation = glGetAttribLocation(program, "texcoord"); + normalLocation = glGetAttribLocation(program, "normal"); MLocation = glGetUniformLocation(program, "M"); VLocation = glGetUniformLocation(program, "V"); PLocation = glGetUniformLocation(program, "P"); - /*创建vbo*/ - Vertex vertex[3]; - - vertex[0].pos[0] = 0; - vertex[0].pos[1] = 0; - vertex[0].pos[2] = -100.0f; - vertex[0].color[0] = 0.0f; - vertex[0].color[1] = 0.0f; - vertex[0].color[2] = 0.0f; - vertex[0].color[3] = 1.0f; + /*load model*/ + unsigned int *indexes = nullptr; + int vertexCount = 0, indexCount = 0; + VertexData* vertexes = LoadObjModel("res/model/Sphere.obj", &indexes, vertexCount, indexCount); - vertex[1].pos[0] = 10; - vertex[1].pos[1] = 0; - vertex[1].pos[2] = -100.0f; - vertex[1].color[0] = 0.0f; - vertex[1].color[1] = 0.0f; - vertex[1].color[2] = 0.0f; - vertex[1].color[3] = 1.0f; + if (vertexes == nullptr) { + printf("load obj model fail\n"); + } - vertex[2].pos[0] = 0; - vertex[2].pos[1] = 10; - vertex[2].pos[2] = -100.0f; - vertex[2].color[0] = 0.0f; - vertex[2].color[1] = 0.0f; - vertex[2].color[2] = 0.0f; - vertex[2].color[3] = 1.0f; - GLuint vbo; - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(float)*7*3, vertex, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + /*创建vbo*/ + GLuint vbo = CreateBufferObject(GL_ARRAY_BUFFER, sizeof(VertexData) * vertexCount, GL_STATIC_DRAW, vertexes); /*创建IBO*/ - unsigned int indexes[] = {0,1,2}; - GLuint ibo; - glGenBuffers(1, &ibo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * 3, indexes, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + GLuint ibo = CreateBufferObject(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indexCount, GL_STATIC_DRAW, indexes); - glClearColor(1.0f, 1.0f, 0.0f, 1.0f); + glClearColor(0.1f, 0.1f, 0.1f, 1.0f); //创建一个单位矩阵和一个投影矩阵,后面用来传递到shader float identify[] = { @@ -233,6 +190,7 @@ INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine 0,0,1,0, 0,0,0,1 }; + glm::mat4 model = glm::translate(0.0f, 0.0f, -5.0f); glm::mat4 projection = glm::perspective(45.0f, 800.0f/600.0f, 0.1f, 1000.0f); /*显示窗口*/ @@ -251,27 +209,26 @@ INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(program); - - //传递mvp矩阵到shader - glUniformMatrix4fv(MLocation, 1, GL_FALSE, identify); + glUniformMatrix4fv(MLocation, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(VLocation, 1, GL_FALSE, identify); glUniformMatrix4fv(PLocation, 1, GL_FALSE, glm::value_ptr(projection)); - //给shader的pos指定数据和color数据 glBindBuffer(GL_ARRAY_BUFFER, vbo); glEnableVertexAttribArray(posLocation); - glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); - glEnableVertexAttribArray(colorLocation); - glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(float) * 3)); + glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)0); + glEnableVertexAttribArray(texcoordLocation); + glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 3)); + glEnableVertexAttribArray(normalLocation); + glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 5)); glBindBuffer(GL_ARRAY_BUFFER, 0); - //glDrawArrays(GL_TRIANGLES, 0, 3); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); - glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); + glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glUseProgram(0); + SwapBuffers(dc); } diff --git a/misc.cpp b/misc.cpp new file mode 100644 index 0000000..62ace13 --- /dev/null +++ b/misc.cpp @@ -0,0 +1,38 @@ +#include "misc.h" +#include + +GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void * data) +{ + GLuint object; + glGenBuffers(1, &object); + glBindBuffer(bufferType, object); + glBufferData(bufferType, size, data, usage); + glBindBuffer(bufferType, 0); + + return object; +} + +char* LoadFileContent(const char *path) { + FILE* pFile = fopen(path, "rb"); + if (pFile) { + fseek(pFile, 0, SEEK_END); + int nLen = ftell(pFile); + char* buffer = nullptr; + if (nLen != 0) { + buffer = new char[nLen + 1]; + rewind(pFile); + fread(buffer, nLen, 1, pFile); + buffer[nLen] = '\0'; + } + else { + printf("load file %s fail, content is 0\n", path); + } + fclose(pFile); + return buffer; + } + else { + printf("open file %s fail\n", path); + } + fclose(pFile); + return nullptr; +} diff --git a/misc.h b/misc.h new file mode 100644 index 0000000..513e345 --- /dev/null +++ b/misc.h @@ -0,0 +1,5 @@ +#pragma once +#include "glew.h" + +GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void* data = nullptr); +char* LoadFileContent(const char *path); \ No newline at end of file diff --git a/model.cpp b/model.cpp new file mode 100644 index 0000000..fc6f32a --- /dev/null +++ b/model.cpp @@ -0,0 +1,122 @@ +#include "model.h" +#include "misc.h" +#include +#include +#include +#include + +VertexData * LoadObjModel(const char * filePath, unsigned int ** indexes, int & vertexCount, int & indexCount) +{ + char* fileContent = LoadFileContent(filePath); + if (fileContent != nullptr) { + + struct VertexInfo { + float v[3]; + }; + + struct VertexDefine { + int positionIndex; + int texcoordIndex; + int normalIndex; + }; + + std::vector position; + std::vector texcoord; + std::vector normal; + + std::vector objIndexes; //点的索引 对应opengl的indexes + std::vector vertices; //每一个点 对应opengl的vertex + + std::stringstream ssObjFile(fileContent); + char szOneLine[256]; + std::string temp; + while (!ssObjFile.eof()) { + memset(szOneLine, 0, 256); + ssObjFile.getline(szOneLine, 256); + printf("%s \n", szOneLine); + if (strlen(szOneLine) > 0) { + std::stringstream ssOneLine(szOneLine); + if (szOneLine[0] == 'v') { + if (szOneLine[1] == 't') { + ssOneLine >> temp; + VertexInfo vi; + ssOneLine >> vi.v[0]; + ssOneLine >> vi.v[1]; + texcoord.push_back(vi); + } + else if (szOneLine[1] == 'n') { + ssOneLine >> temp; + VertexInfo vi; + ssOneLine >> vi.v[0]; + ssOneLine >> vi.v[1]; + ssOneLine >> vi.v[2]; + normal.push_back(vi); + } + else { + ssOneLine >> temp; + VertexInfo vi; + ssOneLine >> vi.v[0]; + ssOneLine >> vi.v[1]; + ssOneLine >> vi.v[2]; + + position.push_back(vi); + } + } + else if(szOneLine[0] == 'f'){ + ssOneLine >> temp; + std::string vertexStr; + for (int i = 0; i < 3; i++) { + ssOneLine >> vertexStr; + + size_t pos = vertexStr.find_first_of('/'); + std::string positionIndexStr = vertexStr.substr(0, pos); + size_t pos2 = vertexStr.find_first_of('/', pos + 1); + std::string texcoordIndexStr = vertexStr.substr(pos + 1, pos2 - pos - 1); + std::string normalIndexStr = vertexStr.substr(pos2 + 1, vertexStr.length() - pos2 - 1); + + VertexDefine vd; + vd.positionIndex = atoi(positionIndexStr.c_str()) - 1; + vd.texcoordIndex = atoi(texcoordIndexStr.c_str()) - 1; + vd.normalIndex = atoi(normalIndexStr.c_str()) - 1; + + int nCurrentIndex = -1; + size_t nCurrentVerticeCount = vertices.size(); + for (size_t j = 0; j < nCurrentVerticeCount; j++) { + if (vertices[j].positionIndex == vd.positionIndex && + vertices[j].texcoordIndex == vd.texcoordIndex && + vertices[j].normalIndex == vd.normalIndex) { + nCurrentIndex = j; + break; + } + } + + if (nCurrentIndex == -1) { + nCurrentIndex = vertices.size(); + vertices.push_back(vd); + } + + objIndexes.push_back(nCurrentIndex); + + } + } + } + } + printf("face count %u\n", objIndexes.size() / 3); + + indexCount = (int)objIndexes.size(); + *indexes = new unsigned int[indexCount]; + for (int i = 0; i < indexCount; i++) { + (*indexes)[i] = objIndexes[i]; + } + + vertexCount = (int)vertices.size(); + VertexData *vertexes = new VertexData[vertexCount]; + for (int i = 0; i < vertexCount; i++) { + memcpy(vertexes[i].position, position[vertices[i].positionIndex].v, sizeof(float) * 3); + memcpy(vertexes[i].texcoord, texcoord[vertices[i].texcoordIndex].v, sizeof(float) * 2); + memcpy(vertexes[i].normal, normal[vertices[i].normalIndex].v, sizeof(float) * 3); + } + return vertexes; + } + return nullptr; +} diff --git a/model.h b/model.h new file mode 100644 index 0000000..ffc6f1b --- /dev/null +++ b/model.h @@ -0,0 +1,9 @@ +#pragma once + +struct VertexData { + float position[3]; + float texcoord[2]; + float normal[3]; +}; + +VertexData* LoadObjModel(const char* filePath, unsigned int **indexes, int &vertexCount, int &indexCount); \ No newline at end of file diff --git a/res/shader/test.fs b/res/shader/test.fs new file mode 100644 index 0000000..7118c4d --- /dev/null +++ b/res/shader/test.fs @@ -0,0 +1,3 @@ +void main() { + gl_FragColor = vec4(1.0); +} \ No newline at end of file diff --git a/test.vs b/res/shader/test.vs similarity index 65% rename from test.vs rename to res/shader/test.vs index 31bd325..83fe756 100644 --- a/test.vs +++ b/res/shader/test.vs @@ -1,12 +1,11 @@ attribute vec3 pos; -attribute vec4 color; +attribute vec2 texcoord; +attribute vec3 normal; uniform mat4 M; uniform mat4 V; uniform mat4 P; -varying vec4 V_Color; void main() { - V_Color = color; gl_Position = P*V*M*vec4(pos,1.0); } \ No newline at end of file diff --git a/shader2.VC.db b/shader2.VC.db index 0b75c14..4617c98 100644 Binary files a/shader2.VC.db and b/shader2.VC.db differ diff --git a/shader2.vcxproj b/shader2.vcxproj index 9a2ce2e..acb980e 100644 --- a/shader2.vcxproj +++ b/shader2.vcxproj @@ -147,10 +147,16 @@ + + - - + + + + + + diff --git a/shader2.vcxproj.filters b/shader2.vcxproj.filters index 61f8924..b857b09 100644 --- a/shader2.vcxproj.filters +++ b/shader2.vcxproj.filters @@ -18,12 +18,26 @@ 婧愭枃浠 + + 婧愭枃浠 + + + 婧愭枃浠 + + + + + 婧愭枃浠 + + + 婧愭枃浠 + - + 婧愭枃浠 - + 婧愭枃浠 diff --git a/test.fs b/test.fs deleted file mode 100644 index 40cde35..0000000 --- a/test.fs +++ /dev/null @@ -1,4 +0,0 @@ -varying vec4 V_Color; -void main() { - gl_FragColor = V_Color; -} \ No newline at end of file