Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  abc3d.cpp

  Sprache: C
 

/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include <vector>
#include <math.h>

#define GL_GLEXT_PROTOTYPES
#define EGL_EGLEXT_PROTOTYPES
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#undef EGL_EGLEXT_PROTOTYPES
#undef GL_GLEXT_PROTOTYPES

#include "abc3d.h"
#include "debug.h"

namespace android {
namespace hardware {
namespace camera {
namespace provider {
namespace implementation {
namespace abc3d {
namespace {
constexpr char kTag[] = "abc3d";

float dot3(const float a3[], const float b3[]) {
    return a3[0] * b3[0] + a3[1] * b3[1] + a3[2] * b3[2];
}

/*
 * https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/gluLookAt.xml
 * https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/glTranslate.xml
 * This function takes `m44` (where zzz (assumed zero) and ooo (assumed one)
 * are ignored) and multiplies it by a translation matrix.
 *
 *           m44             translate
 *  [  s0  s1  s2 zzz ]   [ 1 0 0 -eyeX ]   [  s0  s1  s2 -dot3(m44[0:2],  eye3) ]
 *  [ up0 up1 up2 zzz ] * [ 0 1 0 -eyeY ] = [ up0 up1 up2 -dot3(m44[4:6],  eye3) ]
 *  [  b0  b1  b2 zzz ]   [ 0 0 1 -eyeZ ]   [  b0  b1  b2 -dot3(m44[8:10], eye3) ]
 *  [ zzz zzz zzz ooo ]   [ 0 0 0     1 ]   [   0   0   0                      1 ]
*/

void lookAtEyeCoordinates(float m44[], const float eye3[]) {
    m44[3]  = -dot3(&m44[0], eye3);
    m44[7]  = -dot3(&m44[4], eye3);
    m44[11] = -dot3(&m44[8], eye3);
    m44[12] = 0;
    m44[13] = 0;
    m44[14] = 0;
    m44[15] = 1;
}
}  // namespace

#define RETURN_CTOR_FAILED(S) \
    ALOGE("%s:%s:%d %s failed", kTag, __func__, __LINE__, S); return;

AutoImageKHR::AutoImageKHR(const EGLDisplay display, const EGLClientBuffer clientBuf)
        : mEglDisplay(display) {
    static const EGLint imageAttrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
    mEglImage = eglCreateImageKHR(
        display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuf, imageAttrs);
    if (mEglImage == EGL_NO_IMAGE_KHR) {
        RETURN_CTOR_FAILED("eglCreateImageKHR");
    }
}

AutoImageKHR::AutoImageKHR(AutoImageKHR&& rhs) noexcept
        : mEglDisplay(rhs.mEglDisplay)
        , mEglImage(std::exchange(rhs.mEglImage, EGL_NO_IMAGE_KHR)) {}

AutoImageKHR& AutoImageKHR::operator=(AutoImageKHR&& rhs) noexcept {
    if (this != &rhs) {
        mEglDisplay = rhs.mEglDisplay;
        mEglImage = std::exchange(rhs.mEglImage, EGL_NO_IMAGE_KHR);
    }
    return *this;
}

AutoImageKHR::~AutoImageKHR() {
    if (mEglImage != EGL_NO_IMAGE_KHR) {
        eglDestroyImageKHR(mEglDisplay, mEglImage);
    }
}

EglCurrentContext::EglCurrentContext(const EGLDisplay display)
        : mEglDisplay(display) {}

EglCurrentContext::EglCurrentContext(EglCurrentContext&& rhs) noexcept
        : mEglDisplay(std::exchange(rhs.mEglDisplay, EGL_NO_DISPLAY)) {}

EglCurrentContext& EglCurrentContext::operator=(EglCurrentContext&& rhs) noexcept {
    if (this != &rhs) {
        mEglDisplay = std::exchange(rhs.mEglDisplay, EGL_NO_DISPLAY);
    }
    return *this;
}

EglCurrentContext::~EglCurrentContext() {
    if (mEglDisplay != EGL_NO_DISPLAY) {
        LOG_ALWAYS_FATAL_IF(!eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
                                            EGL_NO_SURFACE, EGL_NO_CONTEXT));
    }
}

EglContext::EglContext(EglContext&& rhs) noexcept
        : mEglDisplay(std::exchange(rhs.mEglDisplay, EGL_NO_DISPLAY))
        , mEglContext(std::exchange(rhs.mEglContext, EGL_NO_CONTEXT))
        , mEglSurface(std::exchange(rhs.mEglSurface, EGL_NO_SURFACE)) {}

EglContext& EglContext::operator=(EglContext&& rhs) noexcept {
    if (this != &rhs) {
        mEglDisplay = std::exchange(rhs.mEglDisplay, EGL_NO_DISPLAY);
        mEglContext = std::exchange(rhs.mEglContext, EGL_NO_CONTEXT);
        mEglSurface = std::exchange(rhs.mEglSurface, EGL_NO_SURFACE);
    }
    return *this;
}

EglContext::~EglContext() {
    clear();
}

void EglContext::clear() {
    if (mEglSurface != EGL_NO_SURFACE) {
        eglDestroySurface(mEglDisplay, mEglSurface);
        mEglSurface = EGL_NO_SURFACE;
    }
    if (mEglContext != EGL_NO_CONTEXT) {
        eglDestroyContext(mEglDisplay, mEglContext);
        mEglContext = EGL_NO_CONTEXT;
    }
    if (mEglDisplay != EGL_NO_DISPLAY) {
        eglTerminate(mEglDisplay);
        mEglDisplay = EGL_NO_DISPLAY;
    }
}

EglCurrentContext EglContext::init() {
    if (mEglContext != EGL_NO_CONTEXT) {
        LOG_ALWAYS_FATAL_IF(!eglMakeCurrent(mEglDisplay, mEglSurface,
                                            mEglSurface, mEglContext));
        return EglCurrentContext(mEglDisplay);
    }

    const EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (display == EGL_NO_DISPLAY) {
        return EglCurrentContext(FAILURE(EGL_NO_DISPLAY));
    }

    EGLint major, minor;
    if (!eglInitialize(display, &major, &minor)) {
        return EglCurrentContext(FAILURE(EGL_NO_DISPLAY));
    }
    ALOGD("%s:%d: Initialized EGL, version %d.%d", __func__, __LINE__,
          static_cast<int>(major), static_cast<int>(minor));

    static const EGLint configAttrs[] = {
        EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
        EGL_CONFIG_CAVEAT,      EGL_NONE,
        EGL_RED_SIZE,           8,
        EGL_GREEN_SIZE,         8,
        EGL_BLUE_SIZE,          8,
        EGL_ALPHA_SIZE,         8,
        EGL_NONE
    };

    EGLint numConfigs = 1;
    EGLConfig config = EGL_NO_CONFIG_KHR;
    if (!eglChooseConfig(display, configAttrs, &config, 1, &numConfigs) ||
            (config == EGL_NO_CONFIG_KHR) || (numConfigs != 1)) {
        eglTerminate(display);
        return EglCurrentContext(FAILURE(EGL_NO_DISPLAY));
    }

    static const EGLint contextAttrs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    const EGLContext context = eglCreateContext(display, config,
                                                EGL_NO_CONTEXT, contextAttrs);
    if (context == EGL_NO_CONTEXT) {
        eglTerminate(display);
        return EglCurrentContext(FAILURE(EGL_NO_DISPLAY));
    }

    EGLSurface surface = EGL_NO_SURFACE;
    if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context)) {
        // EGL_KHR_surfaceless_context is not supported
        const EGLint surfaceAttrs[] = {
            EGL_WIDTH,  1,
            EGL_HEIGHT, 1,
            EGL_NONE
        };
        surface = eglCreatePbufferSurface(display, config, surfaceAttrs);
        if (surface == EGL_NO_SURFACE) {
            eglDestroyContext(display, context);
            eglTerminate(display);
            return EglCurrentContext(FAILURE(EGL_NO_DISPLAY));
        }

        if (!eglMakeCurrent(display, surface, surface, context)) {
            eglDestroySurface(display, surface);
            eglDestroyContext(display, context);
            eglTerminate(display);
            return EglCurrentContext(FAILURE(EGL_NO_DISPLAY));
        }
    }

