게시판 즐겨찾기
편집
드래그 앤 드롭으로
즐겨찾기 아이콘 위치 수정이 가능합니다.
openGL 고수님들 도움좀...
게시물ID : programmer_4404짧은주소 복사하기
작성자 : Lazer
추천 : 0
조회수 : 927회
댓글수 : 1개
등록시간 : 2014/07/08 00:14:12
안녕하세요.. 원인을 몰라서 도움 부탁드립니다.

subroutine uniform을 설정했는데 반영이 되질 않네요.. 뭘 잘못한걸까요? ㅠㅠ


#include <GL/glew.h>
#include <GL/freeglut.h>
#include <glm/glm.hpp>

#include <iostream>

void init();
void display();

void main(int argc, char* argv[])
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA);
  glutInitWindowSize(512, 512);
  glutInitContextVersion(4, 3);
  glutInitContextProfile(GLUT_CORE_PROFILE);
  glutCreateWindow(argv[0]);

  if (glewInit())
  {
    std::cerr << "Unable to initialize GLEW ... exiting" << std::endl;
    exit(EXIT_FAILURE);
  }

  init();

  glutDisplayFunc(display);

  glutMainLoop();
}

enum VAO_IDs { Triangle, NumVAOs };
enum Buffer_IDs { ArrayBuffer, NumBuffers };
enum Attrib_IDs { vPosition = 0 };

const GLuint NumVertices = 6;

GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];

void init()
{
  glGenVertexArrays(NumVAOs, VAOs);
  glBindVertexArray(VAOs[Triangle]);

  GLfloat vertices[NumVertices][2] = {
    { -0.90f, -0.90f },
    { 0.85f, -0.90f },
    { -0.90f, 0.85f },
    { 0.90f, -0.85f },
    { 0.90f, 0.90f },
    { -0.85f, 0.90f }
  };

  glGenBuffers(NumBuffers, Buffers);
  glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  const GLchar* vSrc = {
    "#version 430 core                       \n"
    "                                        \n"
    "layout(location = 0) in vec4 vPosition; \n"
    "                                        \n"
    "void main()                             \n"
    "{                                       \n"
    "  gl_Position = vPosition;              \n"
    "}                                       \n"
  };

  GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(vShader, 1, &vSrc, NULL);
  glCompileShader(vShader);

  GLint vCompiled = 0;
  glGetShaderiv(vShader, GL_COMPILE_STATUS, &vCompiled);
  if (!vCompiled)
  {
    GLint length = 0;
    glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &length);

    GLchar* log = new GLchar[length];
    glGetShaderInfoLog(vShader, length, NULL, log);
    std::cerr << log << std::endl;
    delete[] log;
  }

  const GLchar* fSrc = {
    "#version 430 core                          \n"
    "                                           \n"
    "subroutine vec4 ColorFunc();               \n"
    "subroutine (ColorFunc) vec4 Red()          \n"
    "{                                          \n"
    "  return vec4(1.0, 0.0, 0.0, 1.0);         \n"
    "}                                          \n"
    "subroutine (ColorFunc) vec4 Blue()         \n"
    "{                                          \n"
    "  return vec4(0.0, 0.0, 1.0, 1.0);         \n"
    "}                                          \n"
    "subroutine (ColorFunc) vec4 Green()        \n"
    "{                                          \n"
    "  return vec4(0.0, 1.0, 0.0, 1.0);         \n"
    "}                                          \n"
    "                                           \n"
    "subroutine uniform ColorFunc colorSelector;\n"
    "void main()                                \n"
    "{                                          \n"
    "  gl_FragColor = colorSelector();          \n"
    "}                                          \n"
  };

  GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fShader, 1, &fSrc, NULL);
  glCompileShader(fShader);

  GLint fCompiled = 0;
  glGetShaderiv(fShader, GL_COMPILE_STATUS, &fCompiled);
  if (!fCompiled)
  {
    GLint length = 0;
    glGetShaderiv(fShader, GL_INFO_LOG_LENGTH, &length);

    GLchar* log = new GLchar[length];
    glGetShaderInfoLog(fShader, length, NULL, log);
    std::cerr << log << std::endl;
    delete[] log;
  }

  if (vCompiled && fCompiled)
  {
    GLuint program = glCreateProgram();
    glAttachShader(program, vShader);
    glAttachShader(program, fShader);
    glLinkProgram(program);

    GLint linked = 0;
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if (!linked)
    {
      GLint length = 0;
      glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);

      GLchar* log = new GLchar[length];
      glGetProgramInfoLog(program, length, NULL, log);
      std::cerr << log << std::endl;
      delete[] log;
    }
    else
    {
      glUseProgram(program);
      glDeleteShader(vShader);
      glDeleteShader(fShader);

      GLuint colorSelectorLoc = glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "colorSelector");
      if (colorSelectorLoc < 0)
      {
        std::cerr << "Invalid subroutine uniform location" << std::endl;
      }

      GLuint redIdx = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "Red");
      if (redIdx == GL_INVALID_INDEX)
      {
        std::cerr << "Invalid subroutine index" << std::endl;
      }

      GLuint greenIdx = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "Green");
      if (greenIdx == GL_INVALID_INDEX)
      {
        std::cerr << "Invalid subroutine index" << std::endl;
      }

      GLuint blueIdx = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "Blue");
      if (blueIdx == GL_INVALID_INDEX)
      {
        std::cerr << "Invalid subroutine index" << std::endl;
      }

      GLsizei n;
      glGetIntegerv(GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS, &n);
      GLuint *indices = new GLuint[n];
      indices[colorSelectorLoc] = greenIdx;

      glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, n, indices);

      delete[] indices;

    }
  }
}

void display()
{
  glClear(GL_COLOR_BUFFER_BIT);

  glBindBuffer(GL_ARRAY_BUFFER, Buffers[Triangle]);

  glEnableVertexAttribArray(vPosition);
  glVertexAttribPointer(vPosition, 2, GL_FLOAT, false, 0, NULL);

  glDrawArrays(GL_TRIANGLES, 0, NumVertices);

  glFlush();
}
전체 추천리스트 보기
새로운 댓글이 없습니다.
새로운 댓글 확인하기
글쓰기
◀뒤로가기
PC버전
맨위로▲
공지 운영 자료창고 청소년보호