C语言 OpenGL,物体移动时 Flink

frebpwbc  于 6个月前  发布在  Flink
关注(0)|答案(2)|浏览(80)

我是OpenGL的新手,我正在尝试使用mouse移动对象。我正在使用OpenGL 4.4 Core ProfileMinGW 32freeGLUTGLUGLEW,用C编程。
该程序绘制一个六边形GL_LINE_LOOP和颜色(0.5, 0.5, 0.5, 1.0)
问题是当我用鼠标移动它时,对象会轻轻 Flink ,颜色会变成深灰色。当用颜色(1.0, 1.0, 1.0, 1.0)绘图时也会 Flink ,但它不太可见。
我尝试使用wglSwapIntervalEXT()更改交换间隔,但它只接受值01 .我还尝试启用三重缓冲和“等待垂直同步”我的图形卡参数.更改这三个参数并不能解决问题.
代码非常简单,顶点着色器采用与平移对应的Uniform vectort来应用于对象。
顶点着色程序:

#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,但 Flink 甚至发生。
draw函数:

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*常量中。左键单击并移动鼠标可以移动对象。

izkcnapc

izkcnapc1#

从你的描述中,我猜你已经启用了纹理,但是你没有提供任何纹理信息,所以,在绘制立方体之前调用glDisable(GL_TEXTURE_2D);

sycxhyv7

sycxhyv72#

正如genpfault所建议的,这是一个硬件性能问题。我已经在75 Hz的LCD上尝试过相同的程序,响应时间为1 ms。
它仍然 Flink 一点,但它是一个很难察觉。

相关问题