OpenGL,移动时对象闪烁

时间:2016-12-15 12:09:31

标签: c opengl

我是OpenGL的新手,我正在尝试使用mouse移动对象。我正在使用 OpenGL 4.4核心配置文件 MinGW32 freeGLUT GLU GLEW ,用C编程。

该程序使用GL_LINE_LOOP和颜色(0.5, 0.5, 0.5, 1.0)绘制六边形。

问题是当我使用鼠标移动它时,对象轻轻闪烁,颜色变为深灰色。使用颜色(1.0, 1.0, 1.0, 1.0)进行绘制时也会出现闪烁,但 可见。

我尝试使用wglSwapIntervalEXT()更改交换间隔,但它只接受值01。我还试图启用三重缓冲和我的显卡的“等待Vsync”参数。改变这三个参数并不能解决问题。

代码非常简单,顶点着色器采用与要应用于对象的平移相对应的均匀向量 t

顶点着色器程序:

#version 440 core
in vec3 vertex_position;
uniform vec3 vertex_color;
uniform vec4 t;
uniform mat4 matrix;

out vec4 color;

vec4 vp;

void main() {
  color = vec4(vertex_color,1.0);
  vp = matrix * vec4(vertex_position,1.0);
  gl_Position = vec4(vp.x+t.x, vp.y+t.y, vp.z+t.z, vp.w+t.w);
}

片段着色器程序:

#version 440 core
in vec4 color;
void main()
{
  gl_FragColor = color;
}

绘制函数非常简单,我有一个定时器函数,每16 ms调用glutPostRedisplay(),以获得60 FPS。我试过没有定时器功能,它增加了FPS,但是甚至发生了闪烁。

绘制功能:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

static int init = 1;
if(init == 1) {
  glUseProgram(shader_program_core);
  matrixloc = glGetUniformLocation(shader_program_core,"matrix");
  // Load the matrix into the vertex shader:
  glUniformMatrix4fv(matrixloc, 1, GL_FALSE, PMVmatrix);
  colorloc = glGetUniformLocation(shader_program_core,"vertex_color");
  // translation localisation:
  tloc = glGetUniformLocation(shader_program_core,"t");

  init = 0;
}

glUniform3f(colorloc,0.5,0.5,0.5);
// translation:
glUniform4f(tloc,tx,ty,tz,tw);

glBindVertexArray(vao);

glDrawArrays(GL_LINE_LOOP, 0, 6);

glBindVertexArray(0);


glutSwapBuffers();

显示问题的完整源代码在这里:

#define GLEW_STATIC

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include <math.h>
#include <time.h>

// coordinates of the hexagon:
GLfloat hexagon[18];

GLuint vao;
GLuint vbo;

// translations:
GLfloat tx = 0.0;
GLfloat ty = 0.0;
GLfloat tz = 0.0;
GLfloat tw = 0.0;

// window dimensions:
GLint width;
GLint height;

int window;

// coordinates of clicked point
int clicked_x;
int clicked_y;

// set to 1 if clicked down:
int clicked_down = 0;




/////////////////////////////////////////////////////////
//
// Shader programs for core profile:
//

const char * vsprog_core =
"#version 440 core\n"
"in vec3 vertex_position;\n"
"uniform vec3 vertex_color;\n"
"uniform vec4 t;\n"
"uniform mat4 matrix;\n"
" \n"
"out vec4 color;\n"
" \n"
"vec4 vp;\n"
" \n"
"void main() {\n"
"  color = vec4(vertex_color,1.0);\n"
"  vp = matrix * vec4(vertex_position,1.0);\n"
"  gl_Position = vec4(vp.x+t.x, vp.y+t.y, vp.z+t.z, vp.w+t.w);\n"
"}\n";

const char * fsprog_core = 
"#version 440 core\n"
"in vec4 color;\n"
"void main()\n"
"{\n"
"  gl_FragColor = color;\n"
"}\n";

// uniforms locations:
GLint tloc;
GLint colorloc;
GLint matrixloc;

GLuint shader_program_core;

GLfloat PMVmatrix[16] = {
0.500000,  0.000000,  0.000000,  0.000000,
0.000000,  0.500000,  0.000000,  0.000000,
0.000000,  0.000000,  0.500000,  0.000000,
0.000000,  0.000000,  0.000000,  1.000000
};






