IntelliJ에서 SVN을 연결하여 프로젝트 파일을 관리하고 공유하는 방법에 대해 알아봅니다.

IntelliJ 설치와 프로젝트 생성 그리고 VisualSVN 설치와 관리 방법은 이전에 작성한 글을 참고하고

IntelliJ IDEA 2023.3
설치 프로젝트 생성


VisualSVN Server 5.3.1 Repository
생성 및 User Group 관리

 

여기서는 IntelliJ에서 SVN에 연결하여 프로젝트들을 Share하고 Commit 하는 방법에 대해 설명합니다.

 

 

1. IntelliJ SVN 프로그램 연결

 

IntelliJ에서 svn 프로그램을 사용할 수 있도록 연결해 주어야 별도의 SVN 프로그램을 사용하지 않고 바로 CommitUpdate를 할 수 있습니다.

먼저 IntelliJ를 실행합니다.

 

 

IntelliJ 설치를 설명할 때 생성해 놓은 Sample 프로젝트가 보이는군요.

 

SVN 프로그램을 연결하려면 먼저 프로그램이 설치되어 있어야겠죠.

VisualSVN에는 Apache Subversion이 포함되어 있다고 VisualSVN 설치할 때 설명 드렸는데 진짜인지 확인을 해볼까요?

 

 

 

VisualSVN이 설치된 폴더(C:\Program Files\VisualSVN Server\bin)에 가보면 svn.exe 파일이 있는것을 확인할 수 있습니다.

IntelliJsvn.exe 파일을 등록해주면 이 프로그램을 이용하여 파일을 관리하게 됩니다.

svn 파일은 기존에 Tortoise SVN등 다른 프로그램을 설치하였으면 그것을 이용해도 됩니다.

 

등록을 진행해봅니다.

 

 

 

상위 메뉴에서 File > Settings... 메뉴를 선택하여 Settings 팝업을 오픈합니다.

 

 

 

Settings 팝업 좌측에서 Version Control > Subversion 메뉴를 선택 하면 우측에 Path to Subversion executable 항목이 보입니다.

입력란 끝에 있는 폴더 모양 아이콘을 클릭하여 Subversion 팝업을 오픈합니다.

 

 

 

Subversion 팝업 창 화면이 나타나면 여기서 svn.exe 파일을 선택하고 [OK] 버튼을 클릭해 줍니다.

 

 

 

하단에 있는 [Apply] 버튼과 [OK] 버튼을 클릭하여 설정을 반영하면 등록이 완료됩니다.

 

 

2. SVN Repository 연결

 

이제 프로젝트를 저장할 SVN Repository를 연결합니다.

VisualSVN에서 Repository를 생성할 때 위치 접속 정보를 알려주는데 이 주소를 사용하면 됩니다.

저장소 생성시 나오는 화면을 잠시 보면

 

 

 

Repository URL 항목에 주소와 Repository 명칭의 조합으로 되어있습니다.

URL을 등록하면 연결이 됩니다.

 

 

 

IntelliJ 상단 메뉴에서 VSC > Browse VCS Repository > Browse Subversion Repository... 를 선택하면 IntelliJ 하단에 SVN Repositories 창이 나타납니다.

 

 

 

여기서 좌측에 있는 [+] 모양을 클릭하면 Repository 주소를 입력할 수 있는 창이 나타납니다.

 

 

 

팝업 창에 Repository 주소를 입력하고 [OK] 버튼을 클릭합니다.

 

 

 

주소가 하나 추가되었습니다.

 

 

3. Project Share

 

 

이제 연결된 Repository에 테스트로 생성한 Sample1 프로젝트를 처음으로 share 해보도록 합니다.

 

 

 

상단 메뉴에서 VCS > Share Project (Subversion)... 을 선택하면 창이 하나 나타납니다.

 

 

 

프로젝트를 Share할 레포지토리를 선택하고 하단 입력 창(commit comment)에 간단한 내용를 작성하고 [Share] 버튼을 클릭합니다.

 

 

 

Subversion 포맷은 가장 최신 것으로 선택 하는게 좋겠죠.  [OK] 버튼을 클릭합니다.

 

 

 

VisualSVN에서 User 생성시 사용한 ID와 비밀번호를 입력해 줍니다.

[Save credentials] 체크하고 [OK] 버튼을 클릭합니다.

 

 

 

Share Directory 작업이 진행됩니다.

 

 

 

Sample1 프로젝트 Share Directory 작업이 완료 되었습니다.

 

 

 

vcs.xml에 등록을 하라고 하는데 [Add] 버튼을 클릭합니다.

 

 

4. File Commit

 

이제 파일을 commit 합니다.

위에서 작업한건 Share Directory이지 file을 올린건 아닙니다.

 

 

Sample1 Project에 마우스를 대고 우클릭 해서 Subversion > Commit Directory... 를 클릭하면 Commit Changes 팝업 창이 나타납니다.

 

 

 

