안녕하세요.. 원인을 몰라서 도움 부탁드립니다.
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();
}