![](/img/trans.png)
[英]Nothing is drawn when using gles 2.0\egl\native activity on Android
[英]Android native activity, GLES 3.0 shader compilations fails
我想针对一个个人项目尝试使用Native Activity和GLES 3.0,直到碰到这个障碍:着色器将不会加载和/或编译,我不确定,因为OPENGL的日志不存在。
这是我的两个着色器:
static const char glVertexShader[] =
"#version 300 es\n"
"in vec4 vPosition;\n"
"void main()\n"
"{\n"
" gl_Position = vPosition;\n"
"}\n\0";
static const char glFragmentShader[] =
"#version 300 es\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n\0";
这是我的着色器加载和程序创建功能:
GLuint loadShader(GLenum shaderType, const char* shaderSource)
{
GLuint shader = glCreateShader(shaderType);
if (shader)
{
glShaderSource(shader, 1, &shaderSource, NULL);
glCompileShader(shader);
GLint compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen)
{
char * buf = new char[infoLen];
if (buf)
{
glGetShaderInfoLog(shader, infoLen, NULL, buf);
log.log_error("Could not Compile Shader %d:\n%s\n", shaderType, buf);
delete[] buf;
}
glDeleteShader(shader);
shader = 0;
}
}
}
return shader;
}
GLuint createProgram(const char* vertexSource, const char * fragmentSource)
{
log.log_info("Loading vertex shader");
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
if (!vertexShader)
{
log.log_info("Vertex shader load failure!");
return 0;
}
log.log_info("Loading fragment shader");
GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
if (!fragmentShader)
{
log.log_info("Fragment shader load failure!");
return 0;
}
GLuint program = glCreateProgram();
if (program)
{
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE)
{
GLint bufLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
if (bufLength)
{
char* buf = new char[bufLength];
if (buf)
{
glGetProgramInfoLog(program, bufLength, NULL, buf);
log.log_error("Could not link program:\n%s\n", buf);
delete[] buf;
}
}
glDeleteProgram(program);
program = 0;
}
}
return program;
}
我还将在下面包括我的设置代码和绘图代码:
设置代码:
GLuint simpleTriangleProgram;
GLuint vPosition;
bool setupGraphics(int w, int h)
{
simpleTriangleProgram = createProgram(glVertexShader, glFragmentShader);
if (!simpleTriangleProgram)
{
log.log_error("Could not create program");
return false;
}
vPosition = glGetAttribLocation(simpleTriangleProgram, "vPosition");
glViewport(0, 0, w, h);
return true;
}
绘图代码:
//-------------------------------
const GLfloat triangleVertices[] = {
0.0f, 1.0f,
-1.0f, -1.0f,
1.0f, -1.0f
};
//-------------------------------
/**
* Just the current frame in the display.
*/
static void engine_draw_frame(struct engine* engine) {
if (engine->display == NULL) {
// No display.
return;
}
// Just fill the screen with a color.
glClearColor(((float)engine->state.x) / engine->width, engine->state.angle,
((float)engine->state.y) / engine->height, 1);
glClear(GL_COLOR_BUFFER_BIT);
//---------------------------------------------------
glUseProgram(simpleTriangleProgram);
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, triangleVertices);
glEnableVertexAttribArray(vPosition);
glDrawArrays(GL_TRIANGLES, 0, 3);
//---------------------------------------------------
eglSwapBuffers(engine->display, engine->surface);
}
是的,正确创建了GLES上下文。
但是让我知道是否也应该发布该代码。
这是我的上下文创建代码:
/**
* Initialize an EGL context for the current display.
*/
static int engine_init_display(struct engine* engine) {
// initialize OpenGL ES and EGL
/*
* Here specify the attributes of the desired configuration.
* Below, we select an EGLConfig with at least 8 bits per color
* component compatible with on-screen windows
*/
const EGLint attribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_NONE
};
EGLint w, h, format;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
EGLContext context;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, 0, 0);
/* Here, the application chooses the configuration it desires.
* find the best match if possible, otherwise use the very first one
*/
eglChooseConfig(display, attribs, NULL, 0, &numConfigs);
std::unique_ptr<EGLConfig[]> supportedConfigs(new EGLConfig[numConfigs]);
assert(supportedConfigs);
eglChooseConfig(display, attribs, supportedConfigs.get(), numConfigs, &numConfigs);
assert(numConfigs);
auto i = 0;
for (; i < numConfigs; i++) {
auto& cfg = supportedConfigs[i];
EGLint r, g, b, d;
if (eglGetConfigAttrib(display, cfg, EGL_RED_SIZE, &r) &&
eglGetConfigAttrib(display, cfg, EGL_GREEN_SIZE, &g) &&
eglGetConfigAttrib(display, cfg, EGL_BLUE_SIZE, &b) &&
eglGetConfigAttrib(display, cfg, EGL_DEPTH_SIZE, &d) &&
r == 8 && g == 8 && b == 8 && d == 0) {
config = supportedConfigs[i];
break;
}
}
if (i == numConfigs) {
config = supportedConfigs[0];
}
EGLint AttribList[] =
{
EGL_CONTEXT_CLIENT_VERSION, 3,
EGL_NONE
};
/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
* guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
* As soon as we picked a EGLConfig, we can safely reconfigure the
* ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
context = eglCreateContext(display, config, NULL, AttribList);
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
log.log_warning("Unable to eglMakeCurrent");
return -1;
}
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
engine->display = display;
engine->context = context;
engine->surface = surface;
engine->width = w;
engine->height = h;
engine->state.angle = 0;
// Check openGL on the system
auto opengl_info = { GL_VENDOR, GL_RENDERER, GL_VERSION, GL_EXTENSIONS };
for (auto name : opengl_info) {
auto info = glGetString(name);
log.log_info("OpenGL Info: %s", info);
}
// Initialize GL state.
// glEnable(GL_CULL_FACE);
// glEnable(GL_DEPTH_TEST);
return 0;
}
完整日志: 日志图片
注意:我的记录器类只是__android_log_vprint()
的包装器。 我没有包括它,因为它一点也不相关。
这个:
#version 300 es
attribute vec4 vPosition;
void main()
{
gl_Position = vPosition;
}
...不是合法的ESSL 300版本着色器,因此您应该获得平台上编译器返回的编译错误日志。 您没有从log_info日志通道获得任何信息吗?
要使着色器合法地使用in
替换attribute
。
根据发布的日志,glCreateShader返回0,仅在上下文无效时才会发生。
查看日志中的时间戳,您似乎在创建OpenGLES上下文之前正在加载着色器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.