MFC 웹사이트 열기

300x250

 

 

아래 site_name에 주소만 변경해서 코드를 넣으면 바로 웹사이트가 뜹니다.

브라우저는 윈도우에서 기본으로 설정된 브라우저로 실행되니 참고해주세요.

HINSTANCE hResult;
hResult = NULL;
CString site_name;
site_name = "https://www.naver.com";
hResult = ShellExecute(NULL, _T("open"), site_name, NULL, NULL, SW_SHOW);

 

2023년 어느겨울에..

 

 

 

 

300x250

댓글()

MFC 중복 실행 막기

300x250

 

 

 

중복 실행 막는 방법은 대략 아래와 같이 3가지 방법이 있다고 합니다.

 

1. 프로세스 목록에서 프로그램 이름을 확인해서 막는 방법

2. Mutex를 사용한 방법

3. 공유메모리를 사용한 방법

 

저는 Mutex를 사용한 방법이 좋다고 해서 자주 사용하는데 이 방법으로 중복 실행을 막는 방법에 대해서 설명 할께요.

간단합니다.

 

MFC 프로그램 코드를 봅시다.

프로젝트 이름이 Test 라는 프로젝트로 만들었다면, CTestApp::InitInstance() 라는 함수가 있어요.

 

 

아래 예시 코드를 보면

기존 함수 제일 위에

7줄의 return 코드를 넣어주세요. 바로 이해가 될것이라고 생각 됩니다.

TestApp은 체크할 프로그램 이름과 일치할 필요는 없어요.  다른 프로그램 이름과 안겹치게 유니크 하게 작성해 주세요

BOOL CTestApp::InitInstance()
{
	// 추가해야 하는 코드
	HANDLE hMutex = NULL;
	hMutex = CreateMutex(NULL, TRUE, _T("TestApp"));
	if (GetLastError() == ERROR_ALREADY_EXISTS)
	{
		AfxMessageBox(_T("프로그램이 이미 실행 중입니다."));
		return FALSE;
	}


	// 밑에는 기존 코드
    //
    //
    //
    //
       
    return FALSE;
}

이상입니다.

 

 

좋은 프로그램 만드세요.

2023년 어느 겨울 작성.

 

 

 

300x250

댓글()

OpenGL 강좌3 - EBO + VAO + VBO

300x250

프로그램 및 코드 다운로드

2. Example_OpenGL_EBO_VAO_VBO.zip
7.74MB

주요 코드는 아래와 같습니다.

#pragma once
#include "GlRender.h"

class RenderEBO_VAO_VBO : public GlRender
{
public:
    RenderEBO_VAO_VBO();
    ~RenderEBO_VAO_VBO();
    
private:
    void GlInit() override;
    void GlDraw() override;

    float vertices[4] = {
        0,10,
        200, 110
    };
    float vertices2[4] = {
        0,20,
        200, 120
    };


    GLuint VAO;
    GLuint VAO2;

    GLuint VBO;
    GLuint VBO2;


    GLuint EBO;
    GLuint VAO3;
    GLuint VBO3;


    float vertices3[12] = {
        50.5f,  50.5f, 0.0f,  // 우측 상단
        50.5f, -50.5f, 0.0f,  // 우측 하단
        -50.5f, -50.5f, 0.0f,  // 좌측 하단
        -50.5f,  50.5f, 0.0f   // 좌측 상단
    };
    unsigned int indices[6] = {  // 0부터 시작한다는 것을 명심하세요!
        0, 1, 3,   // 첫 번째 삼각형
        1, 2, 3    // 두 번째 삼각형
    };

};

 

아래 코드에서는 VAO + VBO를 2개 만들어서 2개의 라인을 그립니다.

그리고 EBO + VAO + VBO를 사용하여 정점 좌표를 인덱싱하여 순서를 변경 합니다.

위에 헤더의 indices를 주목해 주세요.