    mEglDisplay = display;
    mEglContext = context;
    mEglSurface = surface;

    return EglCurrentContext(display);
}

EglCurrentContext EglContext::getCurrentContext() {
    if (mEglContext == EGL_NO_CONTEXT) {
        return EglCurrentContext(EGL_NO_DISPLAY);
    } else if (eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
        return EglCurrentContext(mEglDisplay);
    } else {
        return EglCurrentContext(FAILURE(EGL_NO_DISPLAY));
    }
}

AutoTexture::AutoTexture(const GLenum target) {
    glGenTextures(1, &mTex);
    if (mTex) {
        glBindTexture(target, mTex);
    } else {
        RETURN_CTOR_FAILED("glGenTextures");
    }
}

AutoTexture::AutoTexture(const GLenum target,
                         const GLint internalformat,
                         const GLsizei width,
                         const GLsizei height,
                         const GLenum format,
                         const GLenum type,
                         const void* data) {
    glGenTextures(1, &mTex);
    if (mTex) {
        glBindTexture(target, mTex);
        glTexImage2D(target, 0, internalformat, width, height, 0, format, type, data);
    } else {
        RETURN_CTOR_FAILED("glGenTextures");
    }
}

AutoTexture::AutoTexture(AutoTexture&& rhs) noexcept
        : mTex(std::exchange(rhs.mTex, 0)) {}

AutoTexture& AutoTexture::operator=(AutoTexture&& rhs) noexcept {
    if (this != &rhs) {
        mTex = std::exchange(rhs.mTex, 0);
    }
    return *this;
}

AutoTexture::~AutoTexture() {
    clear();
}

void AutoTexture::clear() {
    if (mTex) {
        glDeleteTextures(1, &mTex);
        mTex = 0;
    }
}

AutoFrameBuffer::AutoFrameBuffer() {
    glGenFramebuffers(1, &mFBO);
    if (mFBO) {
        glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
    } else {
        RETURN_CTOR_FAILED("glGenFramebuffers");
    }
}

AutoFrameBuffer::~AutoFrameBuffer() {
    if (mFBO) {
        glDeleteFramebuffers(1, &mFBO);
    }
}

AutoShader::AutoShader(AutoShader&& rhs) noexcept
        : mShader(std::exchange(rhs.mShader, 0)) {}

AutoShader& AutoShader::operator=(AutoShader&& rhs) noexcept {
    if (this != &rhs) {
        mShader = std::exchange(rhs.mShader, 0);
    }
    return *this;
}

AutoShader::~AutoShader() {
    if (mShader) {
        glDeleteShader(mShader);
    }
}

GLuint AutoShader::compile(const GLenum type, const char* text) {
    const GLuint shader = glCreateShader(type);
    if (!shader) {
        return FAILURE(0);
    }

    glShaderSource(shader, 1, &text, nullptr);
    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 > 1) {
            std::vector<char> msg(infoLen + 1);
            glGetShaderInfoLog(shader, infoLen, nullptr, msg.data());
            msg[infoLen] = 0;
            ALOGE("%s:%d: error compiling shader '%s' (type=%d): '%s'",
                  __func__, __LINE__, text, type, msg.data());
        }
        glDeleteShader(shader);
        return FAILURE(0);
    }

