SDL2 / OpenGL程序在一台PC上运行,但在另一台PC上运行

时间:2018-01-14 17:22:47

标签: c linux opengl sdl-2

在我的台式电脑(Linux,OpenSuse 42.2,GraKa:Nvidia GTX 960)上,下面的程序运行正常。它打开一个窗口,其中三个轴X,Y,Z为红色,绿色,蓝色,您可以使用箭头按钮围绕轴移动相机。

在我的Linux笔记本电脑上(OpenSuse 42.3,Intel 5500上的Mesa DRI),该程序只显示黑屏但没有轴。 “glxgears”在笔记本电脑上运行良好,因此原则上OpenGL必须正常工作。

根据我的理解,我必须编写一些不是以便携方式编写的东西,某处依赖于我不应该拥有的东西。

我已经重新阅读了几个SDL2教程,但是我没有看到我遗漏或做错了什么。

如何查看我的程序是否可以移植,或者更好的我如何找到非便携式部件?

Compilerflags:

`sdl2-config --cflags` -I. -Isrc -g

Linkerflags:

`sdl2-config --libs` -lGLEW -lGL -lpthread -lm

main.c中:

#include <GL/glew.h>
#include <GL/glu.h>

#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>

#include "gl_common.h"


int width, height;
SDL_Surface* screen;
SDL_Surface* image;
int stop;
SDL_Window* window = NULL;
SDL_GLContext context;
int joy;
float wx, wy;
float ra;
float dx = 0.05;
float dy = 0.05;
float dr = 0.005;
Uint32 last_time;
static float c = M_PI / 180.0;

GLfloat cam_x, cam_y, cam_z;


GLuint program_object;
int is_initialised = 0;
GLfloat u_mvp[16];
GLint u_mvp_loc;


#define AL 1.4
#define AX 0.15
#define AY 0.05

GLfloat axis[] = {
  // x, red
  0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
  AL,  0.0, 0.0, 1.0, 0.0, 0.0,
  AL - AX, AY, 0.0, 1.0, 0.0, 0.0,
  AL - AX, -AY, 0.0, 1.0, 0.0, 0.0,
  AL,  0.0, 0.0, 1.0, 0.0, 0.0,
  AL - AX, 0.0, AY, 1.0, 0.0, 0.0,
  AL - AX, 0.0, -AY, 1.0, 0.0, 0.0,

  AL,  0.0, 0.0, 1.0, 0.0, 0.0,

  0.0, 0.0, 0.0, 1.0, 0.0, 0.0,

  // y, green
  0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
  0.0,  AL, 0.0, 0.0, 1.0, 0.0,
  0.0,  AL-AX, AY, 0.0, 1.0, 0.0,
  0.0,  AL-AX, -AY, 0.0, 1.0, 0.0,
  0.0,  AL, 0.0, 0.0, 1.0, 0.0,

  AY,  AL-AX, 0.0, 0.0, 1.0, 0.0,
  -AY,  AL-AX, 0.0, 0.0, 1.0, 0.0,

  0.0,  AL, 0.0, 0.0, 1.0, 0.0,

  0.0, 0.0, 0.0, 0.0, 1.0, 0.0,

  // z, blue
  0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
  0.0, 0.0, AL, 0.0, 0.0, 1.0,
  AY, 0.0, AL-AX, 0.0, 0.0, 1.0,
  -AY, 0.0, AL-AX, 0.0, 0.0, 1.0,

  0.0, 0.0, AL, 0.0, 0.0, 1.0,
  0.0, AY, AL-AX, 0.0, 0.0, 1.0,
  0.0, -AY, AL-AX, 0.0, 0.0, 1.0,
  0.0, 0.0, AL, 0.0, 0.0, 1.0,

  0.0, 0.0, 0.0, 0.0, 0.0, 1.0,

};
#define AXIS_SIZE  (sizeof(axis) / 6 / sizeof(GLfloat))


