gpt4 book ai didi

c - OpenGL,物体移动时闪烁

转载 作者:行者123 更新时间:2023-11-30 16:52:35 24 4
gpt4 key购买 nike

我是 OpenGL 的新手,我正在尝试使用 mouse 移动对象。我正在使用 OpenGL 4.4 Core ProfileMinGW32freeGLUTGLUGLEW strong>,用 C 语言编程。

程序用 GL_LINE_LOOP 绘制一个六边形和颜色(0.5, 0.5, 0.5, 1.0)

问题是当我使用鼠标移动它时,该对象轻轻闪烁,颜色变为深灰色。使用颜色(1.0, 1.0, 1.0, 1.0)绘图时也会发生闪烁。 ,但它不太可见。

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

代码非常简单,顶点着色器采用与应用于对象的平移相对应的统一 vector 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;
}

绘图函数非常简单,我有一个计时器函数,调用 glutPostRedisplay()每 16 毫秒一次,以获得大约 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* 中定义常数。单击左键并移动鼠标可以移动对象。

最佳答案

根据您的描述,我(疯狂)猜测您已启用纹理,但没有提供任何纹理信息。因此,只需在绘制立方体之前调用 glDisable(GL_TEXTURE_2D); 即可。

关于c - OpenGL,物体移动时闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41163852/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com