Как мне вызвать из класса, который находится в файле для отображения в другом файле, содержащем код gl, используя шейдеры (где оба файла находятся в папке jni)? - PullRequest
1 голос
/ 23 января 2012

Как добавить мой куб в glVertexArttribPointer в файле .cpp?

У меня есть класс Cube и другая группа классов, которые являются подклассом другого класса Mesh. Мой класс куба находится в другом файле-> group.cpp, где мы добавляем куб. Группа является подклассом класса Mesh, а Cube также является подклассом класса Mesh. код gl находится в newproj.cpp, где line-> glVertexAttribPointer (gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); отображает треугольник, поскольку вершины треугольника указаны в том же файле. Итак, как мне отобразить вершины и индексы куба через код gl? Я новичок в шейдерах, поэтому я не очень понимаю, как отображать с помощью шейдеров. Пожалуйста, объясните мне, как поступить с классом группы, в котором мне нужно добавить и удалить куб.

P.S. Я разрабатываю проект с использованием OpenGL ES 2.0 на Eclipse + Ubuntu. Я пытаюсь преобразовать код, который я нашел в этом руководстве (http://blog.jayway.com/2010/02/15/opengl-es-tutorial-for-android-%E2%80%93-part-v/), в C ++, используя JNI

это мой код в newproj.cpp в моем jni:

#include<string.h>
#include<jni.h>

#include<myheader.h>
#include<android/log.h>

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define  LOG_TAG    "libgl2jni"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

//Cube c;
//Mesh m;
    struct SMatrixStack {
        float lpfMatrix[16];
        float lpfInverse[16];
        bool bInverseUpToDate;
        SMatrixStack *lpsmsNext;
    };
    class CMatrix {
        public:
            CMatrix():lpsmsNext(NULL), bInverseUpToDate(false), bNormalUpToDate(false), bInverseNormalUpToDate(false) {LoadIdentity();};
            ~CMatrix() {SMatrixStack *tmp; while (lpsmsNext) {tmp = lpsmsNext; lpsmsNext = lpsmsNext->lpsmsNext; delete tmp;}};

            void LoadIdentity();
            void Rotate(float angle, float x, float y, float z);
            void Translate(float x, float y, float z);

        private:
            float lpfMatrix[16];
            float lpfInverse[16];
            bool bInverseUpToDate;
            bool bNormalUpToDate;
            bool bInverseNormalUpToDate;
            SMatrixStack *lpsmsNext;
            void Concatenate(float *m);
    };

    void CMatrix::LoadIdentity()
    {
        for(int i=0; i<16; i++)
        {
            lpfMatrix[i] = lpfInverse[i] = 0.0;
        }

        lpfMatrix[0] = lpfInverse[0] = 1.0;
        lpfMatrix[5] = lpfInverse[5] = 1.0;
        lpfMatrix[10]= lpfInverse[10]= 1.0;
        lpfMatrix[15]= lpfInverse[15]= 1.0;

        bInverseUpToDate = true;
    }

    void CMatrix::Concatenate(float *m)
    {
        float tm[16];
        int j;

        for(j=0; j<16; j++) tm[j] = 0.0f;
        tm[0] = tm[5] = tm[10] = tm[15] = 1.0f;

        for (int i=0; i<4; i++)
        {
            j = 4*i;
            tm[j+0] = m[j]*lpfMatrix[0] + m[j+1]*lpfMatrix[4] + m[j+2]*lpfMatrix[8] + m[j+3]*lpfMatrix[12];
            tm[j+1] = m[j]*lpfMatrix[1] + m[j+1]*lpfMatrix[5] + m[j+2]*lpfMatrix[9] + m[j+3]*lpfMatrix[13];
            tm[j+2] = m[j]*lpfMatrix[2] + m[j+1]*lpfMatrix[6] + m[j+2]*lpfMatrix[10]+ m[j+3]*lpfMatrix[14];
            tm[j+3] = m[j]*lpfMatrix[3] + m[j+1]*lpfMatrix[7] + m[j+2]*lpfMatrix[11]+ m[j+3]*lpfMatrix[15];
        }
        for (j=0;j<16;j++)  lpfMatrix[j] = tm[j];
        bInverseUpToDate = false;
    }
    void CMatrix::Rotate(float angle, float x, float y, float z)
    {
        float tm[16];
        int j;
        for(j=0; j<16; j++) tm[j] = 0.0f;
        tm[0] = tm[5] = tm[10] = tm[15] = 1.0f;

        float c = cos(angle);
        float s = sin(angle);
        float v = 1.0f - c;


        tm[0] = x*x*v + c;
        tm[1] = x*y*v - z*s;
        tm[2] = x*z*v + y*s;
        tm[4] = x*y*v + z*s;
        tm[5] = y*y*v + c;
        tm[6] = y*z*v - x*s;
        tm[8] = x*z*v - y*s;
        tm[9] = y*z*v + x*s;
        tm[10]= z*z*v + c;

        Concatenate(tm);
    }
    void CMatrix::Translate(float x, float y, float z)
    {
        float tm[16];
        int j;
        for(j=0; j<16; j++) tm[j] = 0.0;
        tm[0] = tm[5] = tm[10] = tm[15] = 1.0;

        tm[3] = x;
        tm[7] = y;
        tm[11]= z;

        Concatenate(tm);
    }

CMatrix cmobj1;

static void printGLString(const char *name, GLenum s) {
    const char *v = (const char *) glGetString(s);
    LOGI("GL %s = %s\n", name, v);
}

static void checkGlError(const char* op) {
    for (GLint error = glGetError(); error; error
            = glGetError()) {
        LOGI("after %s() glError (0x%x)\n", op, error);
    }
}

static const char gVertexShader[] =
    "attribute vec4 vPosition;\n"
    "void main() {\n"
    "  gl_Position = vPosition;\n"
    "}\n";

static const char gFragmentShader[] =
    "precision mediump float;\n"
    "void main() {\n"
    "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
    "}\n";

GLuint loadShader(GLenum shaderType, const char* pSource) {
    GLuint shader = glCreateShader(shaderType);
    if (shader) {
        glShaderSource(shader, 1, &pSource, 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 = (char*) malloc(infoLen);
                if (buf) {
                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
                    LOGE("Could not compile shader %d:\n%s\n",
                            shaderType, buf);
                    free(buf);
                }
                glDeleteShader(shader);
                shader = 0;
            }
        }
    }
    return shader;
}

GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
    if (!vertexShader) {
        return 0;
    }

    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
    if (!pixelShader) {
        return 0;
        }

    GLuint program = glCreateProgram();
    if (program) {
            glAttachShader(program, vertexShader);
            checkGlError("glAttachShader");
            glAttachShader(program, pixelShader);
            checkGlError("glAttachShader");
            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 = (char*) malloc(bufLength);
                    if (buf) {
                        glGetProgramInfoLog(program, bufLength, NULL, buf);
                        LOGE("Could not link program:\n%s\n", buf);
                        free(buf);
                    }
                }
                glDeleteProgram(program);
                program = 0;
            }
        }

    glDeleteShader(vertexShader);
    glDeleteShader(pixelShader);

    return program;

}

GLuint gProgram;
GLuint gvPositionHandle;


bool setupGraphics(int w, int h) {
    printGLString("Version", GL_VERSION);
    printGLString("Vendor", GL_VENDOR);
    printGLString("Renderer", GL_RENDERER);
    printGLString("Extensions", GL_EXTENSIONS);

    LOGI("setupGraphics(%d, %d)", w, h);
    gProgram = createProgram(gVertexShader, gFragmentShader);
    if (!gProgram) {
        LOGE("Could not create program.");
        return false;
    }
    gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
    checkGlError("glGetAttribLocation");
    LOGI("glGetAttribLocation(\"vPosition\") = %d\n", gvPositionHandle);

    glViewport(0, 0, w, h);
    checkGlError("glViewport");
    return true;
}

const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,0.5f, -0.5f };
//const GLfloat cubearray[]=c.Cube(2,2,2);

