хочу создать "свободную" камеру с движением по осям х, у, z

76
19 сентября 2021, 17:10

В общем у меня не выходить создать камеру которая бы двигалась по осям x, y, z. Увы только по оси z. что я делаю не так ???

Я как то не понимаю как именно работает gluLookAt( x, 0.0f, z+25.0, x+lx, 0.0f, z+25.0+lz, 0.0f, 1.0f, 0.0f); по я z меня код работает (по х почемуто не вышло), но осмысленно я так всё понять и не смог :(.

Вот весь код :

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <glew.h>
#include <freeglut.h>
#include "getBMP.h"
#define PI 3.14159265358979324
#define R 12.0 // Радиус сферы Radius of the sphere.
// угол поворота камеры
float angle=0.0;
// движение по картинке
// координаты вектора направления движения камеры
float lx=0.0f, lz=-1.0f, ly=0.0f;
// XZ позиция камеры
float x=0.0f, z=0.0f, y=0.0f;
//Ключи статуса камеры. Переменные инициализируются нулевыми значениями
//когда клавиши не нажаты
float deltaAngle = 0.0f;
float deltaMove = 0;

// Globals.
static int p = 100; // Количество столбцов сетки  Number of grid columns.
static int q = 100; // Количество рядов сетки Number of grid rows
static float *vertices = NULL; // Массив вершин отображенного образца на сфере. Vertex array of the mapped sample on the sphere.
static float *textureCoordinates = NULL; // Ткоординаты текстуры, массив отображенного образца на сфере. Texture co-ordinates array of the mapped sample on the sphere.
static unsigned int texture[1]; // Массив текстурных индексов. Array of texture indices.
static float Xangle = 0.0, Yangle = 0.0, Zangle = 0.0; //Углы поворота сферы. Angles to rotate sphere.

// Загрузка картинки в текстуру Load image as a texture.
void loadTextures()
{
    imageFile *image[1];
//    image[0] = getBMP("earth.bmp");
    image[0] = getBMP("earth.bmp");
    // image[0] = getBMP("dog1-20x7.bmp");
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image[0]->width, image[0]->height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, image[0]->data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
// Функции для отображения вершины сетки (u_i, v_j) в вершину сетки (f (u_i, v_j), g (u_i, v_j), h (u_i, v_j)) на сфере.
// Fuctions to map the grid vertex (u_i,v_j) to the mesh vertex (f(u_i,v_j), g(u_i,v_j), h(u_i,v_j)) on the sphere.
float f(int i, int j)
{
    return (R * cos(-PI / 2.0 + (float)j / q * PI) * cos(2.0 * (float)i / p * PI));
}
float g(int i, int j)
{
    return (R * sin(-PI / 2.0 + (float)j / q * PI));
}
float h(int i, int j)
{
    return (-R * cos(-PI / 2.0 + (float)j / q * PI) * sin(2.0 * (float)i / p * PI));
}
// Процедура заполнения массива вершин координатами сопоставленных точек выборки.
// Routine to fill the vertex array with co-ordinates of the mapped sample points.
void fillVertexArray(void)
{
    int i, j, k;
    k = 0;
    for (j = 0; j <= q; j++)
        for (i = 0; i <= p; i++)
        {
            vertices[k++] = f(i, j);
            vertices[k++] = g(i, j);
            vertices[k++] = h(i, j);
        }
}
// Процедура заполнения массива координат текстуры значениями координат текстуры в отображенных точках выборки.
// Routine to fill the texture co-ordinates array with the texture co-ordinate values at the mapped sample points.
void fillTextureCoordArray(void)
{
    int i, j, k;
    k = 0;
    for (j = 0; j <= q; j++)
        for (i = 0; i <= p; i++)
        {
            textureCoordinates[k++] = (float)i / p;
            textureCoordinates[k++] = (float)j / q;
        }
}
// Процедура инициализации. Initialization routine.
void setup(void)
{
    // Включаем проверку глубины и массив координат вершин и текстур.
    // Enable depth testing and the vertex and texture coordinate arrays.
    glEnable(GL_DEPTH_TEST);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glClearColor(1.0, 1.0, 1.0, 0.0);
    // Создать идентификатор текстуры. Create texture ids.
    glGenTextures(1, texture);
    // Загружаем текстуру. Load texture.
    loadTextures();
    // Укажите, как значения текстуры объединяются с текущими значениями цвета поверхности.
    // Specify how texture values combine with current surface color values.
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    // Включаем OpenGL текстурирование. Turn on OpenGL texturing.
    glEnable(GL_TEXTURE_2D);
    // Выделите место для массива вершин и координат текстуры.
    // Allocate space for vertex and texture coordinates array.
    vertices = new float[3 * (p + 1)*(q + 1)];
    textureCoordinates = new float[2 * (p + 1)*(q + 1)];
    // Установите указатели массива. Set the array pointers.
    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoordinates);
    // Заполните массивы текстур и координат. Fill the vertex and texture co-ordinates arrays.
    fillVertexArray();
    fillTextureCoordArray();
    // Отберите задние грани сферы. Cull the back faces of the sphere.
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
}
void computePos(float deltaMove)
{
    x += deltaMove * lx * 0.1f;
    z += deltaMove * lz * 0.1f;
}
void computeDir(float deltaAngle)
{
    angle += deltaAngle;
    lx = sin(angle);
    lz = -cos(angle);
}
// Процедура рисования. Drawing routine.
void drawScene(void)
{
    int  i, j;
    if (deltaMove)
        computePos(deltaMove);
    if (deltaAngle)
        computeDir(deltaAngle);
    //очистить буфер цвета и глубины
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // обнулить трансформацию
    glLoadIdentity();
//    gluLookAt(0.0, 0.0, 25.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
//    // установить камеру
//    gluLookAt(       x,   y,    z+25.0,
//                x+lx, y+ly,  z+25.0+lz,
//                0.0f,   1.0f,  0.0f       );
    // установить камеру
    gluLookAt( x, 0.0f, z+25.0, x+lx, 0.0f, z+25.0+lz, 0.0f, 1.0f, 0.0f);
//    gluLookAt(       x,   0.0f,     z+25.0,
//                0.0f, 0.0f,  0.0f,
//                0.0f,   1.0f,  0.0f       );
//    glBegin(GL_QUADS);// полигон с коондинатами
    // Команды для поворота сферы. Commands to turn the sphere.
    glRotatef(Zangle, 0.0, 0.0, 1.0);
    glRotatef(Yangle, 0.0, 1.0, 0.0);
    glRotatef(Xangle, 1.0, 0.0, 0.0);
    // Нанесите текстуру на сферу. Map the texture onto the sphere.
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    for (j = 0; j < q; j++)
    {
        glBegin(GL_TRIANGLE_STRIP);
        for (i = 0; i <= p; i++)
        {
            glArrayElement((j + 1)*(p + 1) + i);
            glArrayElement(j*(p + 1) + i);
        }
        glEnd();
    }
    glutSwapBuffers();
}
// Процедура изменения формы окна OpenGL. OpenGL window reshape routine.
void resize(int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-5.0, 5.0, -5.0, 5.0, 5.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
// Процедура обработки ввода с клавиатуры. Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 27:
        exit(0);
        break;
    case 'x':
        Xangle += 5.0;
        if (Xangle > 360.0) Xangle -= 360.0;
        glutPostRedisplay();
        break;
    case 'X':
        Xangle -= 5.0;
        if (Xangle < 0.0) Xangle += 360.0;
        glutPostRedisplay();
        break;
    case 'y':
        Yangle += 5.0;
        if (Yangle > 360.0) Yangle -= 360.0;
        glutPostRedisplay();
        break;
    case 'Y':
        Yangle -= 5.0;
        if (Yangle < 0.0) Yangle += 360.0;
        glutPostRedisplay();
        break;
    case 'z':
        Zangle += 5.0;
        if (Zangle > 360.0) Zangle -= 360.0;
        glutPostRedisplay();
        break;
    case 'Z':
        Zangle -= 5.0;
        if (Zangle < 0.0) Zangle += 360.0;
        glutPostRedisplay();
        break;
    case 'a':
        x += 0.01f;
        glutPostRedisplay();
         break;
    case 'd':
        x += -0.01f;
        glutPostRedisplay();
         break;
    case 'w':
//        printf(" %d ", deltaMove);
        z += 0.5f;
        glutPostRedisplay();
         break;
    case 's':
        z -= 0.5f;
        glutPostRedisplay();
         break;
    default:
        break;
    }
}
void releaseKey(int key, int x, int y) {
    switch (key) {
        case GLUT_KEY_LEFT:
        case GLUT_KEY_RIGHT:
            deltaAngle = 0.0f;
            break;
        case GLUT_KEY_UP:
        case GLUT_KEY_DOWN:
            deltaMove = 0;
            break;
    }
}
// Процедура вывода инструкций взаимодействия в окно C ++.
// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
    std::cout << "Interaction:" << std::endl;
    std::cout << "Press x, X, y, Y, z, Z to turn the sphere." << std::endl;
    std::cout << "нажмите a, b, для поворота камеры , w, s, для движения камеры (наобьект либо против)" << std::endl;
}
// Основная рутина. Main routine.
int main(int argc, char **argv)
{
    printInteraction();
    glutInit(&argc, argv);
    glutInitContextVersion(4, 3);
    glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("texturedSphere.cpp");
    glutDisplayFunc(drawScene);
    glutReshapeFunc(resize);
    glutKeyboardFunc(keyInput);
    // ---
//    // Новые функции для регистрации
//    glutIgnoreKeyRepeat(1);
    glutSpecialUpFunc(releaseKey);
//    // OpenGL - инициализация функции теста
//    glEnable(GL_DEPTH_TEST);
    // ---
    glewExperimental = GL_TRUE;
    glewInit();
    setup();
    glutMainLoop();
    return 1;
}

READ ALSO
Указатели для создания виджетов

Указатели для создания виджетов

Почему при создании виджета нужно использовать указатель, а не переменную?

115
Почему линковщик не видит символ?

Почему линковщик не видит символ?

В начале файла dllmaincpp есть такой фрагмент кода: extern "C" HINSTANCE hAppInstance;

144
std::unique_lock не захватывает мьютекс

std::unique_lock не захватывает мьютекс

Разрабатываю имплементацию очереди задачВ классе содержатся следующие данные:

77
Как из проекта Qt сделать библиотеку?

Как из проекта Qt сделать библиотеку?

подскажите пожалуйста, у меня есть проект на Qt с использованием qml-я, своеобразное приложение для работы с базой данныхВозникла необходимость...

112