GLUT를 사용하지 않습니다.
GLFW 나 GLEW 를 사용하는 에제를 추천합니다.
아래 예제는 GLEW 를 사용합니다.
https://kyoungwhankim.github.io/ko/blog/opengl_intro/
OpenGL 소개: OpenGL, GLFW, GLEW란? [OpenGL E02]
OpenGL/GLEW/GLFW
kyoungwhankim.github.io
OpenGL 설치: GLEW, GLFW 다운로드법과 Visual Studio에서 OpenGL 사용하기 [OpenGL E03]
velog.io
glut 에서 GFLW + GLEW 사용으로 발전함.
GitHub - TakashiL/OpenGL-Tetris: A Tetris game using opengl
A Tetris game using opengl. Contribute to TakashiL/OpenGL-Tetris development by creating an account on GitHub.
github.com
유니티 하고 언리얼이 없다면
쉐이더 하고 메시를 전부 코드로 셋팅해 주어야 하는 불편함이 엄청나다.
언리얼의 내부와 상당히 비슷하다.
모드, 컨트롤, 각 레이어(레벨) 별로 동작한다.
glBegin(GL_POLYGON);
glVertex2f(20 + x, 380 + y);
glVertex2f(120 + x, 380 + y);
glVertex2f(120 + x, 480 + y);
glVertex2f(20 + x, 480 + y);
glEnd();
glColor3f(0, 0, 0);
위 함수에서
아래 처럼 glDisableVertexAttribArray , glDrawArrays 함수 사용하는 세상으로 변했다.
opengl 에서 opengl es 를 사용하는 세상으로 변한 것이다.
애플에서는 더 이상 opengl es 를 사용하지 않는다고 한다.
void OpenGLRender::drawMesh()
{
if (!bkVertexBuffer.empty())
{
glEnableVertexAttribArray(0);
assert(!checkGlErrors());
glEnableVertexAttribArray(1);
assert(!checkGlErrors());
glEnableVertexAttribArray(2);
assert(!checkGlErrors());
commonProg.use();
glBindTexture(GL_TEXTURE_2D, bkTextureId);
assert(!checkGlErrors());
glBindBuffer(GL_ARRAY_BUFFER, bkVertexBufferId);
assert(!checkGlErrors());
glBufferData(GL_ARRAY_BUFFER, bkVertexBuffer.size() * sizeof(Vertex), bkVertexBuffer.data(), GL_STATIC_DRAW);
assert(!checkGlErrors());
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, xy));
assert(!checkGlErrors());
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
assert(!checkGlErrors());
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, rgba));
assert(!checkGlErrors());
glDrawArrays(GL_TRIANGLES, 0, (int)bkVertexBuffer.size());
assert(!checkGlErrors());
glDisableVertexAttribArray(0);
assert(!checkGlErrors());
glDisableVertexAttribArray(1);
assert(!checkGlErrors());
glDisableVertexAttribArray(2);
assert(!checkGlErrors());
}
if (!atlasVertexBuffer.empty())
{
glEnableVertexAttribArray(0);
assert(!checkGlErrors());
glEnableVertexAttribArray(1);
assert(!checkGlErrors());
glEnableVertexAttribArray(2);
assert(!checkGlErrors());
commonProg.use();
glBindTexture(GL_TEXTURE_2D, atlasTextureId);
assert(!checkGlErrors());
glBindBuffer(GL_ARRAY_BUFFER, atlasVertexBufferId);
assert(!checkGlErrors());
glBufferData(GL_ARRAY_BUFFER, atlasVertexBuffer.size() * sizeof(Vertex), atlasVertexBuffer.data(), GL_STATIC_DRAW);
assert(!checkGlErrors());
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, xy));
assert(!checkGlErrors());
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
assert(!checkGlErrors());
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, rgba));
assert(!checkGlErrors());
glDrawArrays(GL_TRIANGLES, 0, (int)atlasVertexBuffer.size());
assert(!checkGlErrors());
glDisableVertexAttribArray(0);
assert(!checkGlErrors());
glDisableVertexAttribArray(1);
assert(!checkGlErrors());
glDisableVertexAttribArray(2);
assert(!checkGlErrors());
}
if (!textVertexBuffer.empty())
{
glEnableVertexAttribArray(0);
assert(!checkGlErrors());
glEnableVertexAttribArray(1);
assert(!checkGlErrors());
glEnableVertexAttribArray(2);
assert(!checkGlErrors());
glEnableVertexAttribArray(3);
assert(!checkGlErrors());
fontProg.use();
glBindTexture(GL_TEXTURE_2D, fontTextureId);
assert(!checkGlErrors());
glBindBuffer(GL_ARRAY_BUFFER, textVertexBufferId);
assert(!checkGlErrors());
glBufferData(GL_ARRAY_BUFFER, textVertexBuffer.size() * sizeof(TextVertex), textVertexBuffer.data(), GL_STATIC_DRAW);
assert(!checkGlErrors());
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (void*)offsetof(TextVertex, xy));
assert(!checkGlErrors());
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (void*)offsetof(TextVertex, uv));
assert(!checkGlErrors());
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (void*)offsetof(TextVertex, rgba));
assert(!checkGlErrors());
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(TextVertex), (void*)offsetof(TextVertex, falloff));
assert(!checkGlErrors());
glDrawArrays(GL_TRIANGLES, 0, (int)textVertexBuffer.size());
assert(!checkGlErrors());
glDisableVertexAttribArray(0);
assert(!checkGlErrors());
glDisableVertexAttribArray(1);
assert(!checkGlErrors());
glDisableVertexAttribArray(2);
assert(!checkGlErrors());
glDisableVertexAttribArray(3);
assert(!checkGlErrors());
}
}
https://github.com/TakashiL/OpenGL-Tetris
GitHub - TakashiL/OpenGL-Tetris: A Tetris game using opengl
A Tetris game using opengl. Contribute to TakashiL/OpenGL-Tetris development by creating an account on GitHub.
github.com
창 속성을 읽는 함수가 있다.
if (!glfwGetWindowAttrib(wnd, GLFW_FOCUSED) && GameLogic::state == GameLogic::stPlaying)
{
//GameLogic::pauseGame();
//InterfaceLogic::showInGameMenu();
}
마우스 컨트롤 함수
void Control::updateGameControl()
{
if (GameLogic::state != GameLogic::stPlaying)
return;
KeyState leftButtonState = getKeyState(MOUSE_LEFT);
if (mouseMoved || leftButtonState.isPressed)
{
GameLogic::menuButtonHighlighted = false;
if (LayoutObject * gameLayout = Layout::screen.getChild(loGame))
{
if (LayoutObject * mouseoverObject = gameLayout->getObjectFromPoint(mouseX, mouseY))
{
if (mouseoverObject->id == loScoreBarMenuButton)
{
if (leftButtonState.isPressed)
{
GameLogic::pauseGame();
InterfaceLogic::showInGameMenu();
}
else
GameLogic::menuButtonHighlighted = true;
}
}
}
}
3가지 상태에서만 메뉴가 나타나고 싶다.
if (GameLogic::state == GameLogic::stGameOver|| GameLogic::state == GameLogic::stStopped || GameLogic::state == GameLogic::stPaused)
void OpenGLRender::updateMenuLayer()
{
MenuLogic * menuLogic = NULL;
LayoutObject * menuLayout = NULL;
float shadeProgress = 0.0f;
switch (InterfaceLogic::state)
{
case InterfaceLogic::stMainMenu:
menuLogic = &InterfaceLogic::mainMenu;
menuLayout = Layout::screen.getChild(loMainMenu);
shadeProgress = InterfaceLogic::menuShadeProgress;
break;
case InterfaceLogic::stInGameMenu:
menuLogic = &InterfaceLogic::inGameMenu;
menuLayout = Layout::screen.getChild(loInGameMenu);
shadeProgress = InterfaceLogic::menuShadeProgress;
break;
case InterfaceLogic::stQuitConfirmation:
menuLogic = &InterfaceLogic::quitConfirmationMenu;
menuLayout = Layout::screen.getChild(loQuitConfirmationMenu);
shadeProgress = InterfaceLogic::menuShadeProgress;
break;
case InterfaceLogic::stRestartConfirmation:
menuLogic = &InterfaceLogic::restartConfirmationMenu;
menuLayout = Layout::screen.getChild(loRestartConfirmationMenu);
shadeProgress = InterfaceLogic::menuShadeProgress;
break;
case InterfaceLogic::stExitToMainConfirmation:
menuLogic = &InterfaceLogic::exitToMainConfirmationMenu;
menuLayout = Layout::screen.getChild(loExitToMainConfirmationMenu);
shadeProgress = InterfaceLogic::menuShadeProgress;
break;
case InterfaceLogic::stSettings:
menuLogic = &InterfaceLogic::settingsLogic.saveConfirmationMenu;
menuLayout = Layout::screen.getChild(loSaveSettingsMenu);
shadeProgress = InterfaceLogic::settingsLogic.saveConfirmationMenu.transitionProgress;
break;
case InterfaceLogic::stLeaderboard:
break;
case InterfaceLogic::stHidden:
break;
default:
assert(0);
break;
}
if (GameLogic::state == GameLogic::stGameOver|| GameLogic::state == GameLogic::stStopped || GameLogic::state == GameLogic::stPaused)
if (menuLogic && menuLayout)
{
clearVertices();
buildRect(0.0f, 0.0f, 1.0f, 1.0f, glm::vec3(0.0f), Palette::backgroundShadeAlpha * shadeProgress);
drawMesh();
clearVertices();
buildMenu(menuLogic, menuLayout);
drawMesh();
}
}