简体   繁体   English

OpenGL在OSX上出现段错误,但在Raspberry Pi上运行良好

[英]OpenGL segfaults on OSX but works fine on Raspberry Pi

I have started developing an OpenGL (ES) application which will run on both Raspberry Pi and OS X. I'v based my starting point on the "triangle" example which ships with rasbian. 我已经开始开发可在Raspberry Pi和OS X上运行的OpenGL(ES)应用程序。我基于rasbian附带的“三角形”示例作为起点。 This example displays a rotating cube with mapped textures. 本示例显示具有映射纹理的旋转立方体。 It uses specific broadcom functions to initialize the context. 它使用特定的Broadcom函数来初始化上下文。 For OSX i'v used the appropriate GLUT functions. 对于OSX,我使用了适当的GLUT功能。 I have split the init functions out for osx vs pi and the pi version works fine. 我已经为osx vs pi拆分了init函数,并且pi版本可以正常工作。 When I run the osx version, I always get a segfault on glDrawArrays() calls within redraw_scene(). 当我运行osx版本时,总是在redraw_scene()中的glDrawArrays()调用上出现段错误。 Normally the cause of this is incorrect vertex data. 通常,导致此问题的原因是错误的顶点数据。 But as mentioned the same code (in relation to setting up and drawing) works on the Pi. 但是如前所述,相同的代码(与设置和绘图有关)在Pi上起作用。 This is a trimmed version of the code which demonstrates the error. 这是演示错误的代码的精简版本。 Perhaps there is something I need do differently for regular OpenGL vs ES? 对于常规的OpenGL与ES,也许我需要做些不同的事情?

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GLUT/glut.h>

typedef struct {
   uint32_t screen_width;
   uint32_t screen_height;
   GLuint tex[6];
   GLfloat rot_angle_x_inc;
   GLfloat rot_angle_y_inc;
   GLfloat rot_angle_z_inc;
   GLfloat rot_angle_x;
   GLfloat rot_angle_y;
   GLfloat rot_angle_z;
   GLfloat distance;
   GLfloat distance_inc;
   char *tex_buf1;
   char *tex_buf2;
   char *tex_buf3;
} CUBE_STATE_T;

static CUBE_STATE_T _state, *state=&_state;

#define IMAGE_SIZE 128

const GLbyte quadx[6*4*3] = {
    -10, -10,  10, 10, -10,  10, -10,  10,  10, 10,  10,  10, -10, -10, -10, -10,  10, -10, 10, -10, -10, 10,  10, -10,
    -10, -10,  10, -10,  10,  10, -10, -10, -10, -10,  10, -10, 10, -10, -10, 10,  10, -10, 10, -10,  10, 10,  10,  10,
    -10,  10,  10, 10,  10,  10, -10,  10, -10, 10,  10, -10, -10, -10,  10, -10, -10, -10, 10, -10,  10, 10, -10, -10
};

const GLfloat texCoords[6 * 4 * 2] = {
    0.f,  0.f, 0.f,  1.f, 1.f,  0.f, 1.f,  1.f, 0.f,  0.f, 0.f,  1.f, 1.f,  0.f, 1.f,  1.f,
    0.f,  0.f, 0.f,  1.f, 1.f,  0.f, 1.f,  1.f, 0.f,  0.f, 0.f,  1.f, 1.f,  0.f, 1.f,  1.f,
    0.f,  0.f, 0.f,  1.f, 1.f,  0.f, 1.f,  1.f, 0.f,  0.f, 0.f,  1.f, 1.f,  0.f, 1.f,  1.f
};

void reshapeView(int width, int height);
void drawView();
void update_model();
void redraw_scene();

char * junk() {
    // dont load real images just make some random junk
    int image_sz = IMAGE_SIZE*IMAGE_SIZE*3;
    char * texture = (char*)malloc(image_sz);
    for (int x=0;x<image_sz;x++) {
        texture[x] = (char)x;
    }
    return texture;
}

