본문 바로가기
3D웹 프로그래밍/opengl

opengl 삼각형을 이용하여 타원그리기

by 디찌s 2020. 11. 19.
728x90
반응형

 

 

1.버텍스 쉐이더에 데이터 전달하기

버텍스 쉐이더는 OpenGL 파이프라인의 첫번째 프로그래밍 가능한 스테이지이다. 또한 유일한 필수 스테이지기도하다.

 

하지만 버텍스 쉐이더가 실행되기전에 버텍스 페칭 또는 버텍스 풀링이라는 고정 함수 스테이지가 실행된다.

 

버텍스 쉐이더에서 데이터를 가져오거나 내보내자는 작업은 in,out저장 지시어로 전역변수를 선언하는 방식으로 수행한다.

 

Opengl파이프라인 시작 시 in 키워드를 사용하여 버텍스 쉐이더에 입력을 제공한다.

 

in 저장 지시어를 사용하면, 해당 변수는 버텍스 쉐이더의 입력으로 설정되는데, 이는 고정 함수 버텍스 페치 스테이지에 의해 그 내용이 자동적으로 채워진다. 이 변수를 버텍스 속성이라고 부른다.

 

#version 430 core

layout (locatyion=0) in vec4 offset;

void main(void)
{
const vec4 vertices[3] = vec4[3](vec4(0.25,-0.25,0.5,1.0),vec4(-0.25,-0.25,0.5,1.0),vec4(0.25,0.25,0.5,1.0));

gl_Poistion = vertices[gl_VertexID]+offset;
}

 

위 코드는 버텍스 쉐이더에 입력으로 offset을 추가했다. 파이프라인의 첫번째 쉐이더에 대한 입력이기에 버텍스 페치 스테이지에서 자동적으로 내용치 채워진다. 이스테이지는 glVertexAttrib*()라는 버텍스 속성 함수의 많은 변종 중 하나를 사용해 그 변수의 내용을 채울수있다.

void glVertexAttrib4fv(GLuint index,const GLfloat * v);

 

위 함수의 index 인자는 속성을 참조하기 위한값이고, v는 속성에 넣을 새로운 데이터를 가리키는 포인터다.

offset 속성 선언중 layout(location=0)은 레이아웃 지시어라 부르며 버텍스 속성의 위치를 가르킨다. 이 위치값이 바로 해당 속성을 가리키는 index에 설정값이다.

 

예제 코드는 아래와 같다.

  virtual void render(double currentTime)
    {
        const GLfloat color[] ={ 0.0f , 0.2f, 0.0f,1.0f};
      
        glClearBufferfv(GL_COLOR, 0, color);

        //렌더링을 위해 생성했던 프로그램 객체를 사용한다.
        glUseProgram(rendering_program);
		
        GLfloat attrib[] = { (float)sin(currentTime)*0.5f,(float)cos(currentTime)*0.6f,0.0f,1.0f};
        //입력 속성 location layout 0의 값을 갱신한다.
        glVertexAttrib4fv(0,attrib);
        //삼각형을 하나 그린다.
        glDrawArrays(GL_TRIANGLES, 0, 3);
     
    }

 

 

 

 

 

 

아래는 전체코드이다

 

/*
 * Copyright ?2012-2013 Graham Sellers
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <sb6.h>
#include <vmath.h>
class simpleclear_app : public sb6::application
{
public:
    virtual void startup() {

        rendering_program = compile_shaders();
        glGenVertexArrays(1, &vertex_array_object);
        glBindVertexArray(vertex_array_object);
    }

    void shutdown() {
        glDeleteVertexArrays(1, &vertex_array_object);
        glDeleteProgram(rendering_program);
        glDeleteVertexArrays(1, &vertex_array_object);
    }


private:
    GLuint rendering_program;
    GLuint vertex_array_object;


    void init()
    {
        static const char title[] = "Simple Clear";

        sb6::application::init();

        memcpy(info.title, title, sizeof(title));
    }

    virtual void render(double currentTime)
    {
        const GLfloat color[] ={ 0.0f , 0.2f, 0.0f,1.0f};
      
        glClearBufferfv(GL_COLOR, 0, color);

        //렌더링을 위해 생성했던 프로그램 객체를 사용한다.
        glUseProgram(rendering_program);

        GLfloat attrib[] = { (float)sin(currentTime) * 0.5f,(float)cos(currentTime) * 0.6f,0.0f,0.0f };
        //입력 속성의 0의 값을 갱신한다.
        glVertexAttrib4fv(0, attrib);

        //삼각형을 하나 그린다.
        glDrawArrays(GL_TRIANGLES, 0, 3);
     
    }



    GLuint compile_shaders(void) {
        GLuint vertex_shader;
        GLuint fragment_shader;
        GLuint program;
        
        //vertex shader 소스
        static const char * vertex_shader_source[] = {
            "#version 420 core                                                 \n"
            "layout (location =0)in vec4 offset;                               \n"
            "void main(void)                                                   \n"
            "{                                                                 \n"
            "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  \n"
            "                                   vec4(-0.25, -0.25, 0.5, 1.0),  \n"
            "                                   vec4( 0.25,  0.25, 0.5, 1.0)); \n"
            "                                                                  \n"
            "    gl_Position = vertices[gl_VertexID] + offset;                          \n"
            "}  \n"      
        };
        //fragment shader 소스
        static const char * fragment_shader_source[] = {
                   "#version 420 core                                                 \n"
            "                                                                  \n"
            "out vec4 color;                                                   \n"
            "                                                                  \n"
            "void main(void)                                                   \n"
            "{                                                                 \n"
            "    color = vec4(1.0, 1.0, 1.0, 1.0);                             \n"
            "}                                                                 \n"
        };
        //버텍스 쉐이더를 생성하고 컴파일한다.
        vertex_shader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
        glCompileShader(vertex_shader);

        //프래그먼트 쉐이더를 생성하고 컴파일하낟.
        fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragment_shader, 1, fragment_shader_source, NULL);
        glCompileShader(fragment_shader);

        //프로그램을 생성하고 쉐이더를 어태치(attach,부착)시키고 링크한다.
        program = glCreateProgram();
        glAttachShader(program, vertex_shader);
        glAttachShader(program, fragment_shader);
        glLinkProgram(program);

        glGenVertexArrays(1, &vertex_array_object);
        glBindVertexArray(vertex_array_object);

        //이제 프로그램이 쉐이더를 소유하므로 쉐이더를 삭제한다
        glDeleteShader(vertex_shader);
        glDeleteShader(fragment_shader);

        return program;


    }
};

DECLARE_MAIN(simpleclear_app)

728x90
반응형

댓글