이 창에서 commit 하려는 파일을 선택 또는 취소하고 변경된 부분을 확인하는 등의 작업을 할 수 있습니다.  처음 commit 작업이므로 모든 파일을 선택 합니다.

간단하게 Commit Message를 입력하고 [Commit] 버튼을 클릭하면 commit이 진행됩니다.

 

 

 

commit 완료 후 하단 SVN Repositories를 보면 Project 파일이 올라가 있는걸 볼 수 있습니다.

 

 

여러 개의 Project를 올리면 어떤 모습인지 보기위해 프로젝트를 하나 더 생성해서 동일한 작업을 진행해봅니다.

 

Sample2 라는 프로젝트를 생성해서 동일한 작업을 반복하여 중간 과정은 생략하고 Share 하는 단계부터 설명 합니다.

 

 

 

Repository를 선택하고 간단한 Comment를 작성한 후 Sample2 프로젝트를 Share 합니다.

 

 

 

포맷을 정하고

 

 

 

Share Directory가 진행됩니다.

 

 

 

SVN Repositories 에서 Share Directory 후의 모습입니다.

commit을 하지 않아 trunk 폴더에 소스가 올라가있지 않습니다.

 

commit을 진행합니다.

 

 

 

Commit Message를 입력하고 Commit 버튼을 클릭합니다.

 

 

 

Commit이 완료되고 하단의 SVN Repositories 영역에서 마우스를 우클릭하여 리프레쉬 해보면

 

 

 

Sample2 프로젝트에도 파일이 올라간걸 확인할 수 있습니다.

 

 

 

VisualSVN 프로그램을 실행해서 지금까지 진행한 작업이 잘 되었는지 확인해봅니다.

모든 작업이 잘 완료되었습니다.

 

- copy coding -

 

 

몇년 전에 VisualSVN 4.x 버전에 대해 설치 방법을 알아보았는데 변경된 기능이 있는지 확인하기위해 설치 및 간단한 사용법을 알아봅니다.

한가지 주의사항은 컴퓨터 이름이 영문이어야 설치가 가능합니다.  한글인 경우 설치가 중단됩니다.

 

먼저 프로그램을 다운로드 받습니다.

 

https://www.visualsvn.com/downloads/

 

사이트에 접속하면 다양한 제품이 있는데 SVN을 찾아봅니다.

 

 

2개의 버전이 보이는데 [VisualSVN Server 5.3.1 (x64-bit)]를 클릭하고 저장할 폴더를 선택해서 VisualSVN-Server-5.3.1-x64.exe 파일을 다운로드 합니다.

 

다운로드가 완료되면 프로그램을 실행합니다.

 

 

 

제품에 Apache HTTP ServerApache Subversion이 포함되어 있다는 안내 글이 보입니다.

[Next] 버튼을 클릭합니다.

 

 

 

저작권 관련 내용으로 [I accept the terms in the License Agreement] 앞에 있는 체크박스를 클릭해야 [Next] 버튼이 활성화됩니다. [Next] 버튼을 클릭합니다.

 

 

 

컴포넌트 선택 화면인데 기본값으로 하고 [Next] 버튼을 클릭합니다.

 

 

 

설치 위치와 접속 방법 등에 대한 선택 화면입니다.

repositories 위치를 변경 하려면  [Browse...] 버튼을 클릭 하고

 

 

 

폴더를 선택해주면 됩니다.

 

 

 

Repositories 위치를 변경을 해보았습니다.

서버 접속 Port도 변경하려면 수정을 하고 [Next] 버튼을 클릭합니다.

 

 

 

설치 후 툴에서 full-text 검색이 가능하게 해준다는데 개발 툴에서 검색하면 될것 같아 [Next] 버튼을 클릭합니다.

 

 

 

사용자 인증 관리를 Subversion에서 하는 것으로 놓고 [Next] 버튼을 클릭합니다.

사용자 추가와 그룹관리는 아래에서 설명합니다.

 

 

 

설정이 완료되었습니다.  만약 수정이 필요하면 [Back] 버튼을 클릭하여 수정을 하고 설치를 진행하려면 [Install] 버튼을 클릭합니다.

 

 

 

설치가 진행됩니다.

설치하다가 컴퓨터 이름이 한글인 경우 설치가 중단됩니다. 

꼭 영문으로 컴퓨터 이름을 변경하세요.

 

 

 

설치가 완료되었습니다.  VisualSVN Server를 실행하도록 하고 [Finish] 버튼을 클릭 합니다.

 

 

 

VisualSVN Server의 모습입니다.

 

Repository를 하나 생성하도록 하겠습니다.

 

 

 

좌측 트리 메뉴에서 Repositories에 마우스를 놓고 우측 클릭을 하여 팝업 메뉴를 띄웁니다.

여기서 [Create New Repository]를 클릭합니다.

 

 

 

Regular FSFS(Fast Secure File System)으로 기본적인 저장 방법과

Distributed VDFS(VisualSVN Distributed File System)으로 master slave로 분리되어 이중으로 저장하는 방법이 있습니다.