void create() {
    char * myargv [1];
    int myargc = 1;
    myargv[0] = strdup("view");
    glutInit(&myargc, myargv);

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("window");
    glutFullScreen();

    state->tex_buf1 = junk();
    state->tex_buf2 = junk();
    state->tex_buf3 = junk();

    glGenTextures(6, &state->tex[0]);

    glBindTexture(GL_TEXTURE_2D, state->tex[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);

    glBindTexture(GL_TEXTURE_2D, state->tex[1]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);

    glBindTexture(GL_TEXTURE_2D, state->tex[2]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);

    glBindTexture(GL_TEXTURE_2D, state->tex[3]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);

    glBindTexture(GL_TEXTURE_2D, state->tex[4]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);

    glBindTexture(GL_TEXTURE_2D, state->tex[5]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);

    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glEnable(GL_TEXTURE_2D);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glEnable(GL_CULL_FACE);
    glMatrixMode(GL_MODELVIEW);

    glutReshapeFunc(reshapeView);
    glutDisplayFunc(drawView);
    glutIdleFunc(drawView);
}

void reshapeView(int width, int height) {
    state->screen_width = width;
    state->screen_height = height;

    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
    glViewport(0, 0, (GLsizei)state->screen_width, (GLsizei)state->screen_height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    float nearp = 1.0f;
    float farp = 500.0f;
    float hht = nearp * (float)tan(45.0 / 2.0 / 180.0 * 3.141592654);
    float hwd = hht * (float)state->screen_width / (float)state->screen_height;

    glFrustum(-hwd, hwd, -hht, hht, nearp, farp);

    glEnableClientState( GL_VERTEX_ARRAY );
    glVertexPointer( 3, GL_BYTE, 0, quadx );

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.f, 0.f, -50.f);

    state->rot_angle_x = 45.f;
    state->rot_angle_y = 30.f;
    state->rot_angle_z = 0.f;
    state->rot_angle_x_inc = 0.5f;
    state->rot_angle_y_inc = 0.5f;
    state->rot_angle_z_inc = 0.f;
    state->distance = 40.f;
}

void drawView() {
    update_model();
    redraw_scene();
    glutSwapBuffers();
}

void update_model() {
    glLoadIdentity();
    glTranslatef(0.f, 0.f, -state->distance);

    glRotatef(state->rot_angle_x, 1.0f, 0.f, 0.f);
    glRotatef(state->rot_angle_y, 0.f, 1.0f, 0.f);
    glRotatef(state->rot_angle_z, 0.f, 0.f, 1.0f);
}

void redraw_scene() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindTexture(GL_TEXTURE_2D, state->tex[0]);
    glRotatef(270.f, 0.f, 0.f, 1.f ); // front face normal along z axis
    // ZOMG segfaults here!!! 
    glDrawArrays( GL_TRIANGLE_STRIP, 0, 4);

    glBindTexture(GL_TEXTURE_2D, state->tex[1]);
    glRotatef(90.f, 0.f, 0.f, 1.f ); // back face normal along z axis
    glDrawArrays( GL_TRIANGLE_STRIP, 4, 4);

    glBindTexture(GL_TEXTURE_2D, state->tex[2]);
    glRotatef(90.f, 1.f, 0.f, 0.f ); // left face normal along x axis
    glDrawArrays( GL_TRIANGLE_STRIP, 8, 4);

    glBindTexture(GL_TEXTURE_2D, state->tex[3]);
    glRotatef(90.f, 1.f, 0.f, 0.f ); // right face normal along x axis
    glDrawArrays( GL_TRIANGLE_STRIP, 12, 4);

    glBindTexture(GL_TEXTURE_2D, state->tex[4]);
    glRotatef(270.f, 0.f, 1.f, 0.f ); // top face normal along y axis
    glDrawArrays( GL_TRIANGLE_STRIP, 16, 4);

    glBindTexture(GL_TEXTURE_2D, state->tex[5]);
    glRotatef(90.f, 0.f, 1.f, 0.f ); // bottom face normal along y axis
    glDrawArrays( GL_TRIANGLE_STRIP, 20, 4);
}

int main() {
    create();
    glutMainLoop();
    return 0;
}

CMake file... CMake文件...

cmake_minimum_required(VERSION 3.5)
project(jni)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -framework OpenGL -framework GLUT -Wno-deprecated -std=c++11")

set(SOURCE_FILES
    demo.cpp
)

add_executable(demo.bin ${SOURCE_FILES})

You should check the return value of glGetError() right before the segfault to determine what went wrong. 您应该在段glGetError()之前检查glGetError()的返回值,以确定出了什么问题。 The segfault may be caused by the driver or the graphics card not supporting certain types of OpenGL operations. 段错误可能是由驱动程序或图形卡不支持某些类型的OpenGL操作引起的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM