Java Android/OpenGLES2-创建;着色器';不同线程中的程序

Java Android/OpenGLES2-创建;着色器';不同线程中的程序,java,android,opengl-es,Java,Android,Opengl Es,我是OpenGLES新手,我对着色器程序有问题。 我的设想是: Thread A(works as loop) manages everything but it does not draw on screen Thread B only draws on screen Thread A decides if Thread B will draw in current cycle 我的问题是当线程A为线程B创建着色器程序时,B无法访问属性和统一位置 以下是创建着色器程序的方式: int ver

我是OpenGLES新手,我对着色器程序有问题。 我的设想是:

Thread A(works as loop) manages everything but it does not draw on screen
Thread B only draws on screen
Thread A decides if Thread B will draw in current cycle
我的问题是当线程A为线程B创建着色器程序时,B无法访问属性和统一位置

以下是创建着色器程序的方式:

int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

mProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mProgram, vertexShader);
GLES20.glAttachShader(mProgram, pixelShader);
GLES20.glLinkProgram(mProgram);
这是线程B使用程序的方式:

GLES20.glUseProgram(mProgram);
int positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
GLES20.glEnableVertexAttribArray(positionHandle);

GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
如果mProgram是由线程A创建的,则GLGetAttributeLocation返回-1 GLGetAttributeLocation返回线程B创建mProgram时的有效位置

若线程创建的mProgram和positionHandle硬编码为有效位置,则着色器程序将无法正常工作


我的问题:是否可以在线程A中创建着色器程序以供线程B使用?

我没有阅读您的整个问题;我只看过“你的剧本”。既然你说你是OpenGL/GameDev新手,我就简单地说你的“场景”是错误的。很久以前,我写的第一个游戏也使用了类似的方法,所以我不怪你:)

您应该使用如下工作方式的单个线程:

load everything (textures, shaders, buffers, ...)
while (running)
{
    start timer
    update game (step by one frame, handle user input)
    render game
    show to openglbuffer to the screen (swap buffers)
    stop timer
    manage fps limiting (ie: sleep, using the difference of the timers)
}
clean up

OpenGL出现所有问题的原因是,只有一个线程可以使用OpenGL上下文。

我在GameDev(directX)和多重威胁方面有经验,所以这不是问题所在。我的问题是着色器程序,因为我知道OpenGL作为状态机工作,而且我100%确信当线程A创建着色器程序线程B什么都不做时,我应该能够创建有效的着色器程序。也许,你误解了我的句子,但只有一个固定线程具有上下文。但我认为应该可以手动更改它。DirectX的工作方式与OGL完全不同。DX版本的工作原理各不相同,因此您必须明确地考虑到这一点。在我看来,您正在尝试进行双缓冲,有一种合适的OGL方法可以做到这一点(google It)。不幸的是,多线程程序中OpenGL上下文的行为没有得到很好的指定,并且通常依赖于驱动程序。例如,众所周知,Nvidia的OpenGL驱动程序可以为上下文实例化特定于线程的数据,这意味着任何给定的上下文只能在创建它的线程中使用。其他驱动程序不是这样的(上下文可以在线程之间“传递”)。不过,唯一可移植的方法是确保只有创建OpenGL上下文的线程在使用它。一次只能有一个渲染上下文处于活动状态,并且不能从其他线程使用它。您应该阅读以下内容:然而,我无法找到GLES20的makecurrent替代方案。很可能它不存在。我建议只在主线程中调用OpenGL命令。