1
votes

Please help me understand what a good way to draw 2D scene (ortho) is. I am using OpenGL with shaders.

If I have a viewport of size 800x600 for example and draw quads. Some quads are in the viewport and some are not.

Are quads that are out of the viewport proccessed by OpenGL and shaders? If yes, do I need to cut them from the draw function? Are there standard decisions (glEnable(???)) for this situation or do I need make one myself?

Draw:

void Draw()
{
  glUseProgram(ProgramId);
  glUniformMatrix4fv(MVPId, 1, GL_FALSE, (float*)pMVP);

  glEnableVertexAttribArray(0);
  glEnableVertexAttribArray(1);
  glEnableVertexAttribArray(2);

  glBindBuffer(GL_ARRAY_BUFFER, BaseQuadBufferId);
  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);

  glBindBuffer(GL_ARRAY_BUFFER, BaseColorBufferId);
  glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);

  glBindBuffer(GL_ARRAY_BUFFER, OffsetQuadBufferId);
  glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);

  glVertexAttribDivisor(0, 0); //basic size
  glVertexAttribDivisor(1, 0); //basic color
  glVertexAttribDivisor(2, 1); //offset
  glDrawArraysInstanced(GL_QUADS, 0, 4, QuadCount);

  glDisableVertexAttribArray(0);
  glDisableVertexAttribArray(1);
  glDisableVertexAttribArray(2);
}

MVP:

CameraPosition = glm::vec3(0,0,1);
CameraDirection = glm::vec3(0,0,0);
Projection = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, -1.0f, 1.0f);
Model = glm::mat4(1.0f);
View = glm::lookAt(CameraPosition, CameraDirection, glm::vec3(0,1,0));
MVP = Projection * View * Model;

Vertex Shader:

layout(location = 0) in vec3 vertexPosition;
layout(location = 1) in vec4 vertexColor;
layout(location = 2) in vec2 vertexOffset;

uniform mat4 MVP;
out vec4 Color;

void main()
{
  gl_Position =  MVP * vec4(vertexPosition + vec3(vertexOffset.xy,0), 1);
  Color = vertexColor;
}

Image with question: http://imgur.com/VckmghQ

2

2 Answers

1
votes

All vertices submited using glDraw… are processed by the vertex shader (and geometry and/or tesselation shaders if geometry and/or tesselation shaders are used). Only after the vertex processing stage (vertex, tesselation and geometry shaders) clipping can be applied. After clipping only those fragments that fall into the viewport & scissor rectangle and pass the pixel ownership test are being processed.

1
votes

When your question is: Do I have to handle objects outside of the visible area myself, then the answer is no.

OpenGL clips all primitives automatically and ensures that all of them are displayed correctly even if they are partially visible. Technically, this is done directly before the fragment shader is called. The reason for this is, that the previouse shader stages could transform the primitive, so the decision can only be made after all of them. The clipping is then done in normalized device coordinates (and thus in 3D, also against near and far plane).

Have a look at this for more information about the rendering pipeline.