0~4 사이의 순서를 변경하면 LINE_STRIP 그리는 위치가 바뀌게 됩니다.

void RenderEBO_VAO_VBO::GlInit()
{    
    /***************************************************************************************
    * VAO + VBO 1번째
    **************************************************************************************/
    // VAO 생성 및 바인딩
    glGenVertexArrays(1, &VAO);  // 1.할당 (앞에 인자는 1개 의미)
    glBindVertexArray(VAO);

    // VBO
    // 1. Gen(할당) -> 2. Bind(바인딩) -> 3. Data(입력) -> 4. Link 순서로 사용
    glGenBuffers(1, &VBO);  // 1.할당 (앞에 인자는 1개 의미)
    glBindBuffer(GL_ARRAY_BUFFER, VBO); // 2. GL_ARRAY_BUFFER 형식 바인딩 (이 버퍼 말고도 종류가 많음)
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW); // 3.데이터 복사 및 크기 설정
    ///GL_STATIC_DRAW: 데이터가 거의 변하지 않습니다.
    ///GL_DYNAMIC_DRAW: 데이터가 자주 변경됩니다.
    ///GL_STREAM_DRAW: 데이터가 그려질때마다 변경됩니다.

    // 4. Link Vertex Attribute
    int location = 0;
    glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GL_FLOAT), (void*)0);
    glEnableVertexAttribArray(location);



    /***************************************************************************************
    * VAO + VBO 2번째
    **************************************************************************************/
    // VAO 생성 및 바인딩
    glGenVertexArrays(1, &VAO2); // 1.할당 (앞에 인자는 1개 의미)
    glBindVertexArray(VAO2); // VAO를 OpenGL context에 연결(bind)

    // VBO
    // 1. Gen(할당) -> 2. Bind(바인딩) -> 3. Data(입력) -> 4. Link 순서로 사용
    glGenBuffers(1, &VBO2);   // 1.할당 (앞에 인자는 1개 의미)
    glBindBuffer(GL_ARRAY_BUFFER, VBO2); // 2. GL_ARRAY_BUFFER 형식 바인딩 (이 버퍼 말고도 종류가 많음)
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STREAM_DRAW); // 3.데이터 복사 및 크기 설정
    ///GL_STATIC_DRAW: 데이터가 거의 변하지 않습니다.
    ///GL_DYNAMIC_DRAW: 데이터가 자주 변경됩니다.
    ///GL_STREAM_DRAW: 데이터가 그려질때마다 변경됩니다.

    // 4. Link Vertex Attribute
    glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GL_FLOAT), (void*)0);
    glEnableVertexAttribArray(location);



    /***************************************************************************************
     * EVO + VAO + VBO
     **************************************************************************************/
    // VAO 생성 및 바인딩
    glGenVertexArrays(1, &VAO3);  // 1.할당 (앞에 인자는 1개 의미)
    glBindVertexArray(VAO3);  // VAO를 OpenGL context에 연결(bind)

    // VBO
    // 1. Gen(할당) -> 2. Bind(바인딩) -> 3. Data(입력) -> 4. Link 순서로 사용
    glGenBuffers(1, &VBO3);   // 1.할당 (앞에 인자는 1개 의미)
    glBindBuffer(GL_ARRAY_BUFFER, VBO3);  // 2. GL_ARRAY_BUFFER 형식 바인딩 (이 버퍼 말고도 종류가 많음)
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices3), vertices3, GL_STREAM_DRAW); // 3.데이터 복사 및 크기 설정

    // OpenGL이 사용하기 위해 인덱스 리스트를 element 버퍼에 복사
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STREAM_DRAW);
    ///GL_STATIC_DRAW: 데이터가 거의 변하지 않습니다.
    ///GL_DYNAMIC_DRAW: 데이터가 자주 변경됩니다.
    ///GL_STREAM_DRAW: 데이터가 그려질때마다 변경됩니다.

    // Link Vertex Attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
}

 

