Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

glsl - Draw a 2D Quad in OpenGL

Whenever I think I understand something about openGL I find I don't understand anything.
I don't understand what I'm doing wrong.
The quad is not rendered.

Here is how I init the data

  std::vector<glm::vec3> vertices;

  vertices.resize(6);
                                           // first triangle
  vertices[0] = glm::vec3(x+w, y,   0.0f); // top right
  vertices[1] = glm::vec3(x+w, y+h, 0.0f); // bottom right
  vertices[2] = glm::vec3(x,   y,   0.0f); // top left
                                           // second triangle
  vertices[3] = glm::vec3(x+w, y+h, 0.0f); // bottom right
  vertices[4] = glm::vec3(x,   y+h, 0.0f); // bottom left
  vertices[5] = glm::vec3(x,   y,   0.0f); // top left

Where (x, y) is coord of the top left corner in pixel screen position and (w, h) is the length of the sides of the quad

This is how I set in the GPU the data

  glGenVertexArrays(1, &vao);
  glBindVertexArray(vao);
  
  glGenBuffers(1, &vbo);
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
  glEnableVertexAttribArray(0);
  
  glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);

  glBindVertexArray(0);

This is how I render it

  glBindVertexArray(vao);
  
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

  glDrawArrays(GL_TRIANGLES, 0, 6);

  glBindVertexArray(0);

And these are my vertex and fragment shader

  #version 330 core

  layout (location = 0) in vec3 position;

  void main() {

    gl_Position = vec4(position, 1.0);

  }


  #version 330 core

  out vec4 outColor;

  void main() {

     outColor = vec4(1.0);

 }

UPDATE

How Rabbit76 point out: I do not see the rectangle, because it is outside the view. If you don't use a projection matrix, the vertex coordinates must be in range [-1.0, 1.0]. If you want to use "window" coordinates you must use an orthographic projection"

So I changed the vertex shader in the following way and everything works!

   #version 330 core

   layout (location = 0) in vec3 position;

   uniform vec2 viewport; //Width and Height of the viewport

   void main() {

      // From pixels to 0-1
      vec2 coord = position.xy / viewport;

      // Flip Y so that 0 is top
      coord.y = (1.0-coord.y);

      // Map to NDC -1,+1
      coord.xy = coord.xy * 2.0 - 1.0;

      gl_Position = vec4(coord.xy, 0.0, 1.0);

   }
question from:https://stackoverflow.com/questions/65859056/draw-a-2d-quad-in-opengl

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You don't see the rectangle because it's out of view. If you are not using a projection matrix, the vertex coordinates must be in the range [-1.0, 1.0]. If you want to use "window" coordinates you must use an Orthographic projection.

You need to transform the vertex coordinates through the projection matrix. This is usually done in the vertex shader. However, it is also possible to transform the vertex coordinates on the CPU. Use glm::ortho to define the orthographic projection matrix and transform the vertices:

glm::mat4 projection = glm::ortho(0.0f, window_width, window_height, 0.0f, -1.0f, 1.0f);

for (auto &vertex : vertices)
    vertex = glm::vec3(projection * glm::vec4(vertex, 1.0f));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...