void renderFrame() {
    static float grey;
    grey += 0.01f;

    glClearColor(grey, grey, grey, 1.0f);
    checkGlError("glClearColor");
    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    checkGlError("glClear");

    // Replace the current matrix with the identity matrix
    cmobj1.LoadIdentity();

    // Translates 4 units into the screen.
    cmobj1.Translate(0.0,0.0,-4.0);

    glUseProgram(gProgram);
    checkGlError("glUseProgram");
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
    //glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, cubearray);
      checkGlError("glVertexAttribPointer");
    glEnableVertexAttribArray(gvPositionHandle);
    checkGlError("glEnableVertexAttribArray");
    glDrawArrays(GL_TRIANGLES, 0, 3);
    checkGlError("glDrawArrays");
    // c.Cube(2,2,2);
    //root.draw();
}

extern "C"
{
    JNIEXPORT void JNICALL Java_newproj_pack_Tutcppmain_init(JNIEnv * env, jobject obj,  jint width, jint height);
    JNIEXPORT void JNICALL Java_newproj_pack_Tutcppmain_step(JNIEnv * env, jobject obj);

};

JNIEXPORT void Java_newproj_pack_Tutcppmain_init(JNIEnv * env, jobject obj,  jint width, jint height)
{
    setupGraphics(width, height);
}

JNIEXPORT void Java_newproj_pack_Tutcppmain_step(JNIEnv * env, jobject obj)
{
    //OpenGLRenderer Renderobj();
    renderFrame();
}

и это мой код group.cpp , который также есть в моем jni:

#include<iostream>
#include <stdio.h>          // Header File For Standard Input/Output

#include <stdlib.h>
#include <math.h>

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include "string.h"
#include<vector>
using namespace std;
//#include<mesh.cpp>
//#include<myheader.h>

#include<iostream>
#include <stdio.h>          // Header File For Standard Input/Output

#include <stdlib.h>
#include <math.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include "string.h"

struct SMatrixStack1 {
        float lpfMatrix[16];
        float lpfInverse[16];
        bool bInverseUpToDate;
        SMatrixStack1 *lpsmsNext;
    };
    class CMatrix1 {
        public:
            CMatrix1():lpsmsNext(NULL), bInverseUpToDate(false), bNormalUpToDate(false), bInverseNormalUpToDate(false) {LoadIdentity();};
            ~CMatrix1() {SMatrixStack1 *tmp; while (lpsmsNext) {tmp = lpsmsNext; lpsmsNext = lpsmsNext->lpsmsNext; delete tmp;}};

            void LoadIdentity();
            void Rotate(float angle, float x, float y, float z);
            void Translate(float x, float y, float z);

        private:
            float lpfMatrix[16];
            float lpfInverse[16];
            bool bInverseUpToDate;
            bool bNormalUpToDate;
            bool bInverseNormalUpToDate;
            SMatrixStack1 *lpsmsNext;
            void Concatenate(float *m);
    };

    void CMatrix1::LoadIdentity()
    {
        for(int i=0; i<16; i++)
        {
            lpfMatrix[i] = lpfInverse[i] = 0.0;
        }

        lpfMatrix[0] = lpfInverse[0] = 1.0;
        lpfMatrix[5] = lpfInverse[5] = 1.0;
        lpfMatrix[10]= lpfInverse[10]= 1.0;
        lpfMatrix[15]= lpfInverse[15]= 1.0;

        bInverseUpToDate = true;
    }

    void CMatrix1::Concatenate(float *m)
            {
        float tm[16];
        int j;

        for(j=0; j<16; j++) tm[j] = 0.0f;
        tm[0] = tm[5] = tm[10] = tm[15] = 1.0f;

        for (int i=0; i<4; i++)
        {
            j = 4*i;
            tm[j+0] = m[j]*lpfMatrix[0] + m[j+1]*lpfMatrix[4] + m[j+2]*lpfMatrix[8] + m[j+3]*lpfMatrix[12];
            tm[j+1] = m[j]*lpfMatrix[1] + m[j+1]*lpfMatrix[5] + m[j+2]*lpfMatrix[9] + m[j+3]*lpfMatrix[13];
            tm[j+2] = m[j]*lpfMatrix[2] + m[j+1]*lpfMatrix[6] + m[j+2]*lpfMatrix[10]+ m[j+3]*lpfMatrix[14];
            tm[j+3] = m[j]*lpfMatrix[3] + m[j+1]*lpfMatrix[7] + m[j+2]*lpfMatrix[11]+ m[j+3]*lpfMatrix[15];
        }
        for (j=0;j<16;j++)  lpfMatrix[j] = tm[j];
        bInverseUpToDate = false;
    }
    void CMatrix1::Rotate(float angle, float x, float y, float z)
    {
        float tm[16];
        int j;
        for(j=0; j<16; j++) tm[j] = 0.0f;
        tm[0] = tm[5] = tm[10] = tm[15] = 1.0f;

        float c = cos(angle);
        float s = sin(angle);
        float v = 1.0f - c;

        tm[0] = x*x*v + c;
        tm[1] = x*y*v - z*s;
        tm[2] = x*z*v + y*s;
        tm[4] = x*y*v + z*s;
        tm[5] = y*y*v + c;
        tm[6] = y*z*v - x*s;
        tm[8] = x*z*v - y*s;
        tm[9] = y*z*v + x*s;
        tm[10]= z*z*v + c;

        Concatenate(tm);
    }
    void CMatrix1::Translate(float x, float y, float z)
    {
        float tm[16];
        int j;
        for(j=0; j<16; j++) tm[j] = 0.0;
        tm[0] = tm[5] = tm[10] = tm[15] = 1.0;

        tm[3] = x;
        tm[7] = y;
        tm[11]= z;

        Concatenate(tm);
    }


