Newer
Older
Import / applications / HighwayDash / ports / Game / States / MotdState.h
//  BlockyFroggy
//  Copyright © 2017 John Ryland.
//  All rights reserved.
#pragma once
#ifndef MOTD_STATE_H
#define MOTD_STATE_H


#include "BlankState.h"
#include "GameSim.h"

// experiment
//#include <opencv2/videoio/videoio_c.h>
#include <opencv2/opencv.hpp>
#include <OpenGLES/ES2/gl.h>
#include "GLProgram.h"
#include "Graphics.h"
#include "Motion.h"


DECLARE_PROGRAM_UNIFORMS(VertexColorProgram)
  DECLARE_UNIFORM(mat4, modelViewProjectionMatrix)
DECLARE_PROGRAM_UNIFORMS_END

DECLARE_VERTEX(VertexColorVertex)
  DECLARE_ATTRIB(vec3,  pos, GL_FALSE)
  DECLARE_ATTRIB(col4i, col, GL_TRUE)
DECLARE_VERTEX_END


DECLARE_ATTRIB_TYPE(vt2i, int16_t, x, y, u, v)

DECLARE_PROGRAM_UNIFORMS(CameraQuadProgram)
  DECLARE_UNIFORM(vec2attrib, invScreen)
  DECLARE_UNIFORM(GLint, texture)
DECLARE_PROGRAM_UNIFORMS_END

DECLARE_VERTEX(ScreenVertex)
  DECLARE_ATTRIB(vt2i, posAndTex, GL_FALSE)
DECLARE_VERTEX_END


DECLARE_ATTRIB_TYPE(v2i, int16_t, x, y)

DECLARE_PROGRAM_UNIFORMS(LineProgram)
  DECLARE_UNIFORM(vec2attrib, invScreen)
DECLARE_PROGRAM_UNIFORMS_END

DECLARE_VERTEX(LineVertex)
  DECLARE_ATTRIB(v2i,   pos, GL_FALSE)
  DECLARE_ATTRIB(col4i, col, GL_TRUE)
DECLARE_VERTEX_END


// Material Context
//   - pass it a texture
//   - pass it a shader
//   - pass it shader parameters
// Objects
//   - array of vertexes
//   - a material reference
template <class UniformsType, class VertexType>
class ProgramContext2
{
  static constexpr int MaxTextureCount() { return 32; }
public:
  void setup(const char *a_vertexShader, const char *a_fragmentShader,
                   Precision a_defaultPrecision, const OptionsType& a_options, int a_textures = 0, enum PrimitiveType a_type = Triangles)
  {
    // Setup main program
    auto bindUniformsFunc = [this](GLuint a_program) { m_uniforms.getLocations(a_program); };
    m_program.deleteProgram();
    VertexArray<VertexType> v;
    m_program.loadShaders(a_vertexShader, a_fragmentShader, a_defaultPrecision, a_options, m_vertexArray.bindAttributesFunction(), bindUniformsFunc);
    m_vertexArray.createVertexBuffer(a_type);

    m_textureCount = std::min(a_textures, MaxTextureCount());
    glGenTextures(m_textureCount, m_textureIds);
    for (int i = 0; i < m_textureCount; i++)
    {
      glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, (const GLvoid *)nullptr);
      glGenerateMipmap(GL_TEXTURE_2D);
    }
  }

  void shutdown()
  {
    m_program.deleteProgram();
    m_vertexArray.destroyVertexBuffer();
  }
  
  void setTextureData(int a_textureSlot, const unsigned char* a_data)
  {
    if (a_textureSlot < m_textureCount)
    {
      glBindTexture(GL_TEXTURE_2D, m_textureIds[a_textureSlot]);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, (const GLvoid *)a_data);
      glGenerateMipmap(GL_TEXTURE_2D);
    }
  }
  
  void update()
  {
    m_vertexArray.update();
  }

  void draw()
  {
    for (int i = 0; i < m_textureCount; i++)
    {
      glActiveTexture(GL_TEXTURE0 + i);
      glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
    }
    m_program.useProgram();
    m_uniforms.setUniforms();
    m_vertexArray.draw();
  }
  
  GLProgram               m_program;
  UniformsType            m_uniforms;
  VertexArray<VertexType> m_vertexArray;
  int                     m_textureCount;
  GLuint                  m_textureIds[MaxTextureCount()];
};


class MotdState : public BlankState
{
public:
  MotdState();
  ~MotdState();

  const char* getName() const override { return "MotdState"; }
  void enter(GameGraphics& graphics) override;
  void draw(GameGraphics& graphics) override;
  bool update(GameUi::UpdateState& state, float elapsed) override;

  void reset();

private:
  const char* m_motdStr = "";
  
// experiment
  //CvCapture* m_capture;
  cv::VideoCapture m_camera;
  GLuint m_cameraTexId;
  cv::Mat m_camFrame;

  MotionTracking m_deviceMotion;
  float qRot[4];
  double accel[3];
  double vel[3];
  double pos[3];
  double dt;
  
  double m_accelXHistory[640];
  double m_accelYHistory[640];
  double m_accelZHistory[640];

  int m_velXHistory[640];
  int m_velYHistory[640];
  int m_velZHistory[640];

  int m_posXHistory[640];
  int m_posYHistory[640];
  int m_posZHistory[640];

  ProgramContext2<CameraQuadProgram, ScreenVertex>       m_cameraQuadContext;
  ProgramContext2<VertexColorProgram, VertexColorVertex> m_demoModelContext;
  ProgramContext2<LineProgram, LineVertex>               m_linesContext;
};


void resetMotd();


#endif // MOTD_STATE_H