    if (mShader) {
        glDeleteShader(mShader);
    }

    mShader = shader;
    return shader;
}

AutoProgram::AutoProgram(AutoProgram&& rhs) noexcept
        : mProgram(std::exchange(rhs.mProgram, 0)) {}

AutoProgram& AutoProgram::operator=(AutoProgram&& rhs) noexcept {
    if (this != &rhs) {
        mProgram = std::exchange(rhs.mProgram, 0);
    }
    return *this;
}

AutoProgram::~AutoProgram() {
    clear();
}

void AutoProgram::clear() {
    if (mProgram) {
        glDeleteProgram(mProgram);
        mProgram = 0;
    }
}

bool AutoProgram::link(const GLuint vertexShader,
                       const GLuint fragmentShader) {
    const GLuint program = glCreateProgram();
    if (!program) {
        return FAILURE(false);
    }

    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
    glLinkProgram(program);

    GLint linked = 0;
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if (!linked) {
        GLint infoLen = 0;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
        if(infoLen > 1) {
            std::vector<char> msg(infoLen + 1);
            glGetProgramInfoLog(program, infoLen, nullptr, msg.data());
            msg[infoLen] = 0;
            ALOGE("%s:%d: error linking shaders: '%s'",
                  __func__, __LINE__, msg.data());
        }

        glDeleteProgram(program);
        return FAILURE(false);
    }

    if (mProgram) {
        glDeleteProgram(mProgram);
    }

    mProgram = program;
    return true;
}

GLint AutoProgram::getAttribLocation(const char* name) const {
    if (mProgram > 0) {
        const GLint result = glGetAttribLocation(mProgram, name);
        return (result >= 0) ? result : FAILURE(-1);
    } else {
        return FAILURE(-1);
    }
}

GLint AutoProgram::getUniformLocation(const char* name) const {
    if (mProgram > 0) {
        const GLint result = glGetUniformLocation(mProgram, name);
        return (result >= 0) ? result : FAILURE(-1);
    } else {
        return FAILURE(-1);
    }
}

// https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/glFrustum.xml
void frustum(float m44[],
             const double left, const double right,
             const double bottom, const double top,
             const double near, const double far) {
    const double invWidth = 1.0 / (right - left);
    const double invHeight = 1.0 / (top - bottom);
    const double invDepth = 1.0 / (far - near);
    const double near2 = 2 * near;

    m44[0] = near2 * invWidth;
    m44[1] = 0;
    m44[2] = (right + left) * invWidth;
    m44[3] = 0;

    m44[4] = 0;
    m44[5] = near2 * invHeight;
    m44[6] = (top + bottom) * invHeight;
    m44[7] = 0;

    m44[8] = 0;
    m44[9] = 0;
    m44[10] = -(far + near) * invDepth;
    m44[11] = -far * near2 * invDepth;

    m44[12] = 0;
    m44[13] = 0;
    m44[14] = -1;
    m44[15] = 0;
}

/*
 * https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/gluLookAt.xml
 * https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
 *
 * Here we calculate {Side, Up, Backwards} from Euler angles in the XYZ order:
 *
 * [ 1,    0,     0 ]   [  cosY, 0, sinY ]   [ cosZ, -sinZ, 0 ]   [ sx, ux, bx ]
 * [ 0, cosX, -sinX ] * [     0, 1,    0 ] * [ sinZ,  cosZ, 0 ] = [ sy, uy, by ]
 * [ 0, sinX,  cosX ]   [ -sinY, 0, cosY ]   [    0,     0, 1 ]   [ sz, uz, bz ]
 *
 * We calculate `backwards` because the camera looks into the negative Z
 * direction, so instead of calculating camera's forward and negating it twice,
 * let's call it `backwards`.
 *
 * After multiplying the first two:
 * [         cosY,    0,         sinY ]
 * [  sinX * sinY, cosX, -sinX * cosY ]
 * [ -cosX * sinY, sinX,  cosX * cosY ]
 *
 * The final result:
 * [                       cosY * cosZ,                      -cosY * sinZ,         sinY ]
 * [  sinX * sinY * cosZ + cosX * sinZ, -sinX * sinY * sinZ + cosX * cosZ, -sinX * cosY ]
 * [ -cosX * sinY * cosZ + sinX * sinZ,  cosX * sinY * sinZ + sinX * cosZ,  cosX * cosY ]
 *
 * {Side, Up, Backwards} are the columns in the matrix above.
 */

void lookAtXyzRot(float m44[], const float eye3[], const float rot3[]) {
    const double sinX = sin(rot3[0]);
    const double cosX = cos(rot3[0]);
    const double sinY = sin(rot3[1]);
    const double cosY = cos(rot3[1]);
    const double sinZ = sin(rot3[2]);
    const double cosZ = cos(rot3[2]);

    m44[0]  = cosY * cosZ;
    m44[1]  = sinX * sinY * cosZ + cosX * sinZ;
    m44[2]  = -cosX * sinY * cosZ + sinX * sinZ;
    m44[4]  = -cosY * sinZ;
    m44[5]  = -sinX * sinY * sinZ + cosX * cosZ;
    m44[6]  = cosX * sinY * sinZ + sinX * cosZ;
    m44[8]  = sinY;
    m44[9]  = -sinX * cosY;
    m44[10] = cosX * cosY;
    lookAtEyeCoordinates(m44, eye3);
}

void mulM44(float m44[], const float lhs44[], const float rhs44[]) {
    m44[0] = lhs44[0] * rhs44[0] + lhs44[1] * rhs44[4] + lhs44[2] * rhs44[8] + lhs44[3] * rhs44[12];
    m44[1] = lhs44[0] * rhs44[1] + lhs44[1] * rhs44[5] + lhs44[2] * rhs44[9] + lhs44[3] * rhs44[13];
    m44[2] = lhs44[0] * rhs44[2] + lhs44[1] * rhs44[6] + lhs44[2] * rhs44[10] + lhs44[3] * rhs44[14];
    m44[3] = lhs44[0] * rhs44[3] + lhs44[1] * rhs44[7] + lhs44[2] * rhs44[11] + lhs44[3] * rhs44[15];

    m44[4] = lhs44[4] * rhs44[0] + lhs44[5] * rhs44[4] + lhs44[6] * rhs44[8] + lhs44[7] * rhs44[12];
    m44[5] = lhs44[4] * rhs44[1] + lhs44[5] * rhs44[5] + lhs44[6] * rhs44[9] + lhs44[7] * rhs44[13];
    m44[6] = lhs44[4] * rhs44[2] + lhs44[5] * rhs44[6] + lhs44[6] * rhs44[10] + lhs44[7] * rhs44[14];
    m44[7] = lhs44[4] * rhs44[3] + lhs44[5] * rhs44[7] + lhs44[6] * rhs44[11] + lhs44[7] * rhs44[15];

    m44[8] = lhs44[8] * rhs44[0] + lhs44[9] * rhs44[4] + lhs44[10] * rhs44[8] + lhs44[11] * rhs44[12];
    m44[9] = lhs44[8] * rhs44[1] + lhs44[9] * rhs44[5] + lhs44[10] * rhs44[9] + lhs44[11] * rhs44[13];
    m44[10] = lhs44[8] * rhs44[2] + lhs44[9] * rhs44[6] + lhs44[10] * rhs44[10] + lhs44[11] * rhs44[14];
    m44[11] = lhs44[8] * rhs44[3] + lhs44[9] * rhs44[7] + lhs44[10] * rhs44[11] + lhs44[11] * rhs44[15];

    m44[12] = lhs44[12] * rhs44[0] + lhs44[13] * rhs44[4] + lhs44[14] * rhs44[8] + lhs44[15] * rhs44[12];
    m44[13] = lhs44[12] * rhs44[1] + lhs44[13] * rhs44[5] + lhs44[14] * rhs44[9] + lhs44[15] * rhs44[13];
    m44[14] = lhs44[12] * rhs44[2] + lhs44[13] * rhs44[6] + lhs44[14] * rhs44[10] + lhs44[15] * rhs44[14];
    m44[15] = lhs44[12] * rhs44[3] + lhs44[13] * rhs44[7] + lhs44[14] * rhs44[11] + lhs44[15] * rhs44[15];
}

}  // namespace abc3d
}  // namespace implementation
}  // namespace provider
}  // namespace camera
}  // namespace hardware
}  // namespace android

Messung V0.5 in Prozent
C=96 H=95 G=95

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-06-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik