使用不同纹理纹理化多个对象

时间:2015-05-04 15:45:00

标签: c++ opengl multitexturing

有人可以向我解释如何在OpenGL中渲染具有不同纹理的多个对象?

我认为我几乎已经到了最后的结果,但此刻我被困在这里,我不知道接下来我需要做什么。真的需要一些帮助!

目前这就是我所拥有的:

  1. drawSphere():根据longs和lats的数量绘制一个UV球体

    int numberOfVerices = 0;

    for(int i = 0; i <= lats; i++) {
        double lat0 = M_PI * (-0.5 + (double) (i - 1) / lats);
        double z0  = sin(lat0);
        double zr0 =  cos(lat0);
    
        double lat1 = M_PI * (-0.5 + (double) i / lats);
        double z1 = sin(lat1);
        double zr1 = cos(lat1);
    
        for(int j = 0; j <= longs; j++) {
            double lng = 2 * M_PI * (double) (j - 1) / longs;
            double x = cos(lng);
            double y = sin(lng);
    
            glNormal3f(x * zr0, y * zr0, z0);
    
            vertices.push_back(x * zr0);
            vertices.push_back(y * zr0);
            vertices.push_back(z0);
            indices.push_back(numberOfVerices);
            numberOfVerices++;
    
            vertices.push_back(x * zr1);
            vertices.push_back(y * zr1);
            vertices.push_back(z1);
            indices.push_back(numberOfVerices);
            numberOfVerices++;
       }
       indices.push_back(GL_PRIMITIVE_RESTART_FIXED_INDEX);
    }
    
  2. SetupGeometry():此方法用于绑定顶点和纹理坐标。

  3. drawSphere(300,300);

    glGenBuffers(1, &vboVertex);
    glBindBuffer(GL_ARRAY_BUFFER, vboVertex);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(0);
    
    glGenBuffers(1, &vboTexture);
    glBindBuffer(GL_ARRAY_BUFFER, vboTexture);
    glBufferData(GL_ARRAY_BUFFER, texture.size() * sizeof(GLfloat), &texture[0], GL_STATIC_DRAW);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(1);
    
    glGenBuffers(1, &vboIndex);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndex);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
    
    numsToDraw = indices.size();
    nums = indices.size();
    
    1. SetupShader():创建着色器并编译着色器
    2. char text [1000];     int length;

      vertexSource = filetobuf("space/sphere.vert");
      fragmentSource = filetobuf("space/sphere.frag");
      
      vertexShader = glCreateShader(GL_VERTEX_SHADER);
      fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
      
      glShaderSource(vertexShader, 1, (const GLchar**) &vertexSource, 0);
      glShaderSource(fragmentShader, 1, (const GLchar**) &fragmentSource, 0);
      
      fprintf(stderr, "Compiling vertex shader....\n");
      glCompileShader(vertexShader);
      fprintf(stderr, "Compiling fragment shader....\n");
      glCompileShader(fragmentShader);
      fprintf(stderr, "Done....\n");
      
      shaderProgram = glCreateProgram();
      glAttachShader(shaderProgram, vertexShader);
      glAttachShader(shaderProgram, fragmentShader);
      
      glBindAttribLocation(shaderProgram, 0, "in_Position");
      glBindAttribLocation(shaderProgram, 1, "Texture_Coord");
      
      printf("Linking program ... \n");
      glLinkProgram(shaderProgram);
      
      glGetProgramInfoLog(shaderProgram, 1000, &length, text);
      if(length > 0){
          fprintf(stderr, "Validate Shader Program\n%s\n", text );
      }
      
      glUseProgram(shaderProgram);
      
      1. SetupTexture(char * filename):加载图片,生成2个纹理数组,一个到GL_TEXTURE0,另一个到GL_TEXTURE1
      2. GLuint纹理[2];     glGenTextures(2,texture);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture[0]);
        data = stbi_load(fileName, &w, &h, &n, 0);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glUniform1i(glGetUniformLocation(shaderProgram, "texture_Sun"), 0);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        stbi_image_free(data);
        
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, texture[1]);
        data = stbi_load(fileName1, &w, &h, &n, 0);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glUniform1i(glGetUniformLocation(shaderProgram, "texture_Earth"), 1);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        stbi_image_free(data);
        
        1. 渲染(int i):渲染2个对象,即球体。
        2. glClearColor(0.0,0.0,0.0,1.0); / *让我们的背景变黑* /     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

          glEnable(GL_PRIMITIVE_RESTART);
          glPrimitiveRestartIndex(GL_PRIMITIVE_RESTART_FIXED_INDEX);
          glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndex);
          
          glPushMatrix();
          glLoadIdentity();
          glm::mat4 Projection = glm::perspective(50.0f, 5.0f / 3.0f, 1.0f, 100.0f);
              glm::mat4 View = glm::lookAt(
                  glm::vec3(0, 5, 2),
                  glm::vec3(0, 0, 0),
                  glm::vec3(0, 1, 0)
              );
          
              /* Animations */
              GLfloat angle = (GLfloat) (i);
              View = glm::translate(View, glm::vec3(2.0f, 0.0f, 0.0f));
              View = glm::rotate(View, angle * 0.5f, glm::vec3(0.0f, 0.0f, 1.0f));
              /* ******* */
          
              glm::mat4 Model = glm::mat4(1.0f);
              glm::mat4 MVP = Projection * View * Model;
          
              glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "mvpMatrix"), 1, GL_FALSE, glm::value_ptr(MVP));
          glDrawElements(GL_QUAD_STRIP, numsToDraw, GL_UNSIGNED_INT, NULL);
          glPopMatrix();
          
          glPushMatrix();
          glLoadIdentity();
          glm::mat4 Projection1 = glm::perspective(50.0f, 5.0f / 3.0f, 1.0f, 100.0f);
              glm::mat4 View1 = glm::lookAt(
                  glm::vec3(0, 5, 2),
                  glm::vec3(0, 0, 0),
                  glm::vec3(0, 1, 0)
              );
          
              /* Animations */
              GLfloat angle1 = (GLfloat) (i);
              View1 = glm::translate(View1, glm::vec3(-2.0f, 0.0f, 0.0f));
              View1 = glm::rotate(View1, angle1 * -0.5f, glm::vec3(0.0f, 0.0f, 1.0f));
              /* ******* */
          
              glm::mat4 Model1 = glm::mat4(1.0f);
              MVP = Projection1 * View1 * Model1;
          
              glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "mvpMatrix"), 1, GL_FALSE, glm::value_ptr(MVP));
          glDrawElements(GL_QUAD_STRIP, nums, GL_UNSIGNED_INT, NULL);
          glPopMatrix();
          

          VertexShader:

          #version 330 core
          precision highp float;
          attribute vec3 in_Position;
          attribute vec3 in_Position1;
          varying vec4 Texture_Coord;
          
          uniform mat4 mvpMatrix;
          
          void main(void){
              gl_Position = mvpMatrix * vec4(in_Position, 1.0);
              Texture_Coord = vec4(in_Position, 1.0);
          }
          

          FragmentShader:

          #version 330 core
          precision highp float;
          varying vec4 Texture_Coord;
          
          uniform sampler2D texture_Sun;
          uniform sampler2D texture_Earth;
          
          out vec4 FragColor;
          
          void main(void){
              vec2 longLat = vec2((atan(Texture_Coord.y, Texture_Coord.x)/3.1415926 + 1) * 0.5, (asin(Texture_Coord.z) / 3.1415926 + 0.5));
          
              FragColor = texture2D(texture_Sun, longLat);
              FragColor = texture2D(texture_Earth, longLat);
          }
          

          主要代码:

          SetupGeomtry();
              SetupShader();
              SetupTexture("images/Earth.jpg", "images/sun.jpg");
              /*
               *  Main loop
               */
              int i = 0;
              while(!glfwWindowShouldClose(window)){
                  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
          
                  Render(i+=1);
                  glfwSwapBuffers(window);
                  glfwPollEvents();
                  Sleep(10);
              }
          

1 个答案:

答案 0 :(得分:1)

通常你会加载纹理(即将它们缓冲到GPU):

Author.books.new

然后在绘制每个对象之前绑定所述对象的相关纹理:

GLuint texture[2];
glGenTextures(2, texture);

glBindTexture(GL_TEXTURE_2D, texture[0]);
data = stbi_load(fileName, &w, &h, &n, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
stbi_image_free(data);

glBindTexture(GL_TEXTURE_2D, texture[1]);
data = stbi_load(fileName1, &w, &h, &n, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
stbi_image_free(data);

然后// already selected the shader programme for both Sun and Earth GLint textureLocation = glGetUniformLocation(shaderProgram, "texture_CelestialBody"); // optionally remember more locations for multi texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture[0]); glUniform1i(textureLocation, 0); // optionally bind more textures for multi texture shader... // draw Sun now glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture[1]); glUniform1i(textureLocation, 0); // optionally bind more textures for multi texture shader... // draw Earth now 识别太阳和地球的纹理 - 即片段着色器不会区分两者。