class Mesh
{
    private:

        // Flat Color
        float rgba[4];
        int isize;
        int vsize;
        int csize;

        //CMatrix cmobj;
        GLuint program;


    public:

        Mesh();
        void draw();
        float *IBuffer;
        float *VBuffer;
        float *CBuffer;

        float x;
        float y;
        float z;

        CMatrix1 cmobj;
    protected:
        void setVertices(float &vertices, int vsize);
        void setIndices(short &indices, int isize);
        void setColor(float red, float green, float blue, float alpha);
        void setColors(float &colors, int csize);

};

Mesh::Mesh(){
    int isize=-1;
    float *p = rgba;

    // Smooth Colors
    *CBuffer = NULL;
    *VBuffer=NULL;
    *IBuffer=NULL;
    float rgba[]={ 1.0f, 1.0f, 1.0f, 1.0f };
    GLuint program = glCreateProgram();
}

void Mesh:: draw()
{
    float rgba[]={ 1.0f, 1.0f, 1.0f, 1.0f };
    float *vertices;
    // Rotate params.
        float rx = 0;

        float ry = 0;

        float rz = 0;

    // Counter-clockwise winding.
    glFrontFace(GL_CCW);
    // Enable face culling.
    glEnable(GL_CULL_FACE);
    // What faces to remove with the face culling.
    glCullFace(GL_BACK);

/*
    static const char gVertexShader[] =
        "attribute vec4 a_Color;\n"
        "glVertexAttrib4f(a_Color, rgba[0], rgba[1], rgba[2], rgba[3]);"
        "varying vec4 v_Color;\n"
        "attribute vec4 a_Position;"
        "void main() {\n"
            "  v_Color = a_Color;\n"
        "a_Position = Projection * Modelview * Position;"
        "gl_Position=a_Position;"

        "}\n";
    static const char gFragmentShader[] =
        "precision mediump float;\n"
        "varying vec4 v_Color;\n"
        "void main() {\n"
        "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
        "gl_FragColor=v_Color;\n"
        "}\n";
*/
    static const char gVertexShader[] =
        "attribute vec4 vPosition;\n"
        "void main() {\n"
        "  gl_Position = vPosition;\n"
        "}\n";

    static const char gFragmentShader[] =
        "precision mediump float;\n"
        "void main() {\n"
        "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
        "}\n";
    GLuint positionSlot = glGetAttribLocation(program, "vPosition");
    glVertexAttrib4fv(0, rgba);

    glEnableVertexAttribArray(positionSlot);

    GLsizei stride = sizeof(vertices);
    glVertexAttribPointer(positionSlot, 2, GL_FLOAT, GL_FALSE, stride, VBuffer);

    //glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
    glClearColor(1.0,1.0,1.0,1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    cmobj.Translate(x, y, z);
    cmobj.Rotate(rx, 1, 0, 0);
    cmobj.Rotate(ry, 0, 1, 0);
    cmobj.Rotate(rz, 0, 0, 1);

    // Point out the where the color buffer is.
    glDrawElements(GL_TRIANGLES, isize,GL_UNSIGNED_SHORT, IBuffer);
    // Disable the vertices buffer.
    glDisableVertexAttribArray(positionSlot);
    // Disable face culling.
    glDisable(GL_CULL_FACE);

}


void Mesh::setVertices(float &vertices, int vsize)
{
    for(int v=0;v<vsize;v++)
    {
        VBuffer[v]=vertices;
    }
}

void Mesh::setIndices(short &indices, int isize)
{

    for(int i=0;i<isize;i++)
    {
        IBuffer[i]=indices;
    }
}

void Mesh::setColor(float red, float green, float blue, float alpha)
{
        // Setting the flat color.
        rgba[0] = red;
        rgba[1] = green;
        rgba[2] = blue;
        rgba[3] = alpha;
}

void Mesh::setColors(float &colors, int csize)
{

    for(int c=0; c<csize;c++){
        CBuffer[c]=colors;
    }
}


class Cube : Mesh
{
    public:
        Cube(float width, float height, float depth);
};


    Cube::Cube(float width, float height, float depth) {
        width /= 2;
        height /= 2;
        depth /= 2;

        float vertices[] =
        {
                -width, -height, -depth, // 0
                width, -height, -depth, // 1
                width, height, -depth, // 2
                -width, height, -depth, // 3
                -width, -height, depth, // 4
                width, -height, depth, // 5
                width, height, depth, // 6
                -width, height, depth, // 7
        };

        short indices[] = { 0, 4, 5, 0, 5, 1, 1, 5, 6, 1, 6, 2, 2, 6, 7, 2, 7,
                3, 3, 7, 4, 3, 4, 0, 4, 7, 6, 4, 6, 5, 3, 0, 1, 3, 1, 2, };



        int vsize=sizeof(vertices);
        int isize=sizeof(indices);

        setIndices(*indices,isize);
        setVertices(*vertices,vsize);


    }

class Group : Mesh {
public:
  void AddCube() {
      Cube c;
      c.Cube(2,2,2);

  }
  void drawobj(){
      Mesh m;
      m.draw();
  }
private:

};
vector<Group> grpobj;

1 Ответ

0 голосов
/ 26 января 2012

Это полный и полный беспорядок. Вам нужно отделить геометрию от шейдеров. Таким образом, геометрия вашего класса должна только экспортировать его списки вершин и индексов и иметь возможность

a) вызовите glVertexAttribPointer () и glEnableVertexAttribArray () для подготовки к рендерингу и
б) визуализировать их с помощью glDrawElements ().

Это важно, потому что вы можете рендерить один объект в нескольких местах, тогда вы делаете а) один раз и б) много раз.

Шейдеры - это совсем другое. У вас должен быть класс с шейдерами, который может компилировать исходные коды шейдеров, а затем использовать шейдеры. Возможно, вы захотите иметь более одного шейдера в своем приложении, поэтому вы будете компилировать шейдеры один раз при запуске, а затем переключаться между ними во время рисования.

Я не собираюсь исправлять твой код. Вам лучше написать простое приложение (например, «первый треугольник» или «цветной треугольник», как их часто называют), и улучшить оттуда свой объектный дизайн.

...