void quit(void) {
  SDL_GL_DeleteContext(context);
  SDL_DestroyWindow(window);
  SDL_Quit();
}


void draw() {
  GLfloat proj_mat[16];
  GLfloat model_mat[16];

  GLfloat model_mat2[16];
  GLfloat ctr[3];
  GLfloat eye[3];
  GLfloat up[3];

  glViewport(0, 0, width, height);
  mat_glu_perspective(proj_mat, 45.0f, (GLfloat)(width) / height, 0.1f, 100.0f);

#if 0
  printf("\n\nproj_mat\n");
  mat_show(u_mvp);
#endif

  eye[0] = cam_x;
  eye[1] = cam_y;
  eye[2] = cam_z;

  ctr[0] = 0.0;
  ctr[1] = 0.0;
  ctr[2] = 0.0;

  up[0] = 0.0;
  up[1] = 0.0;
  up[2] = 1.0;

  mat_glu_look_at(model_mat, eye, ctr, up);
  mat_mul(u_mvp, proj_mat, model_mat);

#if 0
  printf("\n\nu_mvp\n");
  mat_show(u_mvp);
#endif

  glUniformMatrix4fv(u_mvp_loc, 1, GL_FALSE, u_mvp);

  glClearColor ( 0.0, 0.0, 0.0, 1.0 );
  glClear(GL_COLOR_BUFFER_BIT);
  glClear(GL_DEPTH_BUFFER_BIT);
  //  glEnable(GL_CULL_FACE);
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);
  //  glCullFace(GL_FRONT_AND_BACK);
  glUseProgram(program_object);

  glVertexAttribPointer(0, 3, GL_FLOAT, GL_TRUE, 6 * sizeof(GLfloat), axis);
  glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, 6 * sizeof(GLfloat), axis+3);

  glEnableVertexAttribArray(0);
  glEnableVertexAttribArray(1);
  //  glDisableVertexAttribArray(2);
  //  glDisableVertexAttribArray(3);

  glDrawArrays(GL_LINE_STRIP, 0, AXIS_SIZE);


  SDL_GL_SwapWindow(window);
}

void init_gl(void) {
  const char* vsh;
  const char* fsh;

  GLuint vertex_shader;
  GLuint fragment_shader;
  GLint linked;

  vsh = load_file("shader.vsh");
  fsh = load_file("shader.fsh");

  fprintf(stderr, "vertex shader\n");
  vertex_shader = load_shader(GL_VERTEX_SHADER, vsh);
  fprintf(stderr, "fragment shader\n");
  fragment_shader = load_shader(GL_FRAGMENT_SHADER, fsh);

  program_object = glCreateProgram();
  if(program_object == 0) {
    printf("program object is 0\n");
    exit(-10);
  }

  glAttachShader(program_object, vertex_shader);
  glAttachShader(program_object, fragment_shader);

  glBindAttribLocation(program_object, 0, "a_pos");
  glBindAttribLocation(program_object, 1, "a_col");

  glLinkProgram(program_object);

  glGetProgramiv(program_object, GL_LINK_STATUS, &linked);

  if(!linked) {
    GLint info_len;

    glGetProgramiv(program_object, GL_INFO_LOG_LENGTH, &info_len);

    if(info_len > 1) {
      char* info_log = (char*)malloc(info_len);

      glGetProgramInfoLog(program_object, info_len, NULL, info_log);
      fprintf(stderr, "<%s>\n\n", info_log);
      free(info_log);
      exit(-1);
    }

    glDeleteProgram(program_object);

    exit(-11);
  }

  mat_identity(u_mvp);

  u_mvp_loc = glGetUniformLocation(program_object, "u_mvp");
}


void update_cam(void) {
  cam_x = ra*cos(c*wx)*cos(c*wy);
  cam_y = ra*sin(c*wx)*cos(c*wy);
  cam_z = ra*sin(c*wy);
}

void left(Uint32 d) {
    wx -= dx*d;
    if(wx < 0.0) wx += 360.0;
    update_cam();
}

void right(Uint32 d) {
    wx += dx*d;
    if(wx > 360.0) wx -= 360.0;
    update_cam();
}

void up(Uint32 d) {
  if(wy + dy*d < 90.0) {
    wy += dy*d;
    update_cam();
  }
}

void down(Uint32 d) {
  if(wy - dy*d > -90.0) {
    wy -= dy*d;
    update_cam();
  }
}

void zoom_in(Uint32 d) {
  if(ra > 1.0) ra -= dr*d;
  update_cam();
}

void zoom_out(Uint32 d) {
  if(ra < 30.0) ra += dr*d;
  update_cam();
}

static Uint32 time_diff(void) {
  Uint32 ret;
  Uint32 now = SDL_GetTicks();

  ret = now - last_time;
  last_time = now;

  return ret;
}

int main(int argc, char** argv) {
  SDL_Event event;
  int k;
  Uint32 d;

  atexit(quit);

  if(SDL_Init(SDL_INIT_VIDEO) < 0) {
    printf("couldn't init: %s\n", SDL_GetError());
    exit(-1);
  }

  width = 1024;
  height = 768;

  //Use OpenGL 3.2 core
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1);

  window = SDL_CreateWindow( "SDL OpenGL exaple", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL );
  if( window == NULL ) {
    printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
    exit(-2);
  }

  context = SDL_GL_CreateContext( window );
  if( context == NULL ) {
    printf( "OpenGL context could not be created! SDL Error: %s\n", SDL_GetError() );
    exit(-3);
  }

  glewExperimental = GL_TRUE;
  GLenum glewError = glewInit();
  if( glewError != GLEW_OK ) {
    printf( "Error initializing GLEW! %s\n", glewGetErrorString( glewError ) );
    exit(-4);
  }

  screen = SDL_GetWindowSurface( window );

  init_gl();
  is_initialised = 1;
  wx = 150.0;
  wy = 0.0;
  ra = 4.0;
  update_cam();

  d = time_diff();

  joy = 0;
  stop = 0;
  while(!stop) {
    while(SDL_PollEvent(&event)) {
      switch(event.type) {
      case SDL_QUIT:
do_exit:
    exit(-1);
    stop = 1;
    break;

      case SDL_KEYDOWN:
    switch(event.key.keysym.sym) {
    case SDLK_ESCAPE:
    case 'q':
      goto do_exit;
      break;

    case SDLK_LEFT:
      joy |= 4;
      break;

    case SDLK_RIGHT:
      joy |= 8;
      break;

    case SDLK_UP:
      joy |= 1;
      break;

    case SDLK_DOWN:
      joy |= 2;
      break;

    case SDLK_PAGEUP:
      joy |= 16;
      break;

    case SDLK_PAGEDOWN:
      joy |= 32;
      break;
    }
    break;

      case SDL_KEYUP:
    switch(event.key.keysym.sym) {
    case SDLK_LEFT:
      joy &= ~4;
      break;

    case SDLK_RIGHT:
      joy &= ~8;
      break;

    case SDLK_UP:
      joy &= ~1;
      break;

    case SDLK_DOWN:
      joy &= ~2;
      break;

    case SDLK_PAGEUP:
      joy &= ~16;
      break;

    case SDLK_PAGEDOWN:
      joy &= ~32;
      break;
    }
    break;
      }
    }

    d = time_diff();

    if(joy & 1) up(d);
    if(joy & 2) down(d);
    if(joy & 4) left(d);
    if(joy & 8) right(d);
    if(joy & 16) zoom_in(d);
    if(joy & 32) zoom_out(d);

    draw();
  }

  return 0;
}

gl_common.c:

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

#include "gl_common.h"


// Matrizen werden spaltenweise angegeben
#define IX(x, y)     ((y) + ((x) * 4))


void mat_show(GLfloat m[]) {
  int x, y, i;

  for(y = 0; y < 4; y++) {
    for(x = 0; x < 4; x++) {
      i = IX(x, y);

      printf("%8.5f  ", m[i]);
    }
    printf("\n");
  }
}


GLfloat vec_len(GLfloat x[]) {
  return sqrt((x[0]) * (x[0]) + (x[1]) * (x[1]) + (x[2]) * (x[2]));
}


void vec_norm(GLfloat x[]) {
  GLfloat l = vec_len(x);

  x[0] /= l;
  x[1] /= l;
  x[2] /= l;
}


void vec_copy(GLfloat dest[], const GLfloat src[]) {
  dest[0] = src[0];
  dest[1] = src[1];
  dest[2] = src[2];
}


void vec_diff(GLfloat res[], const GLfloat a[], const GLfloat b[]) {
  res[0] = a[0] - b[0];
  res[1] = a[1] - b[1];
  res[2] = a[2] - b[2];
}


void vec_cross_product(GLfloat res[], const GLfloat a[], const GLfloat b[]) {
  res[0] = a[1]*b[2] - b[1]*a[2];
  res[1] = a[2]*b[0] - b[2]*a[0];
  res[2] = a[0]*b[1] - b[0]*a[1];
}


GLfloat vec_scalar_product(const GLfloat a[], const GLfloat b[]) {
  return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
}


void mat_identity(GLfloat res[]) {
  res[0] = 1.0f;
  res[1] = 0.0f;
  res[2] = 0.0f;
  res[3] = 0.0f;

  res[4] = 0.0f;
  res[5] = 1.0f;
  res[6] = 0.0f;
  res[7] = 0.0f;

  res[8] = 0.0f;
  res[9] = 0.0f;
  res[10] = 1.0f;
  res[11] = 0.0f;

  res[12] = 0.0f;
  res[13] = 0.0f;
  res[14] = 0.0f;
  res[15] = 1.0f;
}


void mat_mul(GLfloat res[], const GLfloat a[], const GLfloat b[]) {
  GLfloat tmp;
  int x, y, i;

  for(y = 0; y < 4; y++) {
    for(x = 0; x < 4; x++) {

      tmp = 0.0f;
      for(i = 0; i < 4; i++) {
    tmp += a[IX(i, y)] * b[IX(x, i)];
      }

      res[IX(x, y)] = tmp;
    }
  }
}


void mat_glu_look_at(GLfloat res[],
             const GLfloat eye[],
             const GLfloat center[],
             const GLfloat up[])
{
  GLfloat f[3]; // forward
  GLfloat upc[3]; // up copy
  GLfloat s[3]; // side
  GLfloat u[3]; // up

  GLfloat tmp[16];
  GLfloat trl[16];

  vec_diff(f, center, eye);
  vec_norm(f);
  vec_copy(upc, up);
  vec_cross_product(s, f, upc);
  vec_cross_product(u, s, f);
  vec_norm(s);
  vec_norm(u);

  tmp[0] = s[0];
  tmp[1] = u[0];
  tmp[2] = -f[0];
  tmp[3] = 0.0f;

  tmp[4] = s[1];
  tmp[5] = u[1];
  tmp[6] = -f[1];
  tmp[7] = 0.0f;

  tmp[8] = s[2];
  tmp[9] = u[2];
  tmp[10] = -f[2];
  tmp[11] = 0.0f;

  tmp[12] = 0.0f;
  tmp[13] = 0.0f;
  tmp[14] = 0.0f;
  tmp[15] = 1.0f;

  mat_identity(trl);
  trl[12] = -eye[0];
  trl[13] = -eye[1];
  trl[14] = -eye[2];

  mat_mul(res, tmp, trl);
}


