gpt4 book ai didi

c++ - Android NDK OpenGLES 不渲染三角形

转载 作者:太空宇宙 更新时间:2023-11-04 12:50:41 26 4
gpt4 key购买 nike

我一直在努力使用 OpenGLES 1.0、2.0 或 3.0 技术正确渲染任何几何体。我的测试设备是三星 Galaxy S7 Edge(运行 Android 7.0)。我已经为 OpenGLES 和 EGL 实现了许多指南,例如:

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

https://www.khronos.org/assets/uploads/books/openglr_es_20_programming_guide_sample.pdf

http://www.ikerhurtado.com/egl-use-android-native-opengles-applications

代码最初改编自“native-activity”示例:

https://github.com/googlesamples/android-ndk/tree/master/native-activity


Android list :(主要来自 native 事件示例)

...
<!-- Tell the system this app requires OpenGL ES 3.0. -->
<uses-feature android:glEsVersion="0x00030000" android:required="true" />
...

CMAKE:(主要来自 native 事件示例)

...

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:(主要来自 native 事件示例,根据相关性裁剪)

...

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#include <android_native_app_glue.h>

...

/*
*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<EGLConfig[]> 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);
}
}

结果:

记录的信息:

Vendor : Qualcomm
Renderer : Adreno (TM) 530
Version : OpenGL ES 3.2 V@145.0 (GIT@I86b60582e4)
EGL version : 1.4
Window dimensions : 1080, 1920

此外,设备的分辨率缩放设置为 1080x1920。

测试 1.0:https://i.imgur.com/dmofGYw.png测试 3.0:https://i.imgur.com/uoghOZc.png

根据: https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglMakeCurrent.xhtmlglViewPort 应该已经初始化为表面大小 (1080x1920),所以我不知道白色矩形是如何出现的。

两个测试的着色器代码编译时没有来自 Adreno 的错误。


为什么它不能正确渲染几何图形?

根据: https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglCreateContext.xhtml没有办法专门请求 3.0 或更高版本的上下文,为什么创建的上下文有 3.2 版本,而我只能请求 2.0?

最佳答案

Why wont it render geometry correctly?

你的位置数组是三个顶点,每个顶点有两个分量(x,y),但是你告诉 GL 它们每个都有三个分量:

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

why does the created context have version 3.2 when I can only request 2.0?

3.x 版与为 2.0 版编写的代码完全向前兼容,因此驱动程序将上下文升级到它们支持的最新版本是合法的。

关于c++ - Android NDK OpenGLES 不渲染三角形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49212540/

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