그냥 기본으로 두고 [Next] 버튼을 클릭합니다.

 

 

 

새로 생성하는 Repository 이름을 마음대로 결정합니다.  저는 TestRepository로 했습니다.

 

 

 

Empty는 빈공간을 만들고 여기에 여러 개의 프로젝트를 추가하도록 하는 방법과 Single-project로 처음부터 하나의 프로젝트만 관리하도록 생성하는 방법이 있습니다.

기본으로 놔두고 [Next] 버튼을 클릭합니다.

 

 

 

모든 사용자가 읽기 쓰기 가능하도록 두고 [Next] 버튼을 클릭합니다.

 

 

 

앞에서 설정할때 Search Index를 체크한 경우 필요한 기능입니다.

[Create] 버튼을 클릭하여 저장소를 생성합니다.

 

 

 

저장소에 접근할 수 있는 방법으로 URL을 알려주고 있습니다.

Eclipse, Intellij등에서 형상관리를 위해 접속하는데 사용하면 됩니다.

잘 복사해 놓습니다.

 

이제 사용자와 그룹을 만들어서 관리해보도록 하겠습니다.

 

 

좌측 메뉴에서 Users에 마우스를 대고 우클릭을 합니다.

[Create User...] 메뉴를 클릭 합니다.

 

 

 

신규 사용자와 비밀번호를 입력해서 유저를 생성합니다.

비밀번호는 기억하거나 어딘가에 적어놓도록 합니다.

 

 

비밀번호가 너무 간단하다고 하는데 위에 있는 Proceed ...라고 적힌 상단 글씨를 클릭하면 그냥 생성됩니다.

 

 

 

User가 생성되었습니다.

 

 

 

그룹도 동일한 방법으로 Groups에 마우스를 놓고 우클릭을 합니다.

[Create Group...] 메뉴를 클릭 합니다.

 

 

 

그룹 이름을 적당히 입력하고 그룹에 멤버를 추가하기 위해 하단의 [Add...] 버튼을 클릭해 봅니다.

 

 

 

조금 전 생성한 User가 보입니다. 

선택하고 [OK] 버튼을 클릭합니다.

  

 

 

 

together 그룹에 추가되었습니다.

추가할 사용자가 더 없으니 그냥 [OK] 버튼을 클릭합니다.

 

 

 

그룹이 멤버를 포함하면서 생성이 되었습니다.

 

 

이제 생성한 Repository를 사용할 수 있는 사용자 또는 그룹을 연결하는 작업을 시작해 봅니다.

 

 

생성한 TestRepository에 마우스를 놓고 우클릭하여 [Properties...]를 클릭합니다.

 

 

 

Everyone이라는 그룹이 기본으로 포함되어 있습니다. 

조금전에 생성한 그룹을 포함하기 위해 [Add...] 버튼을 클릭합니다.

 

 

 

조금전에 생성한 together 그룹이 보입니다. 선택하고 [OK] 버튼을 클릭합니다.

물론 아래에 있는 user를 한명, 한명 추가하려면 하단에 있는 Users에서 선택을 해도 되지만 그럼 사용자가 많은 경우 관리가 어렵게 됩니다.

 

 

 

기본으로 추가된 Everyone은 아무나 접속 가능한 설정이므로 접속을 차단해야 합니다.

Everyone을 선택하고 하단에 있는 No Access 라디오 버튼을 선택한 후 [OK] 버튼을 클릭하면 접속권한이 취소됩니다.

 

 

 

 

이런식으로 사용자와 그룹을 관리하면 됩니다.

 

다음번에는 Repository Project Share하고 commit 해보도록 하겠습니다.

 

- copy coding -

 

오랬 동안 Eclipse를 사용하여 개발을 해왔는데 최근에 IntellJ를 사용할 기회가 되어 설치부터 차근차근 정리를 해보려고 합니다.

 

JetBrains 사이트에 접속하여 설치 프로그램을 다운로드 합니다.

 

https://www.jetbrains.com/ko-kr/idea/download/?section=windows

 

 

다운로드 페이지에 접속해서 처음에 보이는 IntelliJ IDEA Ultimate는 유료 버전으로 30일 평가판이고 아래쪽으로 내려가면 IntelliJ IDEA Community Edition이 보입니다.

 

 

 

[다운로드]를 클릭하여 IntelliJ IDEA Community Edition 설치파일을 다운로드 받습니다.

 

다운받은 설치파일(ideaIC-2023.3.exe)을 실행하여 설치를 위한 설정 작업을 시작합니다.

설정 및 설치 작업은 간단 합니다.

 

 

[Next] 버튼을 클릭합니다.

 

 

설치 위치를 선택하거나 기본 값을 그대로 사용하여 [Next] 버튼을 클릭합니다.

 

 

 

설치 옵션 선택입니다.

 

Create Desktop Shortcut : 바탕화면에 바로가기 생성 여부입니다.