void mat_glu_perspective(GLfloat res[], GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) {
  GLfloat sine, cotangent, deltaZ;
  GLfloat radians = fovy / 2 * 3.1415926536 / 180;

  deltaZ = zFar - zNear;
  sine = sin(radians);
  if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
    return;
  }
  cotangent = cos(radians) / sine;

  res[0] = cotangent / aspect;
  res[1] = 0.0;
  res[2] = 0.0;
  res[3] = 0.0;

  res[4] = 0.0;
  res[5] = cotangent;
  res[6] = 0.0;
  res[7] = 0.0;

  res[8] = 0.0;
  res[9] = 0.0;
  res[10] = -(zFar + zNear) / deltaZ;
  res[11] = -1.0;

  res[12] = 0.0;
  res[13] = 0.0;
  res[14] = -2 * zNear * zFar / deltaZ;
  res[15] = 0.0;
}


///////////


GLuint load_shader(GLenum type, const char* src) {
  GLuint shader;
  GLint compiled;

  shader = glCreateShader(type);

  if(shader == 0) return 0;

  glShaderSource(shader, 1, &src, NULL);
  glCompileShader(shader);

  glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);

  if(!compiled) {
    GLint info_len;

    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len);

    if(info_len > 1) {
      char* info_log = (char*)malloc(info_len);

      glGetShaderInfoLog(shader, info_len, NULL, info_log);
      fprintf(stderr, "<<<\n%s\n>\n\n", info_log);
      free(info_log);
    }

    glDeleteShader(shader);
    exit(-1);

    return 0;
  }

  return shader;
}


const char* load_file(const char* fname) {
  FILE* fd;
  const char* ret;
  size_t len;

  fd = fopen(fname, "rb");
  if(fd == NULL) {
    fprintf(stderr, "could not load <%s>\n", fname);

    return NULL;
  }

  fseek(fd, -1, SEEK_END);
  len = ftell(fd);
  rewind(fd);

  ret = (const char*)malloc(len + 1);
  if(ret == NULL) {
    fclose(fd);

    fprintf(stderr, "could not get memory <%i>\n", len);
    fclose(fd);

    return NULL;
  }

  fread((void*)ret, 1, len, fd);
  ((char*)ret)[len] = 0;

  //  fprintf(stdout, "<%s>\n\n", ret);

  return ret;
}

gl_common.h:

#ifndef GL_COMMON_H
#define GL_COMMON_H 1

#include <GL/glew.h>
#include <GL/gl.h>

#include <stdio.h>

#define QWE fprintf(stderr, "%s, %i\n", __FILE__, __LINE__)


typedef struct {
  GLuint program_object;
  int width;
  int height;
  GLfloat cam_x;
  GLfloat cam_y;
  GLfloat cam_z;
} UserData;


extern GLuint texbase[];


extern GLuint load_shader(GLenum type, const char* src);

extern const char* load_file(const char* fname);

/* math stuff */

extern GLfloat vec_len(GLfloat x[]);

extern void vec_norm(GLfloat x[]);

extern void vec_copy(GLfloat dest[], const GLfloat src[]);

extern void vec_diff(GLfloat res[], const GLfloat a[], const GLfloat b[]);

extern void vec_cross_product(GLfloat res[], const GLfloat a[], const GLfloat b[]);

extern GLfloat vec_scalar_product(const GLfloat a[], const GLfloat b[]);


extern void mat_mul(GLfloat res[], const GLfloat a[], const GLfloat b[]);

extern void mat_identity(GLfloat res[]);

extern void mat_glu_look_at(GLfloat res[],
                const GLfloat eye[],
                const GLfloat center[],
                const GLfloat up[]);

extern void mat_glu_perspective(GLfloat res[], GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar);

extern void mat_show(GLfloat m[]);


#endif

shader.fsh:

#version 130
precision mediump float;

varying vec4 v_col;

void main()
{
  gl_FragColor = v_col;
}

shader.vsh:

#version 130
uniform mat4 u_mvp;

attribute vec4 a_pos;
attribute vec4 a_col;

varying vec4 v_col;

const float c_zero = 0.0;
const float c_one = 1.0;

void main()
{
  gl_Position = u_mvp * a_pos;
  v_col = a_col;
}

0 个答案:

没有答案