void Draw()
{ 
    int i,j;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);



    static int init = 1;
    if(init == 1) {
      glUseProgram(shader_program_core);
      matrixloc = glGetUniformLocation(shader_program_core,"matrix");
      // Load the matrix into the vertex shader:
      glUniformMatrix4fv(matrixloc, 1, GL_FALSE, PMVmatrix);
      colorloc = glGetUniformLocation(shader_program_core,"vertex_color");
      // translation localisation:
      tloc = glGetUniformLocation(shader_program_core,"t");

      init = 0;
    }

    glUniform3f(colorloc,0.5,0.5,0.5);
    // translation:
    glUniform4f(tloc,tx,ty,tz,tw);

    glBindVertexArray(vao);

    glDrawArrays(GL_LINE_LOOP, 0, 6);

    glBindVertexArray(0);



    glutSwapBuffers();

    //glutPostRedisplay();
}






void onMouseClick(int button, int state, int x, int y) {
  if(state == GLUT_UP && button == GLUT_LEFT_BUTTON) clicked_down = 0;
  if(state == GLUT_DOWN && button == GLUT_LEFT_BUTTON) {
    clicked_down = 1;

    clicked_x = x;
    clicked_y = y;
  }
}



void onMouseMove(int x, int y) {
  int i,j;
  if(clicked_down == 1) {

    // compute x coordinate of the clicked point from the clicked x pixel:
    GLfloat x1 = (clicked_x)*2.0/width - 1.0;

    // compute x coordinate of the actual point from the actual x pixel:
    GLfloat x2 = (x)*2.0/width - 1.0;

    // compute y coordinate of the clicked point from the clicked y pixel:
    GLfloat y1 = (clicked_y)*2.0/height - 1.0;

    // compute y coordinate of the actual point from the actual y pixel:
    GLfloat y2 = (y)*2.0/height - 1.0;

    tx += x2 - x1;
    ty += y1 - y2;


    // save actual coordinates as previous ones, for the next move:
    clicked_x = x;
    clicked_y = y;
  }
}

void timer( int value )
{
    glutPostRedisplay();
    glutTimerFunc( 16, timer, 0 );
}




