gpt4 book ai didi

java - OpenGL : Create proxy user for shader

转载 作者:行者123 更新时间:2023-12-01 12:43:31 24 4
gpt4 key购买 nike

在 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这是我在没有绑定(bind)其他程序的情况下绑定(bind)的程序事先。

我认为当确实出现问题时这会运行良好。当在执行代码之前在当前绑定(bind)程序的顶点着色器上调用 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);
}

}
}

最佳答案

您可以拥有另一个着色器程序,仅用于在着色器与您正在操作的着色器分离时“停放”着色器。这将保留一个引用,防止它被永久删除。

仅显示代码的扩展部分,dummyProgram 是您专门为此目的创建的程序:

if (currVertexShader != 0) {
glAttachShader(dummyProgram, currVertexShader);
glDetachShader(currProgram, currVertexShader);
}
...
if (currVertexShader != 0) {
glAttachShader(currProgram, currVertexShader);
glDetachShader(dummyProgram, currVertexShader);
}

这将基于规范中的以下定义(OpenGL 3.3 规范中的附录 D.1.2)工作:

When a shader object or program object is deleted, it is flagged for deletion, but its name remains valid until the underlying object can be deleted because it is no longer in use. A shader object is in use while it is attached to any program object.

因此,只需将着色器附加到任何程序就足以将其视为“正在使用”,并防止其被删除。如果您对有关程序/着色器生命周期的微妙方面的更多详细信息感兴趣,这是我在之前的问题中写的答案:glDeleteShader - is the order irrelevant? .

关于java - OpenGL : Create proxy user for shader,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24876978/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com