将颜色传递给英特尔HD 4000上的Assimp型号的GLSL着色器1.40

时间:2016-08-23 15:45:12

标签: c++ opengl glsl assimp

我试图通过顶点着色器将颜色属性传递给assimp导入的3d模型的每个点。

尝试解决方案

  1. 通过layout (location = 0) in vec3 color;
  2. 传递

    我的笔记本电脑配有Intel HD 4000图形,不支持#extension ARB_explicit_attrib_location : require。我正在运行GLSL 140,它需要#extension布局才能工作。

    1. 有一个单独的颜色值矢量,其索引与点的索引匹配,并作为另一个属性传入。
    2. 没用。 **编辑(什么没有用):**着色器从未收到main.cpp传递的颜色。

      我的代码

      main.cpp的一部分

      GLuint program_id = LoadShaders("pointcloud.vert", "pointcloud.frag");
      ObjLoader *obj_loader = new ObjLoader();
      int result = 0;
      if (argc > 1) result = obj_loader->loadAsset(argv[1]);
      else{ result = obj_loader->loadAsset("obj_samples/Heart.stl"); rotateY = 0.75f; rotateX = 0.5f;}
      if (result){glfwTerminate(); exit(EXIT_FAILURE);}
      glEnable(GL_DEPTH_TEST);
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      
      GLuint matrix_id = glGetUniformLocation(program_id, "MVP");//get the location for our "MVP" uniform variable
      GLfloat *g_vertex_buffer_data = (GLfloat*)malloc(obj_loader->getNumVertices()*sizeof(GLfloat));//use a large buffer to store the entire scene
      obj_loader->loadVertices(g_vertex_buffer_data);//load the scene into the vertex buffer
      GLint attribute_vertex = glGetAttribLocation(program_id, "vertex_pos");//get the location for the attribute variables
      GLuint vertex_array_id;//generate the Vertex Array Object (Depedency: GLEW)
      GLuint vertex_buffer[2];//initialize the vertex buffer memory (similar to malloc)
      GLuint color_buffer;
      glGenVertexArrays(1, &vertex_array_id); //create the VAO
      glBindVertexArray(vertex_array_id); // bind the VAO
      glGenBuffers(1, vertex_buffer); //create vertex buffer
      glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[0]); //bind the buffer
      glBufferData(GL_ARRAY_BUFFER, obj_loader->getNumVertices()*sizeof(GLfloat), g_vertex_buffer_data, GL_STATIC_DRAW);
      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vec3d), 0);
      glEnableVertexAttribArray(attribute_vertex);//enable
      glUseProgram(program_id);//use our shader
      glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
      glPointSize(3.0f);
      

      LoadShaders():

      GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){//load the shader programs and return the id
      GLuint vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);//create the vertex and fragment shaders
      GLuint fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER);
      std::string vertex_shader_code = readSourceFile(vertex_file_path);//read the shader and fragment programs into string
      if(vertex_shader_code == "")return 0; //failed because empty string
      printf("Compiling Vertex shader : %s\n", vertex_file_path);
      CompileShader(vertex_shader_code, vertex_shader_id);
      std::string fragment_shader_code = readSourceFile(fragment_file_path);//load the fragment program (optional)
      if(fragment_shader_code == "")return 0; //failed: empty string
      printf("Compiling Fragment shader : %s\n", fragment_file_path);//compile the fragment shader
      CompileShader(fragment_shader_code, fragment_shader_id);
      GLint result = GL_FALSE;
      int infolog_length;
      printf("Linking program\n");//link the program
      GLuint program_id = glCreateProgram();
      glAttachShader(program_id, vertex_shader_id);
      glAttachShader(program_id, fragment_shader_id);
      glLinkProgram(program_id);
      glGetProgramiv(program_id, GL_LINK_STATUS, &result);//check the program and ensure that the program is linked properly
      glGetProgramiv(program_id, GL_INFO_LOG_LENGTH, &infolog_length);
      if ( infolog_length > 0 ){
          std::vector<char> program_error_msg(infolog_length+1);
          glGetProgramInfoLog(program_id, infolog_length, NULL, &program_error_msg[0]);
          printf("%s\n", &program_error_msg[0]);
      }else{
          printf("Linked Successfully\n");
      }
      glDeleteShader(vertex_shader_id);
      glDeleteShader(fragment_shader_id);
      return program_id;
      

      }

      pointcloud.vert:

      #version 140
      uniform mat4 MVP;
      out vec4 colorV;
      in vec3 vertex_pos;
      
      void main(){
          gl_Position =  MVP * vec4(vertex_pos, 1.0f);// Output position of the vertex, in clip space : MVP * position
          colorV = vec4(1.0f, 0.0f, 0.0f, 1.0f);
      }
      

      我有一个rgb值的std :: vector我希望传递到着色器 - 任何建议来实现这个看似简单的行为?

1 个答案:

答案 0 :(得分:1)

从你的评论来看,我认为我误解了这个问题。 如果要将顶点颜色从assimp传递到着色器,则需要定义另一个顶点属性。为此,您需要在顶点缓冲区之后创建另一个缓冲区:

GLfloat* colorData = (GLfloat*)malloc(sizeof(GLfloat)*obj_loader->getNumVertices()*3);
obj_loader->loadColors(colorData);//or however you named it
Gluint colorBuffer;
glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Glfloat)*obj_loader->getNumVertices()*3, colorData, GL_STATIC_DRAW);
glBindAttribLocation(program_id, 0, "vertex_pos");
glBindAttribLocation(program_id, 1, "colorData");
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
//... continue with your code

顶点着色器:

#version 140
in vec3 vertex_pos;
in vec3 colorData;
out vec4 colorV;

uniform mat4 MVP;

void main()
{
 //...
}