Untitled
unknown
c_cpp
2 years ago
8.8 kB
4
Indexable
#include<iostream> #include<filesystem> #include<vector> #include<string> #include<glad/glad.h> #include<GLFW/glfw3.h> #define STB_IMAGE_IMPLEMENTATION #include<STB/stb_image.h> #include<glm/glm.hpp> #include<glm/gtc/matrix_transform.hpp> #include<glm/gtc/type_ptr.hpp> #include"textfile.h" using namespace glm; const int WINDOW_WIDTH = 800; const int WINDOW_HEIGHT = 800; GLuint program; GLuint texture; void setShaders() { GLuint v, f, p; char* vs = NULL; char* fs = NULL; v = glCreateShader(GL_VERTEX_SHADER); f = glCreateShader(GL_FRAGMENT_SHADER); vs = textFileRead("shader.vs.glsl"); fs = textFileRead("shader.fs.glsl"); glShaderSource(v, 1, (const GLchar**)&vs, NULL); glShaderSource(f, 1, (const GLchar**)&fs, NULL); free(vs); free(fs); GLint success; char infoLog[1000]; // compile vertex shader glCompileShader(v); glGetShaderiv(v, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(v, 1000, NULL, infoLog); std::cout << "ERROR: VERTEX SHADER COMPILATION FAILED\n" << infoLog << std::endl; } // compile fragment shader glCompileShader(f); glGetShaderiv(f, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(f, 1000, NULL, infoLog); std::cout << "ERROR: FRAGMENT SHADER COMPILATION FAILED\n" << infoLog << std::endl; } // create program object p = glCreateProgram(); // p: program的id // attach shaders to program object glAttachShader(p, f); glAttachShader(p, v); // link program glLinkProgram(p); // check for linking errors glGetProgramiv(p, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(p, 1000, NULL, infoLog); std::cout << "ERROR: SHADER PROGRAM LINKING FAILED\n" << infoLog << std::endl; } glDeleteShader(v); glDeleteShader(f); if (success) glUseProgram(p); else { system("pause"); exit(123); } program = p; } void setTexture() { // Load texture image int imageWidth, imageHeight, imageChannels; unsigned char* imageData = stbi_load("../textures/brick.png", &imageWidth, &imageHeight, &imageChannels, 0); if (!imageData) { std::cout << "Failed to load texture image." << std::endl; exit(1); } // Create texture and bind it GLuint new_texture; glGenTextures(1, &new_texture); glBindTexture(GL_TEXTURE_2D, new_texture); // Set texture parameters and image data glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData); glGenerateMipmap(GL_TEXTURE_2D); // Free image data stbi_image_free(imageData); // Bind the texture to texture unit 0 glUniform1i(glGetUniformLocation(program, "Tex"), 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, new_texture); texture = new_texture; } bool loadOBJ(const char* path, std::vector<glm::vec3>& out_vertices, std::vector<glm::vec2>& out_uvs, std::vector<glm::vec3>& out_normals) { printf("Loading OBJ file %s...\n", path); std::vector<unsigned int> vertexIndices, uvIndices, normalIndices; std::vector<glm::vec3> temp_vertices; std::vector<glm::vec2> temp_uvs; std::vector<glm::vec3> temp_normals; FILE* file = fopen(path, "r"); if (file == NULL) { printf("Impossible to open the file ! Are you in the right path ? See Tutorial 1 for details\n"); getchar(); return false; } while (1) { char lineHeader[128]; // read the first word of the line int res = fscanf(file, "%s", lineHeader); if (res == EOF) break; // EOF = End Of File. Quit the loop. // else : parse lineHeader if (strcmp(lineHeader, "v") == 0) { glm::vec3 vertex; fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z); temp_vertices.push_back(vertex); } else if (strcmp(lineHeader, "vt") == 0) { glm::vec2 uv; fscanf(file, "%f %f\n", &uv.x, &uv.y); uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders. temp_uvs.push_back(uv); } else if (strcmp(lineHeader, "vn") == 0) { glm::vec3 normal; fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z); temp_normals.push_back(normal); } else if (strcmp(lineHeader, "f") == 0) { std::string vertex1, vertex2, vertex3; unsigned int vertexIndex[3], uvIndex[3], normalIndex[3]; int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2]); if (matches != 9) { printf("File can't be read by our simple parser :-( Try exporting with other options\n"); fclose(file); return false; } vertexIndices.push_back(vertexIndex[0]); vertexIndices.push_back(vertexIndex[1]); vertexIndices.push_back(vertexIndex[2]); uvIndices.push_back(uvIndex[0]); uvIndices.push_back(uvIndex[1]); uvIndices.push_back(uvIndex[2]); normalIndices.push_back(normalIndex[0]); normalIndices.push_back(normalIndex[1]); normalIndices.push_back(normalIndex[2]); } else { // Probably a comment, eat up the rest of the line char stupidBuffer[1000]; fgets(stupidBuffer, 1000, file); } } // For each vertex of each triangle for (unsigned int i = 0; i < vertexIndices.size(); i++) { // Get the indices of its attributes unsigned int vertexIndex = vertexIndices[i]; unsigned int uvIndex = uvIndices[i]; unsigned int normalIndex = normalIndices[i]; // Get the attributes thanks to the index glm::vec3 vertex = temp_vertices[vertexIndex - 1]; glm::vec2 uv = temp_uvs[uvIndex - 1]; glm::vec3 normal = temp_normals[normalIndex - 1]; // Put the attributes in buffers out_vertices.push_back(vertex); out_uvs.push_back(uv); out_normals.push_back(normal); } fclose(file); return true; } int main(){ glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "create 3D object", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); gladLoadGL(); glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); // shader setShaders(); // Vertices coordinates std::vector<glm::vec3> vertices; std::vector<glm::vec2> texuvs; std::vector<glm::vec3> normals; // Won't be used at the moment. bool res = loadOBJ("../models/cube.obj", vertices, texuvs, normals); if (!res) { std::cout << "Failed to load model\n"; } else { std::cout << "# of vertex = " << vertices.size() << std::endl; std::cout << "# of texuvs = " << texuvs.size() << std::endl; std::cout << "# of normals = " << normals.size() << std::endl; } GLuint vao, vbo; glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); glEnableVertexAttribArray(0); // Texture setTexture(); glEnable(GL_DEPTH_TEST); // Main while loop while (!glfwWindowShouldClose(window)) { glClearColor(0.07f, 0.13f, 0.17f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //shaderProgram.Activate(); glUseProgram(program); // Bind texture glBindTexture(GL_TEXTURE_2D, texture); // Bind the VAO glBindVertexArray(vao); // Draw primitives, number of indices, datatype of indices, index of indices glDrawArrays(GL_TRIANGLES, 0, vertices.size()); glfwSwapBuffers(window); glfwPollEvents(); } // Delete all the objects we've created glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDeleteProgram(program); glfwDestroyWindow(window); glfwTerminate(); return 0; } // vertex shader code #version 330 layout (location = 0) in vec3 aPos; layout (location = 1) in vec2 aTexCoord; out vec2 texCoord; void main() { gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); texCoord = aTexCoord; } // fragment shader code #version 330 in vec2 texCoord; out vec4 fragColor; uniform sampler2D Tex; void main() { fragColor = texture(Tex, texCoord); }
Editor is loading...