void RenderEBO_VAO_VBO::GlDraw()
{
    glViewport(0, 0, gl_window_width, gl_window_height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrtho((double)-gl_window_width / 2, (double)gl_window_width / 2,
        (double)-gl_window_height / 2, (double)gl_window_height / 2,
        1, -1);
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0, 0, 0, 0);


    glBindVertexArray(VAO);	// 한 줄로 끝!
    glColor4f(0, 1, 0, 1);
    glDrawArrays(GL_LINES, 0, 2);


    glBindVertexArray(VAO2);	// 한 줄로 끝!
    glColor4f(0, 0, 1, 1);
    glDrawArrays(GL_LINES, 0, 2);


    glBindVertexArray(VAO3);	// 한 줄로 끝!
    glColor4f(0, 0, 1, 1);
    glDrawElements(GL_LINE_STRIP, 6, GL_UNSIGNED_INT, 0); // EBO 사용 시 glDrawElements로 출력
}
300x250

댓글()

OpenGL 강좌2 - VBO (VertexBufferObject)

300x250

프로그램 및 코드 다운로드

1. Example_OpenGL_VBO.zip
7.73MB

 

주요 코드는 아래와 같습니다.

 

Header

class RenderVBO : public GlRender
{
public:
    RenderVBO();
    ~RenderVBO();

    GLuint VBO;

    float vertices[8] = {
        0,10,
        200, 110,
        -0,-10,
        -200,-110
    };


private:
    void GlInit() override;
    void GlDraw() override;
};

 

 

CPP

void RenderVBO::GlInit()
{
    // 1. Gen(할당) -> 2. Bind(바인딩) -> 3. Data(입력) -> 4. Link 순서로 사용

    glGenBuffers(1, &VBO); // 1.할당
    glBindBuffer(GL_ARRAY_BUFFER, VBO); // 2. GL_ARRAY_BUFFER 형식 바인딩 (이 버퍼 말고도 종류가 많음)
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) /* Byte 크기*/ , &vertices[0], GL_STREAM_DRAW); // 3.데이터 복사 및 크기 설정
    ///GL_STATIC_DRAW: 데이터가 거의 변하지 않습니다.
    ///GL_DYNAMIC_DRAW: 데이터가 자주 변경됩니다.
    ///GL_STREAM_DRAW: 데이터가 그려질때마다 변경됩니다.

    // 4. Link Vertex Attribute
    int location = 0;

    // 파라미터 : location, 크기, 데이터 형태(float 등), Normalize 여부, 한점 BYTE 크기 (0이면 자동 계산), 시작 인덱스
    glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GL_FLOAT), (void*)0);
    glEnableVertexAttribArray(0);

}

VBO를 사용하기 위해서는 아래순서로 사용합니다. 꼭 기억해두세요.

1. Gen(할당) -> 2. Bind(바인딩) -> 3. Data(입력) -> 4. Link 순서로 사용

 

 

void RenderVBO::GlDraw()
{
    glViewport(0, 0, gl_window_width, gl_window_height);
    glLoadIdentity();

    glOrtho((double)-gl_window_width / 2, (double)gl_window_width / 2,
        (double)-gl_window_height / 2, (double)gl_window_height / 2,
        1, -1);
    

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0, 0, 0, 0);


    glColor4f(0, 1, 0, 1);

    // 중요! 단독으로 VBO만 사용시 VBO버퍼에 마지막으로 입력된 데이터가 출력됨
    // 만약 여러 데이터를 입력하려면 VAO를 같이 사용해야 함(다음 예제 참조)
    glDrawArrays(GL_LINES, 0, 2); // glBegin(GL_LINES); 처럼 쓰면됨 GL_POINTS 등등
    
}

glDrawArrays로 버퍼에 저장된 데이터를 출력하였습니다.

 

300x250

댓글()