Update PATH variable(restart needed) : 윈도우 환경변수에 자동으로 추가해 줍니다.

Update Context menu : 프로젝트 폴더를 선택해서 바로 작업 가능하도록 설정합니다.

Create Association : 사용 언어와 환경을 선택하는 것으로 복수선택이 가능합니다.

 

필요한 항목을 체크하고 [Next] 버튼을 클릭합니다.

 

 

여기까지 환경 설정 작업이었습니다.

[Install] 버튼을 클릭하여 설치를 진행합니다.

 

 

 

설치가 진행되고 잠시 후 완료됩니다.

 

 

 

컴퓨터를 새로 시작해서 바로 환경설정을 적용하거나 나중에 재부팅을 선택합니다.

일단 나중에 재부팅 하기로 하고 [Finish] 버튼을 클릭하여 설치된 Intellij 프로그램을 실행해 봅니다.

 

 

 

사용전에 라이센스 동의를 해야 합니다.  체크박스에 체크하면 [Continue] 버튼이 활성화됩니다.

[Continue] 버튼을 클릭합니다.

 

 

 

인텔리제이를 사용하면서 사용환경 등 여러가지 정보를 보내달라고 하는데 [Don’t Send]를 클릭해서 거절합니다.

 

 

 

드디어 Intellij를 사용할 수 있는 화면에 도달했습니다.

 

좌측에 환경설정을 할 수 있는 메뉴들이 있는데 필요에 따라 하나씩 설정을 하면 됩니다.

간단하게 한번씩 클릭을 해봅니다.

 

 

 

[Customize]를 클릭하면 우측에서 테마는 검은색 그대로 놔두고 디스플레이가 1920x1080인 경우는 글자가 너무 크게 보여서 폰트는 13.0에서 조금 작게 선택했습니다.

 

 

 

[Plugins]에서 Marketplace에는 설치할 수 있는 플러그인이 있고 Installed에는 기존에 설치되어 있는 Plugin들을 볼 수 있습니다.

 

[Learn]은 사용법에 대한 학습을 할 수 있는 새로운 팝업 창이 나타납니다.

 

다시 좌측메뉴에서 [Projects]를 선택하고 우측에서  [New Project]를 선택해서 신규로 프로젝트를 하나 생성해보도록 하겠습니다.

 

 

 

대부분 알아서 입력 또는 선택하면 되는데 JDK는 기존에 설치한 프로그램이 없으면 바로 다운로드 가능 합니다.

 

 

 

여러 버전 중 하나를 선택하고 설치 위치도 설정해서 [Download] 버튼을 클릭합니다.

 

 

 

바로 설치가 진행됩니다.

 

 

 

[Advanced Settings]를 확장하면 기본값이 설정되어 있는데 필요한 내용으로 수정합니다.

 

[Create] 버튼을 클릭하면 프로젝트가 생성됩니다.

 

 

 

프로젝트가 생성된 모습입니다.

Pom.xml 파일을 보니 너무 심플하네요.  한참을 채워 넣어야 할 것 같습니다.

상단에 있는 실행 버튼을 클릭해서 프로젝트를 실행해 봅니다.

 

 

 

Java도 잘 실행이 되는군요.

 

 

 

선택한 폴더에 프로젝트 파일도 생성되었습니다.

사용해 보면서 하나씩 추가적인 기능 설명도 정리를 해보겠습니다.

 

- copy coding -

 

 

이전 글에서 Google에서 학습을 위해 제공하는 OpenGL ES 3.0 관련 소스를 이용하여 삼각형과 사각형을 그려보았습니다.

 

Android OpenGL ES 3.0 삼각형 그리기(java 버전)

 


Android OpenGL ES 3.0 사각형 그리기(java 버전)

 

 

오늘은 직육면체를 그려보려고 하는데 소스는 구글 개발자 사이트에서 찾을 수 없어 인터넷을 찾아보다가 https://github.com/JimSeker/opengl 에서 적당한 소스를 찾아 소개를 드립니다.

프로그램 구성이 구글에서 설명하는 방식과 거의 동일한 구조로 되어있어서 이해하기가 쉬울것 같아 선택했습니다.

 

최종 구현 모습은 여러 곳에서 한번쯤 본듯한 형태입니다.

 

 

 

 

사각형을 그릴때 설명한것 처럼 삼각형을 2개 연결해서 사각형을 그렸습니다.  이번에도 삼각형을 그려서 사각형을 만들고 이 사각형들을 모아서 6면체를 만들게 됩니다.

사용되는 java 프로그램 소스는 처음에 삼각형 그리기 편에서 설명했던 내용이 변함 없이 적용 됩니다.  기본이되는 2개의 클래스가 있는데 이 클래스에 대한 자세한 설명은 삼각형 그리기를 참고하면 되고 여기서는 간략하게 어떤 내용이 있었는지 제목 정도만 알아보겠습니다.

 

GLSurfaceView 클래스 : 객체를 그리고 조작할 수 있는 View 이며 터치 리스너를 구현할 수 있습니다.

 

GLSurfaceView.Renderer 클래스 : 3개의 기본 메서드를 구현해야합니다.

  - onSurfaceCreated() : 최초 한번 호출되며 초기화가 필요한 내용 기술.

  - onDrawFrame() : GLSurfaceView를 다시 그릴때마다 호출되며 Object를 움직이거나 변형 가능.

  - onSurfaceChanged() : GLSurfaceView의 크기, 방향 변경시 호출된다.

 

 

다른 도형과 다르게 Cube 그리기에서 추가되는 부분이 있는데 터치 관련 기능입니다.  GLSurfaceVIew 클래스 설명에 터치 이벤트를 구현한다고 되어있는것 처럼 GLSurfaceView 클래스에 onTouchEvent()가 추가 됩니다.  구현할 때

 

private static final float TOUCH_SCALE_FACTOR = 0.0015f;

 

이 값을 변경하면 화면을 터치하고 Object를 이동 시킬때 한번에 이동하는 거리를 조절할 수 있습니다.

 

Renderer 프로그램에는 onDrawFrame()에서 물체의 변형이나 움직임을 구현할 수 있다고 하였는데 여기서는 육면체를 회전시키는 작업이 추가됩니다.  코드에서

 

mAngle+=4;

 

이 각도값을 변경하면 회전하는 속도를 조절할 수 있습니다.

 

myColor.java 라는 파일이 하나 추가되었는데 삼각형, 사각형은 2차원 이미지라 색상 값을 그냥 코드에 추가를 하였는데 정육면체는 6개의 색을 표현하기 위해 별도의 파일로 만들어 놓았습니다. 귀찮으면 그냥 파일을 만들지 말고 구현하거나 단색으로 테스트해도 됩니다.

설명을 이정도로 하고 실행 했을 때의 모습을 보겠습니다.

 

 

 

 

아래는 전체 코드입니다.  수정하지 않은 파일을 첨부하지 않았습니다.

위에서 소개한 페이지로 가서 소스를 다운받아 테스트 하셔도 됩니다.

 

AndroidManifest.xml

 

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools">



    <uses-feature android:glEsVersion="0x00030000" android:required="true" />



    <application

        android:allowBackup="true"

        android:dataExtractionRules="@xml/data_extraction_rules"

        android:fullBackupContent="@xml/backup_rules"

        android:icon="@mipmap/ic_launcher"

        android:label="@string/app_name"

        android:roundIcon="@mipmap/ic_launcher_round"

        android:supportsRtl="true"

        android:theme="@style/Theme.OpenGLTest"

        tools:targetApi="31">

        <activity

            android:name=".MainActivity"

            android:exported="true">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />



                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>



</manifest>

 

 

 

 

myGlSurfaceView.java

 

package com.example.opengltest;



import android.content.Context;

import android.opengl.GLSurfaceView;

import android.view.MotionEvent;



public class myGlSurfaceView extends GLSurfaceView {



    myRenderer myRender;



    public myGlSurfaceView(Context context) {

        super(context);



        // Create an OpenGL ES 3.0 context.

        setEGLContextClientVersion(3);



        super.setEGLConfigChooser(8, 8, 8, 8, 16, 0);



        // Set the Renderer for drawing on the GLSurfaceView

        myRender = new myRenderer(context);

        setRenderer(myRender);



        // Render the view only when there is a change in the drawing data

        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

    }



    //private final float TOUCH_SCALE_FACTOR = 180.0f / 320;

    private static final float TOUCH_SCALE_FACTOR = 0.0015f;

    private float mPreviousX;

    private float mPreviousY;



    @Override

    public boolean onTouchEvent(MotionEvent e) {

//        return super.onTouchEvent(event);



        float x = e.getX();

        float y = e.getY();



        switch (e.getAction()) {

            case MotionEvent.ACTION_MOVE:



                float dx = x - mPreviousX;

                //subtract, so the cube moves the same direction as your finger.

                //with plus it moves the opposite direction.

                myRender.setX(myRender.getX() - (dx * TOUCH_SCALE_FACTOR));



                float dy = y - mPreviousY;

                myRender.setY(myRender.getY() - (dy * TOUCH_SCALE_FACTOR));

        }



        mPreviousX = x;

        mPreviousY = y;

        return true;

    }

}

 

 

 

 

myRenderer.java

 

package com.example.opengltest;



import android.content.Context;

import android.opengl.GLES30;

import android.opengl.GLSurfaceView;

import android.opengl.Matrix;

import android.util.Log;



import javax.microedition.khronos.egl.EGLConfig;

import javax.microedition.khronos.opengles.GL10;



public class myRenderer implements GLSurfaceView.Renderer {



    private int mWidth;

    private int mHeight;

    private static String TAG = "myRenderer";

    public Cube mCube;

    private float mAngle =0;

    private float mTransY=0;

    private float mTransX=0;

    private static final float Z_NEAR = 1f;

