#include "LocationImage.h"
LocationImage::LocationImage()
{
}
LocationImage::~LocationImage()
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(3, meshVBO);
glBindVertexArray(0);
glDeleteVertexArrays(1, &meshVAO);
indeces.clear();
glUseProgram(0);
glDeleteProgram(shaderProgram);
glBindTexture(GL_TEXTURE_2D, 0);
}
bool LocationImage::InvertSDLImage(int pitch, int height, void* image_pixels)
{
int index;
void* temp_row;
int height_div_2;
temp_row = (void *)malloc(pitch);
if(NULL == temp_row)
{
SDL_SetError("Not enough memory for image inversion");
return false;
}
height_div_2 = (int) (height * .5);
for(index = 0; index < height_div_2; index++) {
memcpy((Uint8 *)temp_row,
(Uint8 *)(image_pixels) +
pitch * index,
pitch);
memcpy(
(Uint8 *)(image_pixels) +
pitch * index,
(Uint8 *)(image_pixels) +
pitch * (height - index-1),
pitch);
memcpy(
(Uint8 *)(image_pixels) +
pitch * (height - index-1),
temp_row,
pitch);
}
free(temp_row);
return true;
}
bool LocationImage::TargetSDLLoadSurface(GLenum target, SDL_Surface *surface)
{
if (!surface)
return false;
GLenum texture_format;
switch (surface->format->BytesPerPixel)
{
case 4:
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
break;
case 3:
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
break;
case 2:
texture_format = GL_LUMINANCE_ALPHA;
break;
case 1:
texture_format = GL_LUMINANCE;
break;
}
if (InvertSDLImage(surface->pitch, surface->h, surface->pixels))
{
glGenTextures(1, &colorTexture);
glBindTexture(GL_TEXTURE_2D, colorTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(target, 0, GL_RGBA, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels);
}
else
return false;
return true;
}
void LocationImage::Matrix4Ortho(float *M, float left, float right, float bottom, float top, float zNear, float zFar)
{
const float tx = - (right + left) / (right - left),
ty = - (top + bottom) / (top - bottom),
tz = - (zFar + zNear) / (zFar - zNear);
M[ 0] = 2 / (right - left); M[ 1] = 0; M[ 2] = 0; M[ 3] = tx;
M[ 4] = 0; M[ 5] = 2 / (top - bottom); M[ 6] = 0; M[ 7] = ty;
M[ 8] = 0; M[ 9] = 0; M[10] = -2 / (zFar - zNear); M[11] = tz;
M[12] = 0; M[13] = 0; M[14] = 0; M[15] = 1;
}
void LocationImage::Matrix4Rotation(float * M, float x, float y, float z)
{
const float A = cosf(x), B = sinf(x), C = cosf(y),
D = sinf(y), E = cosf(z), F = sinf(z);
const float AD = A * D, BD = B * D;
M[ 0] = C * E;
M[ 1] = -C * F;
M[ 2] = D;
M[ 3] = 0;
M[ 4] = BD * E + A * F;
M[ 5] = -BD * F + A * E;
M[ 6] = -B * C;
M[ 7] = 0;
M[ 8] = -AD * E + B * F;
M[ 9] = AD * F + B * E;
M[10] = A * C;
M[11] = 0;
M[12] = 0;
M[13] = 0;
M[14] = 0;
M[15] = 1;
}
void LocationImage::Matrix4Translation(float *M, float x, float y, float z)
{
M[ 0] = 1; M[ 1] = 0; M[ 2] = 0; M[ 3] = x;
M[ 4] = 0; M[ 5] = 1; M[ 6] = 0; M[ 7] = y;
M[ 8] = 0; M[ 9] = 0; M[10] = 1; M[11] = z;
M[12] = 0; M[13] = 0; M[14] = 0; M[15] = 1;
}
void LocationImage::Matrix4Mul(float *M, float * A, float * B)
{
M[ 0] = A[ 0] * B[ 0] + A[ 1] * B[ 4] + A[ 2] * B[ 8] + A[ 3] * B[12];
M[ 1] = A[ 0] * B[ 1] + A[ 1] * B[ 5] + A[ 2] * B[ 9] + A[ 3] * B[13];
M[ 2] = A[ 0] * B[ 2] + A[ 1] * B[ 6] + A[ 2] * B[10] + A[ 3] * B[14];
M[ 3] = A[ 0] * B[ 3] + A[ 1] * B[ 7] + A[ 2] * B[11] + A[ 3] * B[15];
M[ 4] = A[ 4] * B[ 0] + A[ 5] * B[ 4] + A[ 6] * B[ 8] + A[ 7] * B[12];
M[ 5] = A[ 4] * B[ 1] + A[ 5] * B[ 5] + A[ 6] * B[ 9] + A[ 7] * B[13];
M[ 6] = A[ 4] * B[ 2] + A[ 5] * B[ 6] + A[ 6] * B[10] + A[ 7] * B[14];
M[ 7] = A[ 4] * B[ 3] + A[ 5] * B[ 7] + A[ 6] * B[11] + A[ 7] * B[15];
M[ 8] = A[ 8] * B[ 0] + A[ 9] * B[ 4] + A[10] * B[ 8] + A[11] * B[12];
M[ 9] = A[ 8] * B[ 1] + A[ 9] * B[ 5] + A[10] * B[ 9] + A[11] * B[13];
M[10] = A[ 8] * B[ 2] + A[ 9] * B[ 6] + A[10] * B[10] + A[11] * B[14];
M[11] = A[ 8] * B[ 3] + A[ 9] * B[ 7] + A[10] * B[11] + A[11] * B[15];
M[12] = A[12] * B[ 0] + A[13] * B[ 4] + A[14] * B[ 8] + A[15] * B[12];
M[13] = A[12] * B[ 1] + A[13] * B[ 5] + A[14] * B[ 9] + A[15] * B[13];
M[14] = A[12] * B[ 2] + A[13] * B[ 6] + A[14] * B[10] + A[15] * B[14];
M[15] = A[12] * B[ 3] + A[13] * B[ 7] + A[14] * B[11] + A[15] * B[15];
}
void LocationImage::Init(std::string image, float xbegin, float ybegin, float xend, float yend)
{
glCreateShader = (PFNGLCREATESHADERPROC) SDL_GL_GetProcAddress("glCreateShader");
glShaderSource = (PFNGLSHADERSOURCEPROC) SDL_GL_GetProcAddress("glShaderSource");
glCompileShader = (PFNGLCOMPILESHADERPROC) SDL_GL_GetProcAddress("glCompileShader");
glCreateProgram = (PFNGLCREATEPROGRAMPROC) SDL_GL_GetProcAddress("glCreateProgram");
glAttachShader = (PFNGLATTACHSHADERPROC) SDL_GL_GetProcAddress("glAttachShader");
glLinkProgram = (PFNGLLINKPROGRAMPROC) SDL_GL_GetProcAddress("glLinkProgram");
glUseProgram = (PFNGLUSEPROGRAMPROC) SDL_GL_GetProcAddress("glUseProgram");
glGenVertexArrays =(PFNGLGENVERTEXARRAYSPROC) SDL_GL_GetProcAddress("glGenVertexArrays");
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) SDL_GL_GetProcAddress("glBindVertexArray");
glGenBuffers = (PFNGLGENBUFFERSPROC) SDL_GL_GetProcAddress("glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERPROC) SDL_GL_GetProcAddress("glBindBuffer");
glBufferData = (PFNGLBUFFERDATAPROC) SDL_GL_GetProcAddress("glBufferData");
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) SDL_GL_GetProcAddress("glGetAttribLocation");
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) SDL_GL_GetProcAddress("glVertexAttribPointer");
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) SDL_GL_GetProcAddress("glEnableVertexAttribArray");
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) SDL_GL_GetProcAddress("glGetUniformLocation");
glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) SDL_GL_GetProcAddress("glUniformMatrix4fv");
glActiveTexture = (PFNGLACTIVETEXTUREPROC) SDL_GL_GetProcAddress("glActiveTexture");
glUniform1i = (PFNGLUNIFORM1IPROC) SDL_GL_GetProcAddress("glUniform1i");
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) SDL_GL_GetProcAddress("glDeleteBuffers");
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) SDL_GL_GetProcAddress("glDeleteVertexArrays");
glDeleteProgram = (PFNGLDELETEPROGRAMPROC) SDL_GL_GetProcAddress("glDeleteProgram");
glGetShaderiv = (PFNGLGETSHADERIVPROC) SDL_GL_GetProcAddress("glGetShaderiv");
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) SDL_GL_GetProcAddress("glGetShaderInfoLog");
SDL_VideoInfo* info = (SDL_VideoInfo*)SDL_GetVideoInfo();
glViewport(0,0,(GLsizei) info->current_w, (GLsizei) info->current_h);
X = 0;
Y = 0;
SDL_Surface * img = IMG_Load(image.c_str());
TargetSDLLoadSurface(GL_TEXTURE_2D, img);
shaderProgram = glCreateProgram();
vertexShader = glCreateShader(GL_VERTEX_SHADER);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
char *vs = NULL,*fs = NULL;
vs = textFileRead("shaders/vert/locationimage.vert");
fs = textFileRead("shaders/frag/locationimage.frag");
glShaderSource(vertexShader, 1, &vs,NULL);
glShaderSource(fragmentShader, 1, &fs,NULL);
glCompileShader(vertexShader);
glCompileShader(fragmentShader);
free(vs);free(fs);
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, colorTexture);
textureLocation = glGetUniformLocation(shaderProgram, "ColorTexture");
glUniform1i(textureLocation, 0);
Matrix4Ortho(projectionMatrix, -100, 100, -100, 100, -100, 100);
float ModelTranslationMatrix[16];
float ModelRotationMatrix[16];
Matrix4Translation(ModelTranslationMatrix, 0.0, 0.0, 0.0);
Matrix4Rotation(ModelRotationMatrix, 0.0, 0.0, 0.0);
Matrix4Mul(modelMatrix, ModelTranslationMatrix, ModelRotationMatrix);
float cameraTranslate[16];
float cameraRotate[16];
Matrix4Translation(cameraTranslate, 0.0, 0.0, 0.0);
Matrix4Rotation(cameraRotate, 0.0, 0.0, 0.0);
Matrix4Mul(cameraMatrix, cameraRotate, cameraTranslate);
worldMatrixLocation = glGetUniformLocation(shaderProgram, "worldMatrix");
int ind = 0;
float left_bottom_x = xbegin;
float right_bottom_x = xend;
float right_top_x = xend;
float left_top_x = xbegin;
float left_bottom_y = ybegin;
float right_bottom_y = ybegin;
float right_top_y = yend;
float left_top_y = yend;
vertices.push_back(left_bottom_x);
vertices.push_back(left_bottom_y);
vertices.push_back(right_bottom_x);
vertices.push_back(right_bottom_y);
vertices.push_back(right_top_x);
vertices.push_back(right_top_y);
vertices.push_back(left_top_x);
vertices.push_back(left_top_y);
texcoord.push_back(0.0);
texcoord.push_back(1.0);
texcoord.push_back(1.0);
texcoord.push_back(1.0);
texcoord.push_back(1.0);
texcoord.push_back(0.0);
texcoord.push_back(0.0);
texcoord.push_back(0.0);
indeces.push_back(ind);
ind++;
indeces.push_back(ind);
ind++;
indeces.push_back(ind);
ind++;
indeces.push_back(ind);
ind++;
glGenVertexArrays(1, &meshVAO);
glBindVertexArray(meshVAO);
glGenBuffers(3, meshVBO);
positionLocation = glGetAttribLocation(shaderProgram, "Vertex");
glBindBuffer(GL_ARRAY_BUFFER, meshVBO[0]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices.front(), GL_STATIC_DRAW);
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
glEnableVertexAttribArray(positionLocation);
texcoordLocation = glGetAttribLocation(shaderProgram, "TexCoord");
glBindBuffer(GL_ARRAY_BUFFER, meshVBO[1]);
glBufferData(GL_ARRAY_BUFFER, texcoord.size() * sizeof(float), &texcoord.front(), GL_STATIC_DRAW);
glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
glEnableVertexAttribArray(texcoordLocation);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshVBO[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indeces.size() * sizeof(int), &indeces.front(), GL_STATIC_DRAW);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
vertices.clear();
texcoord.clear();
SDL_FreeSurface(img);
}
void LocationImage::NewModelMatrix(float x, float y)
{
float ModelTranslationMatrix[16];
float ModelRotationMatrix[16];
X += x;
Y += y;
Matrix4Translation(ModelTranslationMatrix, X, Y, 0.0);
Matrix4Rotation(ModelRotationMatrix, 0.0, 0.0, 0.0);
Matrix4Mul(modelMatrix, ModelTranslationMatrix, ModelRotationMatrix);
}
void LocationImage::NewModelMatrixMove(float x, float y)
{
float ModelTranslationMatrix[16];
float ModelRotationMatrix[16];
Matrix4Translation(ModelTranslationMatrix, x, y, 0.0);
Matrix4Rotation(ModelRotationMatrix, 0.0, 0.0, 0.0);
Matrix4Mul(modelMatrix, ModelTranslationMatrix, ModelRotationMatrix);
}
void LocationImage::Render()
{
glBindTexture(GL_TEXTURE_2D, colorTexture);
glUseProgram(shaderProgram);
float newMatrix[16];
float worldMatrix[16];
Matrix4Mul(newMatrix, projectionMatrix, modelMatrix);
Matrix4Mul(worldMatrix, cameraMatrix, newMatrix);
glUniformMatrix4fv(worldMatrixLocation, 1, GL_TRUE, worldMatrix);
glBindVertexArray(meshVAO);
glDrawElements(GL_QUADS, indeces.size(), GL_UNSIGNED_INT, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
}