- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在我的 GLUT/OpenGL 练习中,我必须加载 3 个不同的对象,我给它们一个 file.m。这是通过读取该文件、创建列表并最终调用 glCallList() 来完成的。选择一个对象后,我必须如何启用平移和旋转对象的可能性。所以我有:
#define OBJECTS 3
float objAngle[OBJECTS], objAxis[OBJECTS][3], objWAxis[OBJECTS][3], objPos[OBJECTS][3], objWPos[OBJECTS][3];
float objScale[OBJECTS] = {1.0, 1.0, 1.0};
float translation_var[OBJECTS][3];
translation_var[i][0] = translation_var[i][1] = translation_var[i][2] = 0.0;
并且都初始化为0.0
此外我还有:
float ocsmatrix[OBJECTS][16];
float wcsmatrix[OBJECTS][16];
初始化为:
for(i = 0; i < OBJECTS; i++) {
glGetFloatv(GL_MODELVIEW_MATRIX, ocsmatrix[i]);
glGetFloatv(GL_MODELVIEW_MATRIX, wcsmatrix[i]);
}
这是我的键盘功能的一部分:
void keyboard (unsigned char key, int x, int y) {
float* pos = NULL;
float step = 0.0;
if( mode == MODE_CHANGE_EYE_POS ) {
}
else if( mode == MODE_CHANGE_REFERENCE_POS ) {
pos = camC;
step = 0.1;
}
else if( mode == MODE_CHANGE_UP_POS ) {
pos = camU;
step = 0.1;
}
else if( mode == MODE_CHANGE_LIGHT_POS ) {
pos = lightPos;
step = 1.0;
}
else if( mode == MODE_ROTATE_OBJECT ) {
}
if( pos != NULL ) {
if( key == 'x' )
pos[0] += step;
else if( key == 'X' )
pos[0] -= step;
else if( key == 'y' )
pos[1] += step;
else if( key == 'Y' )
pos[1] -= step;
else if( key == 'z' )
pos[2] += step;
else if( key == 'Z' )
pos[2] -= step;
}
if (key == 'l') {
char path[32];
printf("Digitare file.m da caricare: data/file.m\n");
scanf("%s", path);
loadMeshModel(path); /* carico il file.m digitato da console */
}
if (key == '0') {
selected_object = 1;
printf("SELEZIONATO OGGETTO 0\n");
}
if (key == '1') {
selected_object = 2;
printf("SELEZIONATO OGGETTO 1\n");
}
if (key == '2') {
selected_object = 3;
printf("SELEZIONATO OGGETTO 2\n");
}
// gestione trasformazioni OCS
if(key == 'o') {
mode = MODE_TRANSLATE_OCS;
printf("TRASLAZIONE OCS ATTIVA\n");
}
else if(key == 'O') {
mode = MODE_ROTATE_OCS;
printf("ROTAZIONE OCS ATTIVA\n");
}
// gestione trasformazioni WCS
if(key == 'w') {
mode = MODE_TRANSLATE_WCS;
printf("TRASLAZIONE WCS ATTIVA\n");
}
else if(key == 'W') {
mode = MODE_ROTATE_WCS;
printf("ROTAZIONE WCS ATTIVA\n");
}
if(key == 'q') {
mode = MODE_QUADRICS;
}
else if(key == 'Q') {
mode = MODE_MODELS;
}
if( key == 27 ) //esc
exit(1);
if(selected_object > -1) {
if(mode == MODE_TRANSLATE_OCS) {
step = 0.1;
}
else if(mode == MODE_TRANSLATE_WCS) {
step = 0.1;
}
else if(mode == MODE_ROTATE_OCS) {
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixf(ocsmatrix[selected_object]);
step = 2.0;
} else if(mode == MODE_ROTATE_WCS) {
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixf(wcsmatrix[selected_object]);
step = 2.0;
}
}
if( selected_object > -1 )
{
if( key == 'x' ) {
translation_var[selected_object][0] += step;
if(mode == MODE_ROTATE_OCS || mode == MODE_ROTATE_WCS)
glRotatef(-step, 1.0, 0.0, 0.0);
}
else if( key == 'X' ) {
translation_var[selected_object][0] -= step;
if(mode == MODE_ROTATE_OCS || mode == MODE_ROTATE_WCS)
glRotatef(step, 1.0, 0.0, 0.0);
}
else if( key == 'y' ) {
translation_var[selected_object][1] += step;
if(mode == MODE_ROTATE_OCS || mode == MODE_ROTATE_WCS)
glRotatef(-step, 0.0, 1.0, 0.0);
}
else if( key == 'Y' ) {
translation_var[selected_object][1] -= step;
if(mode == MODE_ROTATE_OCS || mode == MODE_ROTATE_WCS)
glRotatef(step, 0.0, 1.0, 0.0);
}
else if( key == 'z' ) {
translation_var[selected_object][2] += step;
if(mode == MODE_ROTATE_OCS || mode == MODE_ROTATE_WCS)
glRotatef(-step, 0.0, 0.0, 1.0);
}
else if( key == 'Z' ) {
translation_var[selected_object][2] -= step;
if(mode == MODE_ROTATE_OCS || mode == MODE_ROTATE_WCS)
glRotatef(step, 0.0, 0.0, 1.0);
}
}
// Save rotation in relative matrixes
if(mode == MODE_ROTATE_OCS) {
glGetFloatv(GL_MODELVIEW_MATRIX, ocsmatrix[selected_object]);
glPopMatrix();
}
else if(mode == MODE_ROTATE_WCS) {
glGetFloatv(GL_MODELVIEW_MATRIX, wcsmatrix[selected_object]);
glPopMatrix();
}
glutPostRedisplay();
}
最后是 display()
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
glShadeModel (GL_SMOOTH); //GL_FLAT
glLightfv( GL_LIGHT0, GL_POSITION, lightPos );
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glMatrixMode( GL_PROJECTION );
glLoadIdentity ();
gluPerspective( fovy, aspect, 1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( camE[0], camE[1], camE[2], camC[0], camC[1], camC[2], camU[0], camU[1], camU[2] );
// Trackball rotation.
glRotatef(tbAngle, tbAxis[0], tbAxis[1], tbAxis[2]);
glLineWidth(2);
drawAxis( 2.0, 1 );
glLineWidth(1);
glRotatef(angle[0], 1.0, 0.0, 0.0);
glRotatef(angle[1], 0.0, 1.0, 0.0);
glRotatef(angle[2], 0.0, 0.0, 1.0);
//draw the mesh model
drawAxis( 1.0, 0 );
for(i=0; i<loaded_objects; i++) {
glPushMatrix();
glMultMatrixf(wcsmatrix[i]);
glTranslatef(objWPos[i][0] + translation_var[i][0], objWPos[i][1] + translation_var[i][1], objWPos[i][2] + translation_var[i][2]);
glMultMatrixf(ocsmatrix[i]);
glTranslatef(objPos[i][0]+translation_var[i][0], objPos[i][1]+translation_var[i][1], objPos[i][2]+translation_var[i][2]);
glScalef( objScale[i], objScale[i], objScale[i]);
//draw the model
if(!wireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glCallList(listname+i);
glPopMatrix();
}
glutSwapBuffers();
因此,这些是在 mesg 对象(在我的例子中是“ pig ”)显示在 3 个轴的中心后我在键盘上按下的按钮:
但是哈巴狗没有动。为什么?它似乎只适用于 translate_var[3] 而不适用于 translate_var[3][3]。但是,如果我使用单维数组,那么我将平移所有 3 个网格对象......另外,i-mesh对象和objPos/objWPos中的第i个位置是如何绑定(bind)的?
最佳答案
您的主要错误/误解是,您将 OpenGL 视为某种 3D 场景管理器。它不是。 OpenGL 所做的只是一次绘制一个点、线或三角形。显示列表是一种宏记录,仅此而已。
在您的键盘处理函数中,您通过操纵 OpenGL 变换矩阵对事件作出 react 。然而,这些矩阵只是绘图过程的另一个输入。仅仅操纵它们没有任何效果。此外,矩阵和“模型”之间没有“关联”,因为 OpenGL 没有模型。
所以你要做的是,在你的键盘处理程序中使用输入来操作你定义的变量;每个对象的一组变量(提示:struct
),然后标记 GLUT 它将在主应用程序循环的下一次迭代时调用显示处理程序(glutPostRedisplay
)。然后在显示例程中使用您在输入事件处理程序中操作的变量的值来为您要绘制的每个模型设置相应的转换矩阵,就在您绘制该模型之前。
关于c - 过剩/OpenGL : how to bind array of coordinates to mesh object to traslate/rotate them,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32950362/
我试图在固定的时间间隔后依次旋转一个红色三角形和一个绿色三角形。我尝试了以下代码,但时间间隔不是常数。我无法找出问题所在。 static void display(void) { now=g
我有一些基本代码可以使用 glut 收集按键事件。 如果我按住一个键,我会触发连续事件(向下/向上/向下/向上/向下/向上/......),而不是预期的向下(一次,在开始时)及以上(一次,最后) #i
当我尝试调整过剩窗口的大小时,屏幕变为空白。 这是 reshape 回调函数的代码: void Resize(int width, int height) { CurrentWidth =
我使用最新的 freeglut 成功编译了这段代码,但我不断得到一个空白窗口,其中填充了 glClearColor 函数中指定的颜色。这个简单的程序来 self 学院提供的交互式计算机图形学教科书。我
任何人都可以解释发生了什么或没有发生什么,以便我可以更正它。到目前为止,这是来自 .cpp 文件的代码。在 Visual Studio Community 2015 中运行。 #include #i
我正在学习一个 openGL 教程,其中包括这个名为“glutCreateWindow”的函数,我的编译器(XCode 5 gcc,OSX)说它已被弃用。 还有什么选项适合替换这些“过剩*”相关函数?
我使用 OpenGL 3.3。在我的应用程序中,我将鼠标光标设置在窗口的中心(我将窗口的大小传递给“Camera”类的构造函数),但是当我调整窗口大小时(如全屏)我将光标放在左边的部分。所以,我想通过
我在为我的 GLUT 小行星游戏显示和动画多个小行星时遇到问题。我可以生成 1 ok,但是当我尝试添加更多时,输出不正确,createasteroid 不断被调用,并且出于某种原因只是在屏幕的不同部分
我认为我遇到了一个棘手的问题。我是 C++ 和 OpenGL/glut 的新手,所以要温柔!我正在编写一个独立于平台的简单程序(仅 2D)并且需要一个基本的 UI,因此我有一个生成 Button 对象
我很笨 :) 那么有人可以帮忙编写分步手册,如何安装“cairo”、“glut”并在 Windows 7 上的 VS 2010 项目 (C++) 中使用它吗? PS:最有趣的事情是我在 Linux 中
在我的 GLUT/OpenGL 练习中,我必须加载 3 个不同的对象,我给它们一个 file.m。这是通过读取该文件、创建列表并最终调用 glCallList() 来完成的。选择一个对象后,我必须如何
我正在尝试制作 gluLookAt() 函数,以便当我按下向上和向下键时,相机围绕 X 轴移动 我正在尝试我在以下位置看到的方法:http://www.lighthouse3d.com/tutoria
我是一名优秀的程序员,十分优秀!