    private static final float Z_FAR = 40f;



    // mMVPMatrix is an abbreviation for "Model View Projection Matrix"

    private final float[] mMVPMatrix = new float[16];

    private final float[] mProjectionMatrix = new float[16];

    private final float[] mViewMatrix = new float[16];

    private final float[] mRotationMatrix = new float[16];





    public myRenderer(Context context) {

        //cube can not be instianated here, because of "no egl context"  no clue.

        //do it in onSurfaceCreate and it is fine.  odd, but workable solution.

    }

    public static int LoadShader(int type, String shaderSrc) {

        int shader;

        int[] compiled = new int[1];



        // Create the shader object

        shader = GLES30.glCreateShader(type);



        if (shader == 0) {

            return 0;

        }



        // Load the shader source

        GLES30.glShaderSource(shader, shaderSrc);



        // Compile the shader

        GLES30.glCompileShader(shader);



        // Check the compile status

        GLES30.glGetShaderiv(shader, GLES30.GL_COMPILE_STATUS, compiled, 0);



        if (compiled[0] == 0) {

            Log.e(TAG, "Erorr!!!!");

            Log.e(TAG, GLES30.glGetShaderInfoLog(shader));

            GLES30.glDeleteShader(shader);

            return 0;

        }



        return shader;

    }



    public static void checkGlError(String glOperation) {

        int error;

        while ((error = GLES30.glGetError()) != GLES30.GL_NO_ERROR) {

            Log.e(TAG, glOperation + ": glError " + error);

            throw new RuntimeException(glOperation + ": glError " + error);

        }

    }



    @Override

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {



        //set the clear buffer color to light gray.

        //GLES30.glClearColor(0.9f, .9f, 0.9f, 0.9f);

        //set the clear buffer color to a dark grey.

        GLES30.glClearColor(0.1f, .1f, 0.1f, 0.9f);

        //initialize the cube code for drawing.

        mCube = new Cube();

        //if we had other objects setup them up here as well.

    }



    @Override

    public void onSurfaceChanged(GL10 gl, int width, int height) {



        mWidth = width;

        mHeight = height;

        // Set the viewport

        GLES30.glViewport(0, 0, mWidth, mHeight);

        float aspect = (float) width / height;



        // this projection matrix is applied to object coordinates

        //no idea why 53.13f, it was used in another example and it worked.

        Matrix.perspectiveM(mProjectionMatrix, 0, 53.13f, aspect, Z_NEAR, Z_FAR);

    }



    @Override

    public void onDrawFrame(GL10 gl) {



        // Clear the color buffer  set above by glClearColor.

        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT | GLES30.GL_DEPTH_BUFFER_BIT);



        //need this otherwise, it will over right stuff and the cube will look wrong!

        GLES30.glEnable(GLES30.GL_DEPTH_TEST);



        // Set the camera position (View matrix)  note Matrix is an include, not a declared method.

        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);



        // Create a rotation and translation for the cube

        Matrix.setIdentityM(mRotationMatrix, 0);



        //move the cube up/down and left/right

        Matrix.translateM(mRotationMatrix, 0, mTransX, mTransY, 0);



        //mangle is how fast, x,y,z which directions it rotates.

        Matrix.rotateM(mRotationMatrix, 0, mAngle, 1.0f, 1.0f, 1.0f);



        // combine the model with the view matrix

        Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mRotationMatrix, 0);



        // combine the model-view with the projection matrix

        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);



        mCube.draw(mMVPMatrix);



        //change the angle, so the cube will spin.

        mAngle+=4;

    }



    //used the touch listener to move the cube up/down (y) and left/right (x)

    public float getY() {

        return mTransY;

    }



    public void setY(float mY) {

        mTransY = mY;

    }



    public float getX() {

        return mTransX;

    }



    public void setX(float mX) {

        mTransX = mX;

    }

}

 

 

Cube.java

 

package com.example.opengltest;



import android.opengl.GLES30;

import android.util.Log;



import java.nio.ByteBuffer;

import java.nio.ByteOrder;

import java.nio.FloatBuffer;



public class Cube {



    private int mProgramObject;

    private int mMVPMatrixHandle;

    private int mColorHandle;

    private FloatBuffer mVertices;



    //initial size of the cube.  set here, so it is easier to change later.

    float size = 0.4f;



    //this is the initial data, which will need to translated into the mVertices variable in the consturctor.