int main( int argc, char *argv[ ], char *envp[ ] )
{ 
  int i,j;


  glutInitContextVersion(4, 4);
  glutInitContextFlags(GLUT_FORWARD_COMPATIBLE/* | GLUT_DEBUG*/);
  glutInitContextProfile(GLUT_CORE_PROFILE);


  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  glutInitWindowSize(640,480);
  window = glutCreateWindow("Program");
  //glutFullScreen();

  width = glutGet(GLUT_WINDOW_WIDTH);
  height = glutGet(GLUT_WINDOW_HEIGHT);

  // get version info
  const GLubyte* renderer;
  const GLubyte* version;



  ///////////////////////////////////////////////////////////////////////
  //
  // start GLEW extension handler
  //

  glewExperimental = GL_TRUE;
  GLenum err = glewInit();
  if (GLEW_OK != err)
  {
    fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
    return(-1);
  }
  fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));




  // get version info
  renderer = glGetString(GL_RENDERER); // get renderer string
  version = glGetString(GL_VERSION); // version as a string
  printf("\nRenderer: %s", renderer);
  printf("\nOpenGL version supported %s", version);
  fflush(stdout);


  // tell GL to only draw onto a pixel if the shape is closer to the viewer
  glEnable(GL_DEPTH_TEST); // enable depth-testing
  glDepthFunc(GL_LESS); // depth-testing interprets a smaller value as "closer"



  //////////////////////////////////////////////////////////
  //
  // Shaders:
  //
  GLint params;
  GLint len;

  GLuint vscore = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(vscore, 1, &vsprog_core, NULL);
  glCompileShader(vscore);
  glGetShaderiv(vscore,GL_COMPILE_STATUS,&params);
  if(params == GL_FALSE) {
    GLchar log[100000];
    glGetShaderInfoLog(vscore,100000,&len,log);
    printf("\n\n%s\n\n",log);
    return(-1);
  }

  GLuint fscore = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fscore, 1, &fsprog_core, NULL);
  glCompileShader(fscore);
  glGetShaderiv(fscore,GL_COMPILE_STATUS,&params);
  if(params == GL_FALSE) {
    GLchar log[100000];
    glGetShaderInfoLog(fscore,100000,&len,log);
    printf("\n\n%s\n\n",log);
    return(-1);
  }

  shader_program_core = glCreateProgram();
  glAttachShader(shader_program_core, fscore);
  glAttachShader(shader_program_core, vscore);

  glLinkProgram(shader_program_core);
  glGetProgramiv(shader_program_core,GL_LINK_STATUS,&params);
  if(params == GL_FALSE) {
    GLchar log[100000];
    glGetProgramInfoLog(shader_program_core,100000,&len,log);
    printf("\n\n%s\n\n",log);
    fflush(stdout);
    return(-1);
  }

  //
  //////////////////////////////////////////////////////////




  //////////////////////////////////////////////////////////
  //
  // Compute coordinates of the hexagon:
  //
  hexagon[0] = cos(0.0*M_PI/3.0 + M_PI/6.0)*500.0/width;
  hexagon[1] = sin(0.0*M_PI/3.0 + M_PI/6.0)*500.0/height;
  hexagon[2] = 0.0;
  hexagon[3] = cos(1.0*M_PI/3.0 + M_PI/6.0)*500.0/width;
  hexagon[4] = sin(1.0*M_PI/3.0 + M_PI/6.0)*500.0/height;
  hexagon[5] = 0.0;
  hexagon[6] = cos(2.0*M_PI/3.0 + M_PI/6.0)*500.0/width;
  hexagon[7] = sin(2.0*M_PI/3.0 + M_PI/6.0)*500.0/height;
  hexagon[8] = 0.0;
  hexagon[9] = cos(3.0*M_PI/3.0 + M_PI/6.0)*500.0/width;
  hexagon[10] = sin(3.0*M_PI/3.0 + M_PI/6.0)*500.0/height;
  hexagon[11] = 0.0;
  hexagon[12] = cos(4.0*M_PI/3.0 + M_PI/6.0)*500.0/width;
  hexagon[13] = sin(4.0*M_PI/3.0 + M_PI/6.0)*500.0/height;
  hexagon[14] = 0.0;
  hexagon[15] = cos(5.0*M_PI/3.0 + M_PI/6.0)*500.0/width;
  hexagon[16] = sin(5.0*M_PI/3.0 + M_PI/6.0)*500.0/height;
  hexagon[17] = 0.0;


  // VAO:
  glGenVertexArrays(1, &(vao));
  glBindVertexArray(vao);

  // VBO:
  glGenBuffers(1,&(vbo));
  glBindBuffer(GL_ARRAY_BUFFER,vbo);
  glBufferData(GL_ARRAY_BUFFER, 18 * sizeof(GLfloat), hexagon, GL_STATIC_DRAW);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0*sizeof(GLfloat), (GLvoid*)0);
  glEnableVertexAttribArray(0);
  glBindBuffer(GL_ARRAY_BUFFER,0);

  // End VAO:
  glBindVertexArray(0);



  glutMouseFunc(onMouseClick);
  glutMotionFunc(onMouseMove);
  glutDisplayFunc(Draw);
  glutTimerFunc(0,timer,0);

  glutMainLoop();

  return 0;
}

着色器以两个char*常量定义。左键单击并移动鼠标可以移动对象。

1 个答案:

答案 0 :(得分:0)

根据您的描述,我的(疯狂)猜测是您启用了纹理,但您没有提供任何纹理信息。 因此,在绘制多维数据集之前,只需调用ActivityManager manager = (ActivityManager) getApplicationContext() .getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> runningTasks = manager.getRunningTasks(1); String mPackageName=""; if(Build.VERSION.SDK_INT > 20){ mPackageName= manager.getRunningAppProcesses().get(0).processName; } else{ mPackageName = manager.getRunningTasks(1).get(0).topActivity.getPackageName(); } if (runningTasks != null && runningTasks.size() > 0) { ComponentName topActivity = runningTasks.get(0).topActivity; if (!mPackageName.equals(getPackageName())) { isTopActivityFromApp = false; } else { if (mPackageName.equals(getPackageName()) && topActivity.getClassName().equals(PaySendActivity.class.getName()) && !isTopActivityFromApp) { // Other Application is opened isTopActivityFromApp = true; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (WalletSharedPrefs.INSTANCE.isPatternLockEnabled(getApplicationContext())) { showprompt(); } } } } 即可。