您将如何为对象产生滚动效果?
How would you produce a scrolling effect for an object?
我在 Visual C++ 中使用 OpenGL,我正在使用 VBO 和 VAO 显示一个矩形,我有一个基本的顶点着色器和片段着色器来为对象应用颜色和位置。
我想产生一个对象的滚动效果,直到我按下
Esc 键。最好的方法是什么?
我知道您可以将模型、视图和投影矩阵提供给着色器以执行对对象的更改。特别是用于执行转换的模型矩阵。我可以更改对象的位置并旋转它,但我不确定如何产生移动对象或旋转直到按下键的连续或滚动效果。
到目前为止我的代码:
GLfloat vb_data[] = {
-0.25f, 0.25f, 0.0f, // Top-left
0.25f, 0.25f, 0.0f, // Top-right
0.25f, -0.25f, 0.0f, // Bottom-right
-0.25f, -0.25f, 0.0f // Bottom-left
};
glGenBuffers(1, &vbo_ID);
glBindBuffer(GL_ARRAY_BUFFER, vbo_ID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vb_data), vb_data, GL_DYNAMIC_DRAW);
GLfloat incre = 0.01f;
glClear(GL_COLOR_BUFFER_BIT);
while (1){
glm::mat4 trans = glm::mat4(1.0f);
glm::mat4 transBar = glm::translate(trans, glm::vec3(0.2f, 0.2f, 1.0f));
glm::mat4 MVP = transBar;
glUseProgram(pgID);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glBindBuffer(GL_ARRAY_BUFFER, vbo_ID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
glDrawArrays(GL_QUADS,0, 4);
glDisableVertexAttribArray(0);
SwapBuffers(g_pOpenGLWindow->hDC);
}
but I am not sure how to produce a continuous or a scrolling effect of moving the object or rotating ...
为了生成平滑的运动(平移或旋转),模型矩阵的平移或旋转部分必须在每一帧中分别改变少量角度。这可以通过在每一帧中增加一小步的控制变量来实现。必须通过在每一帧中使用此控制变量来重新计算模型矩阵。
参见以下伪代码中的概念:
translate_x = 0;
angle = 0;
while (1)
model_matrix = translate(translate_x, 0, 0) * roatateX(angle)
translate_x = translate_x + step_x
angle = angle + step_angle
尝试使用以下代码并调整参数,以获得您需要的效果:
float angle = 0.0f;
float step_ang = 1.0f;
float trans_x = -0.5f;
float step_x = 0.01f;
bool move_forward = true;
while (1)
{
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(trans_x, 0.2f, 1.0f));
model = glm::rotate(model, glm::radians(angle), glm::vec3(0.0f, 0.0f, 1.0f));
angle += step_ang;
trans_x += move_forward ? step_x : -step_x;
move_forward = move_forward ? trans_x < 0.5f : trans_x <= -0.5f;
glm::mat4 MVP = model;
.....
... till a key is pressed.
由于问题被标记为 winapi,我假设您已经为成员 lpfnWndProc
.
初始化了一个 WNDCLASSEX
data structure and that you have set the WindowProc callback function
你必须执行 WM_KEYDOWN message event in the window callback function and to check if the Esc (VK_ESCAPE
) 按下:
全局变量:
bool esc_pressed = false;
回调函数:
LRESULT CALLBACK WindowProcedure( HWND hWnd, unsigned int msg, WPARAM wparam, LPARAM lparam )
{
switch(msg)
{
case WM_KEYDOWN:
if ( wparam == VK_ESCAPE )
esc_pressed = true;
break;
// other messages
// ...
}
return DefWindowProc( hWnd, msg, wparam, lparam );
}
此外,您必须在主循环中处理 window 消息。请参见 GetMessage
function and DispatchMessage
函数。
而不是
while (1)
{
.....
}
你必须
MSG msg;
while( GetMessage( &msg, 0, 0, 0 ) )
{
DispatchMessage( &msg );
.....
}
我在 Visual C++ 中使用 OpenGL,我正在使用 VBO 和 VAO 显示一个矩形,我有一个基本的顶点着色器和片段着色器来为对象应用颜色和位置。
我想产生一个对象的滚动效果,直到我按下 Esc 键。最好的方法是什么?
我知道您可以将模型、视图和投影矩阵提供给着色器以执行对对象的更改。特别是用于执行转换的模型矩阵。我可以更改对象的位置并旋转它,但我不确定如何产生移动对象或旋转直到按下键的连续或滚动效果。
到目前为止我的代码:
GLfloat vb_data[] = {
-0.25f, 0.25f, 0.0f, // Top-left
0.25f, 0.25f, 0.0f, // Top-right
0.25f, -0.25f, 0.0f, // Bottom-right
-0.25f, -0.25f, 0.0f // Bottom-left
};
glGenBuffers(1, &vbo_ID);
glBindBuffer(GL_ARRAY_BUFFER, vbo_ID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vb_data), vb_data, GL_DYNAMIC_DRAW);
GLfloat incre = 0.01f;
glClear(GL_COLOR_BUFFER_BIT);
while (1){
glm::mat4 trans = glm::mat4(1.0f);
glm::mat4 transBar = glm::translate(trans, glm::vec3(0.2f, 0.2f, 1.0f));
glm::mat4 MVP = transBar;
glUseProgram(pgID);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glBindBuffer(GL_ARRAY_BUFFER, vbo_ID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
glDrawArrays(GL_QUADS,0, 4);
glDisableVertexAttribArray(0);
SwapBuffers(g_pOpenGLWindow->hDC);
}
but I am not sure how to produce a continuous or a scrolling effect of moving the object or rotating ...
为了生成平滑的运动(平移或旋转),模型矩阵的平移或旋转部分必须在每一帧中分别改变少量角度。这可以通过在每一帧中增加一小步的控制变量来实现。必须通过在每一帧中使用此控制变量来重新计算模型矩阵。
参见以下伪代码中的概念:
translate_x = 0;
angle = 0;
while (1)
model_matrix = translate(translate_x, 0, 0) * roatateX(angle)
translate_x = translate_x + step_x
angle = angle + step_angle
尝试使用以下代码并调整参数,以获得您需要的效果:
float angle = 0.0f;
float step_ang = 1.0f;
float trans_x = -0.5f;
float step_x = 0.01f;
bool move_forward = true;
while (1)
{
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(trans_x, 0.2f, 1.0f));
model = glm::rotate(model, glm::radians(angle), glm::vec3(0.0f, 0.0f, 1.0f));
angle += step_ang;
trans_x += move_forward ? step_x : -step_x;
move_forward = move_forward ? trans_x < 0.5f : trans_x <= -0.5f;
glm::mat4 MVP = model;
.....
... till a key is pressed.
由于问题被标记为 winapi,我假设您已经为成员 lpfnWndProc
.
WNDCLASSEX
data structure and that you have set the WindowProc callback function
你必须执行 WM_KEYDOWN message event in the window callback function and to check if the Esc (VK_ESCAPE
) 按下:
全局变量:
bool esc_pressed = false;
回调函数:
LRESULT CALLBACK WindowProcedure( HWND hWnd, unsigned int msg, WPARAM wparam, LPARAM lparam )
{
switch(msg)
{
case WM_KEYDOWN:
if ( wparam == VK_ESCAPE )
esc_pressed = true;
break;
// other messages
// ...
}
return DefWindowProc( hWnd, msg, wparam, lparam );
}
此外,您必须在主循环中处理 window 消息。请参见 GetMessage
function and DispatchMessage
函数。
而不是
while (1)
{
.....
}
你必须
MSG msg;
while( GetMessage( &msg, 0, 0, 0 ) )
{
DispatchMessage( &msg );
.....
}