OpenGL- 파이프 라인 이전 : 렌더링 할 객체에 특정 버텍스 쉐이더를 사용하고 싶습니다. 그래서 나는이 생각 : OpenGL : 쉐이더 용 프록시 사용자 만들기
int currProgram = glGetInteger(GL_CURRENT_PROGRAM);
int currVertexShader = 0;
if (currProgram == 0) {
glUseProgram(programName);
} else {
currVertexShader = GLStatics.getShader(currProgram,
GL_VERTEX_SHADER);
if (currVertexShader != 0) {
glDetachShader(currProgram, currVertexShader); // <-- problem here
}
glAttachShader(currProgram, shaderName);
GLStatics.linkProgramSafe(currProgram);
}
// Actual render code
if (currProgram != 0) {
glDetachShader(currProgram, shaderName); // Can safely detach
if (currVertexShader != 0) {
glAttachShader(currProgram, currVertexShader);
}
GLStatics.linkProgramSafe(currProgram);
}
glUseProgram(currProgram);
그래서 나는 정적 GLObjects에 있습니다 : 내가 사용하려는 컴파일 된 버텍스 쉐이더입니다
shaderName
및
programName
을 다른 프로그램이 beforehands을 구속하지 않을 경우 나는 결합하는 프로그램이다.
정말 문제가있을 때 정상적으로 실행될 것이라고 생각했습니다. 코드를 실행하기 전에 현재 바인딩 된 프로그램의 버텍스 쉐이더에서 glDeleteShader()가 호출되면 쉐이더 객체가 삭제되고 (나중에 표시된 라인에서) 다시 연결할 수 없습니다.
효율적인 방법으로이 문제를 쉽게 해결할 수 있습니까?
public class GLStatics {
public static ByteBuffer createDirectBuffer(int size) {
return ByteBuffer.allocateDirect(size);
}
public static int createProgramSafe() {
int programName = glCreateProgram();
if (programName == 0) {
throw new IllegalStateException(
"GL Error: Created Program is 0. Can't proceed.");
}
return programName;
}
public static int getShader(int program, int searchedType) {
int shaderCount = glGetProgrami(program, GL_ATTACHED_SHADERS);
IntBuffer attachedShaders = createDirectBuffer(shaderCount * 4)
.asIntBuffer();
IntBuffer count = createDirectBuffer(4).asIntBuffer();
glGetAttachedShaders(program, count, attachedShaders);
assert count.get() == shaderCount;
for (int i = 0; i < shaderCount; ++i) {
int shaderCandidate = attachedShaders.get();
if (searchedType == glGetShaderi(shaderCandidate, GL_SHADER_TYPE)) {
return shaderCandidate;
}
}
return 0;
}
public static void linkProgramSafe(int program) {
glLinkProgram(program);
if (glGetProgrami(program, GL_LINK_STATUS) == GL_FALSE) {
int errorLength = glGetProgrami(program, GL_INFO_LOG_LENGTH);
String error = glGetProgramInfoLog(program, errorLength);
throw new IllegalStateException(error);
}
}
}
쉐이더를 연결하는 것으로 충분합니다. 링크하지 않아도됩니까? 이것이없는 것보다 이것이 얼마나 더 느린 지 아십니까? – WorldSEnder
예, 부착만으로 충분합니다. 나는 그 대답에 spec quote를 더 자세히 설명했다. 추가되는 오버 헤드는 최소화되어야합니다. 이것은 단호한 루프에서하고 싶지는 않지만, 동일한 코드에서 쉐이더 프로그램을 링크하고 있습니다. 아마 이것은 더 큰 규모의 명령 일 것입니다. –