// 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