android jni opengles,c++ - Android NDK OpenGLES not rendering triangles - Stack Overflow

I have been struggling to correctly render any geometry using OpenGLES 1.0, 2.0, or 3.0 techniques. My testing device is a Samsung Galaxy S7 Edge (running Android 7.0). I have implemented numerous guides for both OpenGLES and EGL such as:

The code was initially adapted from the "native-activity" example:

Android Manifest: (mostly from native-activity example)

...

...

CMAKE: (mostly from native-activity example)

...

add_library(

native-activity

SHARED

main.cpp)

target_include_directories(

native-activity

PRIVATE

${ANDROID_NDK}/sources/android/native_app_glue)

# add lib dependencies

target_link_libraries(

native-activity

android

native_app_glue

EGL

GLESv3

log)

...

main.cpp: (mostly from native-activity example, cropped for relevance)

...

#include

#include

#include

#include

#include

...

/*

*Test GLES 1.0, should draw a white triangle on red background

*/

class TestGLES10 {

public:

GLuint program;

void create() {

char vssource[] =

"attribute vec4 vertexPosition; \n"

"void main(){ \n"

" gl_Position = vertexPosition; \n"

"} \n";

char fssource[] =

"precision mediump float; \n"

"void main(){ \n"

" gl_FragColor = vec4(1.0); "

"} \n";

auto compile = [](const char *source, GLenum type){

GLuint shader = glCreateShader(type);

glShaderSource(shader, 1, &source, nullptr);

glCompileShader(shader);

return shader;

};

GLuint vs = compile(string(vssource).c_str(), GL_VERTEX_SHADER);

GLuint fs = compile(string(fssource).c_str(), GL_FRAGMENT_SHADER);

program = glCreateProgram();

glAttachShader(program, vs);

glAttachShader(program, fs);

glBindAttribLocation(program, 0, "vertexPosition");

glLinkProgram(program);

glDisable(GL_DEPTH_TEST);

}

void update() {

glClearColor(1,0,0,1);

glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(program);

float positions[]{

0.0f, 0.1f,

-0.1f, -0.1f,

0.1f, -0.1f

};

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, positions);

glEnableVertexAttribArray(0);

glDrawArrays(GL_TRIANGLES, 0, 3);

}

};

/*

*Test GLES 3.0, should draw a white triangle on blue background

*/

class TestGLES30 {

public:

GLuint vbo, vao, program;

void create() {

char vssource[] =

"#version 300 es\n"

"layout(location=0) in vec4 vertexPosition; \n"

"void main(){ \n"

" gl_Position = vertexPosition; \n"

"} \n";

char fssource[] =

"#version 300 es\n"

"precision mediump float; \n"

"out vec4 fragment; \n"

"void main(){ \n"

" fragment = vec4(1.0); "

"} \n";

auto compile = [](const char *source, GLenum type){

GLuint shader = glCreateShader(type);

glShaderSource(shader, 1, &source, nullptr);

glCompileShader(shader);

return shader;

};

GLuint vs = compile(string(vssource).c_str(), GL_VERTEX_SHADER);

GLuint fs = compile(string(fssource).c_str(), GL_FRAGMENT_SHADER);

program = glCreateProgram();

glAttachShader(program, vs);

glAttachShader(program, fs);

glLinkProgram(program);

float positions[]{

0.0f, 0.5f,

-0.5f, -0.5f,

0.5f, -0.5f

};

glGenBuffers(1, &vbo);

glBindBuffer(GL_ARRAY_BUFFER, vbo);

glBufferData(GL_ARRAY_BUFFER, 2*4, positions, GL_STATIC_DRAW);

glGenVertexArrays(1, &vao);

glBindVertexArray(vao);

glEnableVertexAttribArray(0);

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*4, 0);

glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindVertexArray(0);

}

void update() {

glClearColor(0,0,1,1);

glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(program);

glBindVertexArray(vao);

glDrawArrays(GL_TRIANGLES, 0, 3);

glBindVertexArray(0);

}

};

...

void android_main(android_app* appInterface) {

appInterface->onAppCmd = commandRelay;

appInterface->onInputEvent = inputRelay;

while(appInterface->window == nullptr){

pollEvents(appInterface);

}

EGLDisplay display;

EGLSurface surface;

EGLContext context;

EGLint majorVersion, minorVersion;

EGLConfig config;

EGLint width, height;

EGLint nativeVisualID;

EGLint configCount;

display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

assert(display != EGL_NO_DISPLAY);

eglInitialize(display, &majorVersion, &minorVersion);

//https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglChooseConfig.xhtml

const EGLint displayAttrib[] = {

EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,//egl 1.3 req

EGL_NATIVE_RENDERABLE, EGL_TRUE,

EGL_SURFACE_TYPE, EGL_WINDOW_BIT,

EGL_BLUE_SIZE, 8,

EGL_GREEN_SIZE, 8,

EGL_RED_SIZE, 8,

EGL_NONE

};

//retreive configs

eglChooseConfig(display, displayAttrib, 0, 0, &configCount);

std::unique_ptr supported(new EGLConfig[configCount]);

eglChooseConfig(display, displayAttrib, supported.get(), configCount, &configCount);

EGLint i = 0, v;

for (; i < configCount; i++) {

auto get = [&](EGLint attrib){

eglGetConfigAttrib(display, supported[i], attrib, &v);

return v;

};

if (Math2::equal(8,

get(EGL_RED_SIZE),

get(EGL_GREEN_SIZE),

get(EGL_BLUE_SIZE),

get(EGL_DEPTH_SIZE))) {//expands to 8 == get(EGL_RED_SIZE) == ...

config = supported[i];

break;

}

}

if (i == configCount) {//default to first

config = supported[0];

}

const EGLint surfaceAttrib[] = {

EGL_RENDER_BUFFER, EGL_BACK_BUFFER,// render to the back buffer, egl 1.2 req

EGL_NONE

};

eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &nativeVisualID);

surface = eglCreateWindowSurface(display, config, appInterface->window, surfaceAttrib);

const EGLint contextAttrib[] = {

EGL_CONTEXT_CLIENT_VERSION, 2,// request a context using Open GL ES 2.0

EGL_NONE

};

context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttrib);

assert(context != EGL_NO_CONTEXT);

//sets initial viewport and scissor dimensions to draw surface size

eglMakeCurrent(display, surface, surface, context);

eglQuerySurface(display, surface, EGL_WIDTH, &width);

eglQuerySurface(display, surface, EGL_HEIGHT, &height);

//this call was mentioned, but missing from the example (removing has same effect)

ANativeWindow_setBuffersGeometry(appInterface->window, width, height, nativeVisualID);

TestGLES10 test;

test.create();

while (true){

test.update();

eglSwapBuffers(display, surface);

}

}

Results:

Logged Info:

Vendor : Qualcomm

Renderer : Adreno (TM) 530

Version : OpenGL ES 3.2 V@145.0 (GIT@I86b60582e4)

EGL version : 1.4

Window dimensions : 1080, 1920

Additionally, the device has resolution scaling set to 1080x1920.

According to:

https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglMakeCurrent.xhtml

the glViewPort should have been initialized to the surface size (1080x1920), so I am at a loss for how the white rectangle could occur.

The shader code for both tests compile without errors from Adreno.

Why wont it render geometry correctly?

According to :

https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglCreateContext.xhtml

there is no way to specifically request a 3.0 or higher context, why does the created context have version 3.2 when I can only request 2.0?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值