// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdlib.h>

#include "main.h"
#include "testbase.h"
#include "utils.h"


namespace glbench {


class TriangleSetupTest : public DrawElementsTestFunc {
 public:
  TriangleSetupTest() {}
  virtual ~TriangleSetupTest() {}
  virtual bool Run();
  virtual const char* Name() const { return "triangle_setup"; }

 private:
  DISALLOW_COPY_AND_ASSIGN(TriangleSetupTest);
};

const char* kVertexShader =
    "attribute vec4 c;"
    "void main() {"
    "  gl_Position = c;"
    "}";

const char* kFragmentShader =
    "uniform vec4 color;"
    "void main() {"
    "  gl_FragColor = color;"
    "}";

bool TriangleSetupTest::Run() {
  glViewport(0, 0, g_width, g_height);

  // This specifies a square mesh in the middle of the viewport.
  // Larger meshes make this test too slow for devices that do 1 mtri/sec.
  // Also note that GLES 2.0 uses 16 bit indices.
  GLint width = 128;
  GLint height = 128;

  GLfloat *vertices = NULL;
  GLsizeiptr vertex_buffer_size = 0;
  CreateLattice(&vertices, &vertex_buffer_size, 1.f / g_width, 1.f / g_height,
                width, height);
  GLuint vertex_buffer = SetupVBO(GL_ARRAY_BUFFER,
                                  vertex_buffer_size, vertices);

  GLuint program =
    InitShaderProgram(kVertexShader, kFragmentShader);
  GLint attribute_index = glGetAttribLocation(program, "c");
  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
  glEnableVertexAttribArray(attribute_index);

  GLint color_uniform = glGetUniformLocation(program, "color");

  GLushort *indices = NULL;
  GLuint index_buffer = 0;
  GLsizeiptr index_buffer_size = 0;

  {
    // Use orange for drawing solid/all culled quads.
    const GLfloat orange[4] = {1.0f, 0.5f, 0.0f, 1.0f};
    glUniform4fv(color_uniform, 1, orange);
    count_ = CreateMesh(&indices, &index_buffer_size, width, height, 0);

    index_buffer = SetupVBO(GL_ELEMENT_ARRAY_BUFFER,
                            index_buffer_size, indices);
    RunTest(this, "triangle_setup", count_ / 3, g_width, g_height, true);
    glEnable(GL_CULL_FACE);
    RunTest(this, "triangle_setup_all_culled", count_ / 3, g_width, g_height, true);
    glDisable(GL_CULL_FACE);

    glDeleteBuffers(1, &index_buffer);
    delete[] indices;
  }

  {
    // Use blue-ish color for drawing quad with many holes.
    const GLfloat cyan[4] = {0.0f, 0.5f, 0.5f, 1.0f};
    glUniform4fv(color_uniform, 1, cyan);
    count_ = CreateMesh(&indices, &index_buffer_size, width, height,
                        RAND_MAX / 2);

    index_buffer = SetupVBO(GL_ELEMENT_ARRAY_BUFFER,
                            index_buffer_size, indices);
    glEnable(GL_CULL_FACE);
    RunTest(this, "triangle_setup_half_culled", count_ / 3, g_width, g_height, true);

    glDeleteBuffers(1, &index_buffer);
    delete[] indices;
  }

  glDeleteProgram(program);
  glDeleteBuffers(1, &vertex_buffer);
  delete[] vertices;
  return true;
}


TestBase* GetTriangleSetupTest() {
  return new TriangleSetupTest;
}


} // namespace glbench