i'm just trying to make simple version of fruits ninja by opengl.
all i need to do is slice rectangle (it has 4 vertex)
but i'm really stuck in this bad code
can anyone help me? here's my codes
vertex Shader
#version 330
layout(location = 0)in vec3 in_Position;
layout(location = 1)in vec3 in_Color;
uniform mat4 modelTransform;
uniform mat4 projectionTransform;
uniform mat4 viewTransform;
out vec3 ex_Color;
void main(void)
{
gl_Position = vec4(in_Position, 1.0);
ex_Color = in_Color;
}
Frag Shader
#version 330
in vec3 ex_Color;
out vec4 gl_FragColor;
void main(void)
{
gl_FragColor = vec4(ex_Color,1.0);
}
#include <fstream>
#include <iostream>
#include <string>
#include <gl/glew.h>
#include <gl/freeglut.h>
#include <gl/freeglut_ext.h>
#include <glm.hpp>
#include <ext.hpp>
#include <gtc/matrix_transform.hpp>
#include <time.h>
#include <stdlib.h>
#include <vector>
#include <math.h>
using namespace std;
class Point
{
public:
float x;
float y;
};
class Piece
{
public:
float x, y;
float dx, dy;
float Vert[4][3];
float Color[4][3];
int ID;
GLuint VAO;
GLuint VBO[2];
void Reshape()
{
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(2, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), Vert, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), Color, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
}
Piece()
{
x = NULL;
y = NULL;
dx = NULL;
dy = NULL;
ID = NULL;
}
Piece(int id, float deltax, float deltay)
{
x = -1.1f;
y = 0.5f;
for (int i = 0; i < 4; ++i)
{
Color[i][0] = 1;
Color[i][1] = 0;
Color[i][2] = 1;
}
Vert[0][0] = x - 0.1f;
Vert[0][1] = y + 0.1f;
Vert[0][2] = 0;
Vert[1][0] = x - 0.1f;
Vert[1][1] = y - 0.1f;
Vert[1][2] = 0;
Vert[2][0] = x + 0.1f;
Vert[2][1] = y + 0.1f;
Vert[2][2] = 0;
Vert[3][0] = x + 0.1f;
Vert[3][1] = y - 0.1f;
Vert[3][2] = 0;
Reshape();
ID = id;
dx = deltax;
dy = deltay;
}
Piece(int id, float deltax, float deltay, float v0[3], float v1[3], float v2[3], float v3[3])
{
ID = id;
dx = deltax;
dy = deltay;
for (int i = 0; i < 4; ++i)
{
Color[i][0] = 1;
Color[i][1] = 0;
Color[i][2] = 1;
}
for (int i = 0; i < 3; ++i)
{
Vert[0][i] = v0[i];
Vert[1][i] = v1[i];
Vert[2][i] = v2[i];
Vert[3][i] = v3[i];
}
x = Vert[2][0] - Vert[0][0];
y = Vert[2][1] = Vert[0][1];
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(2, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), Vert, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), Color, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
}
};
int cid = 0;
int delay = 0;
const float length = 0.5;
char* arr;
bool isClick = 0;
GLuint vertexShader;
GLuint fragmentShader;
GLuint ShaderProgram;
GLuint HLineVAO[3];
GLuint VLineVAO[6];
GLuint VBO[2];
GLuint MouseVAO;
float MouseLine[2][3];
float MouseLineColor[2][3] = {
{0, 0, 0},
{0, 0, 0}
};
vector<Piece> RectList;
vector<Point> LineList;
void convertXY(int w, int h, int x, int y, float& ox, float& oy)
{
ox = (float)(x - (float)w / 2.0) * (float)(1.0 / (float)(w / 2.0));
oy = -(float)(y - (float)h / 2.0) * (float)(1.0 / (float)(h / 2.0));
}
GLchar* filetobuf(const char* filename)
{
string tmp;
string Source;
ifstream readFile;
readFile.open(filename);
readFile.seekg(0, ios::end);
Source.reserve(readFile.tellg());
readFile.seekg(0, ios::beg);
Source.assign((istreambuf_iterator<char>(readFile)), istreambuf_iterator<char>());
arr = new char[Source.length() + 2];
strcpy_s(arr, Source.length() + 1, Source.c_str());
arr[Source.length() + 1] = '\0';
return arr;
}
void make_vertexShaders()
{
GLchar* vertexShaderSource = filetobuf("Vertex.glsl");
//--- 버텍스 세이더 읽어 저장하고 컴파일 하기
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
delete[] arr;
GLint result;
GLchar errorLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &result);
if (!result)
{
glGetShaderInfoLog(vertexShader, 512, NULL, errorLog);
cerr << "ERROR: vertex shader 컴파일 실패\n" << errorLog << endl;
return;
}
}
void make_fragmentShaders()
{
GLchar* fragmentShaderSource = filetobuf("Fragment.glsl");;
//--- 프래그먼트 세이더 읽어 저장하고 컴파일하기
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
delete[] arr;
GLint result;
GLchar errorLog[512];
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &result);
if (!result)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, errorLog);
cerr << "ERROR: fragment shader 컴파일 실패\n" << errorLog << endl;
return;
}
}
void InitBuffer()
{
float HLine[3][2][3];
float HLineColor[2][3] = {
{ 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 1.0f }
};
float VLine[6][2][3];
float VLineColor[2][3] = {
{ 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 1.0f }
};
for(int i = 0; i < 3; ++i)
{
HLine[i][0][0] = -1.0f;
HLine[i][0][1] = -0.7 - 0.1 * i;
HLine[i][0][2] = 0;
HLine[i][1][0] = 1.0f;
HLine[i][1][1] = -0.7 - 0.1 * i;
HLine[i][1][2] = 0;
}
for (int i = 0; i < 3; ++i)
{
glGenVertexArrays(1, &HLineVAO[i]);
glBindVertexArray(HLineVAO[i]);
glGenBuffers(2, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), HLine[i], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), HLineColor, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
}
for (int i = 0; i < 6; ++i)
{
VLine[i][0][0] = -1.0f + (2.0f / 6) * i;
VLine[i][0][1] = -0.7f;
VLine[i][0][2] = 0;
VLine[i][1][0] = -1.0f + (2.0f / 6) * i;
VLine[i][1][1] = -1.0f;
VLine[i][1][2] = 0;
}
for (int i = 0; i < 6; ++i)
{
glGenVertexArrays(1, &VLineVAO[i]);
glBindVertexArray(VLineVAO[i]);
glGenBuffers(2, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), VLine[i], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), VLineColor, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
}
}
void InitShader()
{
make_vertexShaders();
make_fragmentShaders();
//-- shader Program
ShaderProgram = glCreateProgram();
glAttachShader(ShaderProgram, vertexShader);
glAttachShader(ShaderProgram, fragmentShader);
glLinkProgram(ShaderProgram);
//--- 세이더 삭제하기
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
//--- Shader Program 사용하기
glUseProgram(ShaderProgram);
}
GLvoid drawScene() //--- 콜백 함수: 그리기 콜백 함수
{
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (isClick)
{
glBindVertexArray(MouseVAO);
glDrawArrays(GL_LINES, 0, 2);
}
for (int i = 0; i < 6; ++i)
{
glBindVertexArray(VLineVAO[i]);
glDrawArrays(GL_LINES, 0, 2);
}
for (int i = 0; i < 3; ++i)
{
glBindVertexArray(HLineVAO[i]);
glDrawArrays(GL_LINES, 0, 2);
}
vector<Piece>::iterator iter = RectList.begin();
for (; iter != RectList.end(); iter++)
{
for (int i = 0; i < 4; ++i)
{
iter->Vert[i][0] += iter->dx;
iter->Vert[i][1] += iter->dy;
}
iter->Reshape();
glBindVertexArray(iter->VAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
glutSwapBuffers(); // 화면에 출력하기
}
GLvoid Keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'q':
exit(0);
break;
case 'Q':
exit(0);
break;
}
}
GLvoid Mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
float ox, oy;
convertXY(1000, 1000, x, y, ox, oy);
MouseLine[0][0] = ox;
MouseLine[0][1] = oy;
MouseLine[0][2] = 0;
}
else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
{
if (MouseLine[0][0] != MouseLine[1][0])
{
vector<Piece>::iterator Riter = RectList.begin();
for (; Riter != RectList.end();)
{
int cnt = 0;
float Cutted[2][3];
Piece r1;
Piece r2;
bool isSet = 0;
vector<Point>::iterator Piter = LineList.begin();
for (; Piter != LineList.end(); ++Piter)
{
if (cnt == 0 && Piter->x > Riter->Vert[0][0] && Piter->x < Riter->Vert[3][0] && Piter->y < Riter->Vert[0][1] && Piter->y > Riter->Vert[3][1])
{
Cutted[0][0] = Piter->x;
Cutted[0][1] = Piter->y;
Cutted[0][2] = 0;
cnt++;
}
else if (cnt == 1 && (Piter->x < Riter->Vert[0][0] || Piter->x > Riter->Vert[3][0] || Piter->y > Riter->Vert[0][1] || Piter->y < Riter->Vert[3][1]))
{
Cutted[1][0] = Piter->x;
Cutted[1][1] = Piter->y;
Cutted[1][2] = 0;
break;
}
}
if (Cutted[0][0] < Riter->Vert[0][0] + 0.05 && Cutted[0][0] > Riter->Vert[0][0] - 0.05 && Cutted[0][1] < Riter->Vert[0][1] && Cutted[0][1] > Riter->Vert[1][1])
{
r1 = Piece(cid, -0.001f, -0.005f, Riter->Vert[0], Cutted[0], Riter->Vert[2], Cutted[1]);
cid++;
r2 = Piece(cid, 0.001f, -0.005f, Cutted[0], Riter->Vert[1], Cutted[1], Riter->Vert[3]);
Riter = RectList.erase(Riter);
isSet = 1;
}
else if (Cutted[0][0] < Riter->Vert[2][0] + 0.05 && Cutted[0][0] > Riter->Vert[2][0] - 0.05 && Cutted[0][1] < Riter->Vert[2][1] && Cutted[0][1] > Riter->Vert[3][1])
{
r1 = Piece(cid, -0.001f, -0.005f, Riter->Vert[0], Cutted[1], Riter->Vert[2], Cutted[0]);
cid++;
r2 = Piece(cid, 0.001f, -0.005f, Cutted[1], Riter->Vert[1], Cutted[0], Riter->Vert[3]);
Riter = RectList.erase(Riter);
isSet = 1;
}
else if (Cutted[0][1] < Riter->Vert[1][1] + 0.05 && Cutted[0][1] > Riter->Vert[1][1] - 0.05 && Cutted[0][0] < Riter->Vert[1][0] && Cutted[0][0] > Riter->Vert[3][0])
{
r1 = Piece(cid, -0.001f, -0.005f, Riter->Vert[0], Riter->Vert[1], Cutted[1], Cutted[0]);
cid++;
r2 = Piece(cid, 0.001f, -0.005f, Cutted[1], Cutted[0], Riter->Vert[2], Riter->Vert[3]);
Riter = RectList.erase(Riter);
isSet = 1;
}
else if (Cutted[0][1] < Riter->Vert[0][1] + 0.05 && Cutted[0][1] > Riter->Vert[0][1] - 0.05 && Cutted[0][0] < Riter->Vert[0][0] && Cutted[0][0] > Riter->Vert[2][0])
{
r1 = Piece(cid, -0.001f, -0.005f, Riter->Vert[0], Riter->Vert[1], Cutted[0], Cutted[1]);
cid++;
r2 = Piece(cid, 0.001f, -0.005f, Cutted[0], Cutted[1], Riter->Vert[2], Riter->Vert[3]);
Riter = RectList.erase(Riter);
isSet = 1;
}
else
{
Riter++;
}
if(isSet)
{
RectList.push_back(r1);
RectList.push_back(r2);
break;
}
}
}
}
isClick = 0;
LineList.clear();
}
GLvoid Motion(int x, int y)
{
float ox, oy;
isClick = 1;
convertXY(1000, 1000, x, y, ox, oy);
MouseLine[1][0] = ox;
MouseLine[1][1] = oy;
MouseLine[1][2] = 0;
Point p;
p.x = ox;
p.y = oy;
LineList.push_back(p);
glGenVertexArrays(1, &MouseVAO);
glBindVertexArray(MouseVAO);
glGenBuffers(2, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), MouseLine, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), MouseLineColor, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
}
GLvoid Timer(int Value)
{
if (Value == 500)
{
Piece r = Piece(cid, 0.005f, -0.001f);
cid++;
RectList.push_back(r);
delay = 0;
}
delay++;
glutPostRedisplay();
glutTimerFunc(1, Timer, delay);
}
int main(int argc, char** argv)
{
srand((unsigned int)time(NULL));
GLint width = 1000;
GLint height = 1000;
glutInit(&argc, argv);// glut 초기화
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(width, height);
glutCreateWindow("Example1");
glewExperimental = GL_TRUE;
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glFrontFace(GL_CCW);
glewInit();
InitShader();
InitBuffer();
glutTimerFunc(1, Timer, delay);
glutKeyboardFunc(Keyboard);
glutMouseFunc(Mouse);
glutMotionFunc(Motion);
glutDisplayFunc(drawScene);
glutMainLoop();
}