zoukankan      html  css  js  c++  java
  • # opengl 学习 之 07 lesson

    opengl 学习 之 07 lesson

    简介

    OBJ的使用

    link

    http://www.opengl-tutorial.org/uncategorized/2017/06/07/website-update/

    TIPS

    不同的obj有不同的格式

    code

    // Include standard headers
    #include <stdio.h>
    #include <stdlib.h>
    #include <vector>
    
    // Include GLEW
    #include <GL/glew.h>
    
    // Include GLFW
    #include <GLFW/glfw3.h>
    GLFWwindow* window;
    
    // Include GLM
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    using namespace glm;
    
    #include <common/shader.hpp>
    #include <common/texture.hpp>
    #include <common/controls.hpp>
    #include <common/objloader.hpp>
    
    int main( void )
    {
    	// Initialise GLFW
    	if( !glfwInit() )
    	{
    		fprintf( stderr, "Failed to initialize GLFW
    " );
    		getchar();
    		return -1;
    	}
    
    	glfwWindowHint(GLFW_SAMPLES, 4);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
    	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
    	// Open a window and create its OpenGL context
    	window = glfwCreateWindow( 1024, 768, "Tutorial 07 - Model Loading", 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.
    " );
    		getchar();
    		glfwTerminate();
    		return -1;
    	}
    	glfwMakeContextCurrent(window);
    
    	// Initialize GLEW
    	glewExperimental = true; // Needed for core profile
    	if (glewInit() != GLEW_OK) {
    		fprintf(stderr, "Failed to initialize GLEW
    ");
    		getchar();
    		glfwTerminate();
    		return -1;
    	}
    
    	// Ensure we can capture the escape key being pressed below
    	glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
        // Hide the mouse and enable unlimited mouvement
        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
        
        // Set the mouse at the center of the screen
        glfwPollEvents();
        glfwSetCursorPos(window, 1024/2, 768/2);
    
    	// 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); 
    
    	// Cull triangles which normal is not towards the camera
    	glEnable(GL_CULL_FACE);
    
    	GLuint VertexArrayID;
    	glGenVertexArrays(1, &VertexArrayID);
    	glBindVertexArray(VertexArrayID);
    
    	// Create and compile our GLSL program from the shaders
    	GLuint programID = LoadShaders( "TransformVertexShader.vertexshader", "TextureFragmentShader.fragmentshader" );
    
    	// Get a handle for our "MVP" uniform
    	GLuint MatrixID = glGetUniformLocation(programID, "MVP");
    
    	// Load the texture
    	GLuint Texture = loadDDS("uvmap.DDS");
    	
    	// Get a handle for our "myTextureSampler" uniform
    	GLuint TextureID  = glGetUniformLocation(programID, "myTextureSampler");
    
    	// Read our .obj file
    	std::vector<glm::vec3> vertices;
    	std::vector<glm::vec2> uvs;
    	std::vector<glm::vec3> normals; // Won't be used at the moment.
    	bool res = loadOBJ("cube.obj", vertices, uvs, normals);
    
    	// Load it into a VBO
    
    	GLuint vertexbuffer;
    	glGenBuffers(1, &vertexbuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    	glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
    
    	GLuint uvbuffer;
    	glGenBuffers(1, &uvbuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    	glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);
    
    	do{
    
    		// Clear the screen
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    		// Use our shader
    		glUseProgram(programID);
    
    		// Compute the MVP matrix from keyboard and mouse input
    		computeMatricesFromInputs();
    		glm::mat4 ProjectionMatrix = getProjectionMatrix();
    		glm::mat4 ViewMatrix = getViewMatrix();
    		glm::mat4 ModelMatrix = glm::mat4(1.0);
    		glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
    
    		// Send our transformation to the currently bound shader, 
    		// in the "MVP" uniform
    		glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
    
    		// Bind our texture in Texture Unit 0
    		glActiveTexture(GL_TEXTURE0);
    		glBindTexture(GL_TEXTURE_2D, Texture);
    		// Set our "myTextureSampler" sampler to use Texture Unit 0
    		glUniform1i(TextureID, 0);
    
    		// 1rst attribute buffer : vertices
    		glEnableVertexAttribArray(0);
    		glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    		glVertexAttribPointer(
    			0,                  // attribute
    			3,                  // size
    			GL_FLOAT,           // type
    			GL_FALSE,           // normalized?
    			0,                  // stride
    			(void*)0            // array buffer offset
    		);
    
    		// 2nd attribute buffer : UVs
    		glEnableVertexAttribArray(1);
    		glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    		glVertexAttribPointer(
    			1,                                // attribute
    			2,                                // size
    			GL_FLOAT,                         // type
    			GL_FALSE,                         // normalized?
    			0,                                // stride
    			(void*)0                          // array buffer offset
    		);
    
    		// Draw the triangle !
    		glDrawArrays(GL_TRIANGLES, 0, vertices.size() );
    
    		glDisableVertexAttribArray(0);
    		glDisableVertexAttribArray(1);
    
    		// 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);
    	glDeleteProgram(programID);
    	glDeleteTextures(1, &Texture);
    	glDeleteVertexArrays(1, &VertexArrayID);
    
    	// Close OpenGL window and terminate GLFW
    	glfwTerminate();
    
    	return 0;
    }
    
    
    
    # Blender3D v249 OBJ File: untitled.blend
    # www.blender3d.org
    mtllib cube.mtl
    v 1.000000 -1.000000 -1.000000
    v 1.000000 -1.000000 1.000000
    v -1.000000 -1.000000 1.000000
    v -1.000000 -1.000000 -1.000000
    v 1.000000 1.000000 -1.000000
    v 0.999999 1.000000 1.000001
    v -1.000000 1.000000 1.000000
    v -1.000000 1.000000 -1.000000
    vt 0.748573 0.750412
    vt 0.749279 0.501284
    vt 0.999110 0.501077
    vt 0.999455 0.750380
    vt 0.250471 0.500702
    vt 0.249682 0.749677
    vt 0.001085 0.750380
    vt 0.001517 0.499994
    vt 0.499422 0.500239
    vt 0.500149 0.750166
    vt 0.748355 0.998230
    vt 0.500193 0.998728
    vt 0.498993 0.250415
    vt 0.748953 0.250920
    vn 0.000000 0.000000 -1.000000
    vn -1.000000 -0.000000 -0.000000
    vn -0.000000 -0.000000 1.000000
    vn -0.000001 0.000000 1.000000
    vn 1.000000 -0.000000 0.000000
    vn 1.000000 0.000000 0.000001
    vn 0.000000 1.000000 -0.000000
    vn -0.000000 -1.000000 0.000000
    usemtl Material_ray.png
    s off
    f 5/1/1 1/2/1 4/3/1
    f 5/1/1 4/3/1 8/4/1
    f 3/5/2 7/6/2 8/7/2
    f 3/5/2 8/7/2 4/8/2
    f 2/9/3 6/10/3 3/5/3
    f 6/10/4 7/6/4 3/5/4
    f 1/2/5 5/1/5 2/9/5
    f 5/1/6 6/10/6 2/9/6
    f 5/1/7 8/11/7 6/10/7
    f 8/11/7 7/12/7 6/10/7
    f 1/2/8 2/9/8 3/13/8
    f 1/2/8 3/13/8 4/14/8
    
    
    #version 330 core
    
    // Input vertex data, different for all executions of this shader.
    layout(location = 0) in vec3 vertexPosition_modelspace;
    layout(location = 1) in vec2 vertexUV;
    
    // Output data ; will be interpolated for each fragment.
    out vec2 UV;
    
    // Values that stay constant for the whole mesh.
    uniform mat4 MVP;
    
    void main(){
    
    	// Output position of the vertex, in clip space : MVP * position
    	gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
    	
    	// UV of the vertex. No special space for this one.
    	UV = vertexUV;
    }
    
    
    
    #version 330 core
    
    // Interpolated values from the vertex shaders
    in vec2 UV;
    
    // Ouput data
    out vec3 color;
    
    // Values that stay constant for the whole mesh.
    uniform sampler2D myTextureSampler;
    
    void main(){
    
    	// Output color = color of the texture at the specified UV
    	color = texture( myTextureSampler, UV ).rgb;
    }
    
    
    #include <vector>
    #include <stdio.h>
    #include <string>
    #include <cstring>
    
    #include <glm/glm.hpp>
    
    #include "objloader.hpp"
    
    // Very, VERY simple OBJ loader.
    // Here is a short list of features a real function would provide : 
    // - Binary files. Reading a model should be just a few memcpy's away, not parsing a file at runtime. In short : OBJ is not very great.
    // - Animations & bones (includes bones weights)
    // - Multiple UVs
    // - All attributes should be optional, not "forced"
    // - More stable. Change a line in the OBJ file and it crashes.
    // - More secure. Change another line and you can inject code.
    // - Loading from memory, stream, etc
    
    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...
    ", 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
    ");
    		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
    ", &vertex.x, &vertex.y, &vertex.z );
    			temp_vertices.push_back(vertex);
    		}else if ( strcmp( lineHeader, "vt" ) == 0 ){
    			glm::vec2 uv;
    			fscanf(file, "%f %f
    ", &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
    ", &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
    ", &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
    ");
    				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;
    }
    
    
    #ifdef USE_ASSIMP // don't use this #define, it's only for me (it AssImp fails to compile on your machine, at least all the other tutorials still work)
    
    // Include AssImp
    #include <assimp/Importer.hpp>      // C++ importer interface
    #include <assimp/scene.h>           // Output data structure
    #include <assimp/postprocess.h>     // Post processing flags
    
    bool loadAssImp(
    	const char * path, 
    	std::vector<unsigned short> & indices,
    	std::vector<glm::vec3> & vertices,
    	std::vector<glm::vec2> & uvs,
    	std::vector<glm::vec3> & normals
    ){
    
    	Assimp::Importer importer;
    
    	const aiScene* scene = importer.ReadFile(path, 0/*aiProcess_JoinIdenticalVertices | aiProcess_SortByPType*/);
    	if( !scene) {
    		fprintf( stderr, importer.GetErrorString());
    		getchar();
    		return false;
    	}
    	const aiMesh* mesh = scene->mMeshes[0]; // In this simple example code we always use the 1rst mesh (in OBJ files there is often only one anyway)
    
    	// Fill vertices positions
    	vertices.reserve(mesh->mNumVertices);
    	for(unsigned int i=0; i<mesh->mNumVertices; i++){
    		aiVector3D pos = mesh->mVertices[i];
    		vertices.push_back(glm::vec3(pos.x, pos.y, pos.z));
    	}
    
    	// Fill vertices texture coordinates
    	uvs.reserve(mesh->mNumVertices);
    	for(unsigned int i=0; i<mesh->mNumVertices; i++){
    		aiVector3D UVW = mesh->mTextureCoords[0][i]; // Assume only 1 set of UV coords; AssImp supports 8 UV sets.
    		uvs.push_back(glm::vec2(UVW.x, UVW.y));
    	}
    
    	// Fill vertices normals
    	normals.reserve(mesh->mNumVertices);
    	for(unsigned int i=0; i<mesh->mNumVertices; i++){
    		aiVector3D n = mesh->mNormals[i];
    		normals.push_back(glm::vec3(n.x, n.y, n.z));
    	}
    
    
    	// Fill face indices
    	indices.reserve(3*mesh->mNumFaces);
    	for (unsigned int i=0; i<mesh->mNumFaces; i++){
    		// Assume the model has only triangles.
    		indices.push_back(mesh->mFaces[i].mIndices[0]);
    		indices.push_back(mesh->mFaces[i].mIndices[1]);
    		indices.push_back(mesh->mFaces[i].mIndices[2]);
    	}
    	
    	// The "scene" pointer will be deleted automatically by "importer"
    	return true;
    }
    
    #endif
    
    Hope is a good thing,maybe the best of things,and no good thing ever dies.----------- Andy Dufresne
  • 相关阅读:
    mac 切换 默认xcode 版本
    mac 查看jenkins 管理员密码地址
    解决 mac ox 终端显示bogon 的问题
    eclipse 修改默认作者信息
    mac 查看 本地网络代理
    appium 解决 启动case 时不 重装 setting 和 unlock.apk的解决方案实践
    appium 输入时间慢的解决方案
    命令 关闭 appium 命令
    解决 appium could not start ios-webkit-debug-proxy
    PPT总结
  • 原文地址:https://www.cnblogs.com/eat-too-much/p/14068997.html
Copyright © 2011-2022 走看看