    float[] mVerticesData = new float[]{

            ////////////////////////////////////////////////////////////////////

            // FRONT

            ////////////////////////////////////////////////////////////////////

            // Triangle 1

            -size, size, size, // top-left

            -size, -size, size, // bottom-left

            size, -size, size, // bottom-right

            // Triangle 2

            size, -size, size, // bottom-right

            size, size, size, // top-right

            -size, size, size, // top-left

            ////////////////////////////////////////////////////////////////////

            // BACK

            ////////////////////////////////////////////////////////////////////

            // Triangle 1

            -size, size, -size, // top-left

            -size, -size, -size, // bottom-left

            size, -size, -size, // bottom-right

            // Triangle 2

            size, -size, -size, // bottom-right

            size, size, -size, // top-right

            -size, size, -size, // top-left



            ////////////////////////////////////////////////////////////////////

            // LEFT

            ////////////////////////////////////////////////////////////////////

            // Triangle 1

            -size, size, -size, // top-left

            -size, -size, -size, // bottom-left

            -size, -size, size, // bottom-right

            // Triangle 2

            -size, -size, size, // bottom-right

            -size, size, size, // top-right

            -size, size, -size, // top-left

            ////////////////////////////////////////////////////////////////////

            // RIGHT

            ////////////////////////////////////////////////////////////////////

            // Triangle 1

            size, size, -size, // top-left

            size, -size, -size, // bottom-left

            size, -size, size, // bottom-right

            // Triangle 2

            size, -size, size, // bottom-right

            size, size, size, // top-right

            size, size, -size, // top-left



            ////////////////////////////////////////////////////////////////////

            // TOP

            ////////////////////////////////////////////////////////////////////

            // Triangle 1

            -size, size, -size, // top-left

            -size, size, size, // bottom-left

            size, size, size, // bottom-right

            // Triangle 2

            size, size, size, // bottom-right

            size, size, -size, // top-right

            -size, size, -size, // top-left

            ////////////////////////////////////////////////////////////////////

            // BOTTOM

            ////////////////////////////////////////////////////////////////////

            // Triangle 1

            -size, -size, -size, // top-left

            -size, -size, size, // bottom-left

            size, -size, size, // bottom-right

            // Triangle 2

            size, -size, size, // bottom-right

            size, -size, -size, // top-right

            -size, -size, -size // top-left

    };



    float colorcyan[] = myColor.cyan();

    float colorblue[] = myColor.blue();

    float colorred[] = myColor.red();

    float colorgray[] = myColor.gray();

    float colorgreen[] = myColor.green();

    float coloryellow[] = myColor.yellow();



    //vertex shader code

    String vShaderStr =

            "#version 300 es           \n"

                    + "uniform mat4 uMVPMatrix;     \n"

                    + "in vec4 vPosition;           \n"

                    + "void main()                  \n"

                    + "{                            \n"

                    + "   gl_Position = uMVPMatrix * vPosition;  \n"

                    + "}                            \n";

    //fragment shader code.

    String fShaderStr =

            "#version 300 es                          \n"

                    + "precision mediump float;                   \n"

                    + "uniform vec4 vColor;                      \n"

                    + "out vec4 fragColor;                   \n"

                    + "void main()                                  \n"

                    + "{                                            \n"

                    + "  fragColor = vColor;                       \n"

                    + "}                                            \n";



    String TAG = "Cube";





    //finally some methods

    //constructor

    public Cube() {

        //first setup the mVertices correctly.

        mVertices = ByteBuffer

                .allocateDirect(mVerticesData.length * 4)

                .order(ByteOrder.nativeOrder())

                .asFloatBuffer()

                .put(mVerticesData);

        mVertices.position(0);



        //setup the shaders

        int vertexShader;

        int fragmentShader;

        int programObject;

        int[] linked = new int[1];



        // Load the vertex/fragment shaders

        vertexShader = myRenderer.LoadShader(GLES30.GL_VERTEX_SHADER, vShaderStr);

        fragmentShader = myRenderer.LoadShader(GLES30.GL_FRAGMENT_SHADER, fShaderStr);



        // Create the program object

        programObject = GLES30.glCreateProgram();



        if (programObject == 0) {

            Log.e(TAG, "So some kind of error, but what?");

            return;

        }



        GLES30.glAttachShader(programObject, vertexShader);

        GLES30.glAttachShader(programObject, fragmentShader);



        // Bind vPosition to attribute 0

        GLES30.glBindAttribLocation(programObject, 0, "vPosition");



        // Link the program

        GLES30.glLinkProgram(programObject);



        // Check the link status

        GLES30.glGetProgramiv(programObject, GLES30.GL_LINK_STATUS, linked, 0);



        if (linked[0] == 0) {

            Log.e(TAG, "Error linking program:");

            Log.e(TAG, GLES30.glGetProgramInfoLog(programObject));

            GLES30.glDeleteProgram(programObject);

            return;

        }



        // Store the program object

        mProgramObject = programObject;



        //now everything is setup and ready to draw.

    }



