问题描述
这是我的问题的重新表述:How to access files form the Renderer class Opengles (android,java),但没有人回答,所以我决定换一种方式提问。
我正在为 android 构建一个 Opengl es 应用程序,我想访问一些本地文件。我的主要游戏循环位于 Renderer 类中,它是 GLSurfaceView.Renderer 的实现,将用于设置 MainActivity 中的视图。我知道获取某种本地文件*的唯一方法是执行 Activity.getAssets().open("file.something");但后来我需要 MainActivity。问题是,如果我正确理解我的研究,Renderer 类会自动在与 MainActivity 不同的线程上运行,从而导致 MainActivity.getAssets().open();什么都不回。如果那是解决方案,请帮助我找到解决方法或仅使用线程。
*我知道它们不被称为本地文件,但它们仍然用于处理您无法使用绝对路径 qnd 访问的文件,这正是我想要的。
编辑 #1:
import android.app.Activity;
import android.content.Context;
import android.opengl.GLES20;
import android.widget.Toast;
import com.GyooStudios.glu.MainActivity;
import com.GyooStudios.glu.ShaderProgram;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
public abstract class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
public boolean hasFoundFile = true;
public boolean isCompiled = true;
public boolean canReadFile = true;
public String exceptionError = "null";
public ShaderProgram (MainActivity main,String vertexFile,String fragmentFile){
vertexShaderID = loadShader(main,vertexFile,GLES20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader(main,fragmentFile,GLES20.GL_FRAGMENT_SHADER);
programID = GLES20.glCreateProgram();
GLES20.glAttachShader(programID,vertexShaderID);
GLES20.glAttachShader(programID,fragmentShaderID);
GLES20.glLinkProgram(programID);
GLES20.glValidateProgram(programID);
}
public void start(){
GLES20.gluseProgram(programID);
}
public void stop(){
GLES20.gluseProgram(0);
}
protected abstract void bindAttributes();
protected void bindAttribute(int attribute,String variableName){
GLES20.glBindAttribLocation(programID,attribute,variableName);
}
private int loadShader(MainActivity main,String fileName,int type){
int shaderID = 0;
try{
InputStream file = main.getAssets().open(fileName);
Scanner scan = new Scanner(file);
String code = new String();
while(scan.hasNext()){
code = new String(code + scan.nextLine() + "/n");
}
shaderID = GLES20.glCreateShader(type);
GLES20.glShaderSource(shaderID,code);
GLES20.glCompileShader(shaderID);
int[] compileStatus = new int[1];
GLES20.glGetShaderiv(shaderID,GLES20.GL_COMPILE_STATUS,compileStatus,0);
if(compileStatus[0] == 0){
Toast.makeText(main.getApplicationContext(),GLES20.glGetShaderInfoLog(shaderID),Toast.LENGTH_LONG);
GLES20.glDeleteShader(shaderID);
isCompiled = false;
}
}catch(FileNotFoundException e){
hasFoundFile = false;
}catch(IOException e){
canReadFile = false;
}catch(Exception e){
isCompiled = false;
exceptionError = "something went wrong";
exceptionError = e.toString();
}
return shaderID;
}
}
ShaderProgram 在这个类中实现:
import com.GyooStudios.glu.MainActivity;
public class StaticShader extends ShaderProgram{
private static final String VERTEX_FILE = "quad.vertex";
private static final String FRAGMENT_FILE = "quad.fragment";
public StaticShader(MainActivity main){
super(main,VERTEX_FILE,FRAGMENT_FILE);
//bindAttributes();
}
@Override
protected void bindAttributes(){
super.bindAttribute(0,"position");
}
}
StaticShader 用于在 Renederer 中创建的另一个类的构造函数中。这里正在使用渲染器,在 MainActivity 中:
import android.Manifest;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.widget.Toast;
import com.GyooStudios.glu.StaticShader;
import com.GyooStudios.glu.renderer;
import java.io.InputStream;
import java.util.Scanner;
public class MainActivity extends Activity {
private renderer surface;
private GLSurfaceView surfaceView;
private int STORAGE_PERMISSION_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
//Keep in mind that renderer implements GLSurfaceView.Renderer
//And yes,renderer class is with a lower case r,it's my mistake.
super.onCreate(savedInstanceState);
surfaceView = new GLSurfaceView(this);
surfaceView.setEGLContextClientVersion(2);
surface = new renderer(this);
surfaceView.setRenderer(surface);
setContentView(surfaceView);
}
protected void onPause(){
super.onPause();
surfaceView.onPause();
}
protected void onResume(){
super.onResume();
surfaceView.onResume();
}
}
编辑#2: 我尝试只传递 Activity.getAssets(); 返回的 AssetManager;还有上下文。 AssetManager 允许应用程序运行,但它给了我一个异常,我无法确定是哪个。当我厌倦了使用 Toast.makeText(passedOnContext,exception.toString(),Toast.LENGTH_LONG);它使应用程序崩溃。 (是的,我使用 Toasts 来获取调试消息,这是我的 IDE 的限制,它没有在应用程序开发中提供终端)
解决方法
事实证明这根本不是问题!请参阅此处了解新问题:GLES20.glShaderSource does nothing