在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()時,着色器對象將被刪除(在標記的行中),並且之後無法重新附加。
有沒有一種簡單的方法來解決這個問題(在高效的意義上容易)?
爲了完整起見,GLStatics
類:
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
是的,附加就夠了。我在答案中增加了一些更詳細的說明。增加的開銷應該是最小的。這不是你想要在一個緊密的循環中做的事情,但是你要用相同的代碼連接一個着色器程序,這可能是數量級更昂貴的。 –