    public void draw(float[] mvpMatrix) {



        // Use the program object

        GLES30.glUseProgram(mProgramObject);



        // get handle to shape's transformation matrix

        mMVPMatrixHandle = GLES30.glGetUniformLocation(mProgramObject, "uMVPMatrix");

        myRenderer.checkGlError("glGetUniformLocation");



        // get handle to fragment shader's vColor member

        mColorHandle = GLES30.glGetUniformLocation(mProgramObject, "vColor");





        // Apply the projection and view transformation

        GLES30.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

        myRenderer.checkGlError("glUniformMatrix4fv");



        int VERTEX_POS_INDX = 0;

        mVertices.position(VERTEX_POS_INDX);  //just in case.  We did it already though.



        //add all the points to the space, so they can be correct by the transformations.

        //would need to do this even if there were no transformations actually.

        GLES30.glVertexAttribPointer(VERTEX_POS_INDX, 3, GLES30.GL_FLOAT,

                false, 0, mVertices);

        GLES30.glEnableVertexAttribArray(VERTEX_POS_INDX);



        //Now we are ready to draw the cube finally.

        int startPos =0;

        int verticesPerface = 6;



        //draw front face

        GLES30.glUniform4fv(mColorHandle, 1, colorblue, 0);

        GLES30.glDrawArrays(GLES30.GL_TRIANGLES,startPos,verticesPerface);

        startPos += verticesPerface;



        //draw back face

        GLES30.glUniform4fv(mColorHandle, 1, colorcyan, 0);

        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, startPos, verticesPerface);

        startPos += verticesPerface;



        //draw left face

        GLES30.glUniform4fv(mColorHandle, 1, colorred, 0);

        GLES30.glDrawArrays(GLES30.GL_TRIANGLES,startPos,verticesPerface);

        startPos += verticesPerface;



        //draw right face

        GLES30.glUniform4fv(mColorHandle, 1, colorgray, 0);

        GLES30.glDrawArrays(GLES30.GL_TRIANGLES,startPos,verticesPerface);

        startPos += verticesPerface;



        //draw top face

        GLES30.glUniform4fv(mColorHandle, 1, colorgreen, 0);

        GLES30.glDrawArrays(GLES30.GL_TRIANGLES,startPos,verticesPerface);

        startPos += verticesPerface;



        //draw bottom face

        GLES30.glUniform4fv(mColorHandle, 1, coloryellow, 0);

        GLES30.glDrawArrays(GLES30.GL_TRIANGLES,startPos,verticesPerface);

        //last face, so no need to increment.



    }

}

 

 

 

 

myColor.java

 

package com.example.opengltest;



import android.graphics.Color;



public class myColor {



    static float[] red() {

        return new float[]{

                Color.red(Color.RED) / 255f,

                Color.green(Color.RED) / 255f,

                Color.blue(Color.RED) / 255f,

                1.0f

        };

    }



    static float[] green() {

        return new float[]{

                Color.red(Color.GREEN) / 255f,

                Color.green(Color.GREEN) / 255f,

                Color.blue(Color.GREEN) / 255f,

                1.0f

        };

    }



    static float[] blue() {

        return new float[]{

                Color.red(Color.BLUE) / 255f,

                Color.green(Color.BLUE) / 255f,

                Color.blue(Color.BLUE) / 255f,

                1.0f

        };

    }



    static float[] yellow() {

        return new float[]{

                Color.red(Color.YELLOW) / 255f,

                Color.green(Color.YELLOW) / 255f,

                Color.blue(Color.YELLOW) / 255f,

                1.0f

        };

    }



    static float[] cyan() {

        return new float[]{

                Color.red(Color.CYAN) / 255f,

                Color.green(Color.CYAN) / 255f,

                Color.blue(Color.CYAN) / 255f,

                1.0f

        };

    }



    static float[] gray() {

        return new float[]{

                Color.red(Color.GRAY) / 255f,

                Color.green(Color.GRAY) / 255f,

                Color.blue(Color.GRAY) / 255f,

                1.0f

        };

    }

}

 

 

MainActivity.java

 

package com.example.opengltest;



import androidx.appcompat.app.AppCompatActivity;



import android.app.ActivityManager;

import android.content.Context;

import android.content.pm.ConfigurationInfo;

import android.os.Bundle;

import android.util.Log;

import android.view.View;



public class MainActivity extends AppCompatActivity {



    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

//        setContentView(R.layout.activity_main);



        if (detectOpenGLES30()) {

            //so we know it a opengl 3.0 and use our extended GLsurfaceview.

            setContentView(new myGlSurfaceView(this));

        } else {

            // This is where you could create an OpenGL ES 2.0 and/or 1.x compatible

            // renderer if you wanted to support both ES 1 and ES 2.

            Log.e("openglcube", "OpenGL ES 3.0 not supported on device.  Exiting...");

            finish();



        }

    }



    private boolean detectOpenGLES30() {

        ActivityManager am =

                (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

        ConfigurationInfo info = am.getDeviceConfigurationInfo();

        return (info.reqGlEsVersion >= 0x30000);

    }



    @Override

    public void onWindowFocusChanged(boolean hasFocus) {

        super.onWindowFocusChanged(hasFocus);



        if (hasFocus) {

            getWindow().getDecorView().setSystemUiVisibility(

                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE

                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION

                            | View.SYSTEM_UI_FLAG_FULLSCREEN

                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

        }

    }

}

 

 - copy coding -


1···3456789···119

+ Recent posts