Не правильный куб в LWJGL?

В общем начал изучение библиотеки LWJGL (Java)
Вникнув в небольшую базу, освоившись с 2D-фигурами перешел к 3D
И тут честно сказать, все поплыло..

После неудачных попыток отобразить куб в программе, брал координаты уже с разных интернет-источников.
Но у всех были разные ошибки. То куб расплывался в разные стороны, то и вовсе не появлялся.
Я все-таки думаю, что ошибка в моем изначальном коде (Брал с официального сайта LWJGL), где я что-то забыл указать или же наоборот надо было удалить.

Мой код:

spoiler
import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;

import java.nio.*;

import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;

import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;

public class HelloWorld {

    // The window handle
    private long window;
    float tri;
    public void run() {
        System.out.println("Hello LWJGL " + Version.getVersion() + "!");

        init();
        loop();

        // Free the window callbacks and destroy the window
        glfwFreeCallbacks(window);
        glfwDestroyWindow(window);

        // Terminate GLFW and free the error callback
        glfwTerminate();
        glfwSetErrorCallback(null).free();
    }

    private void init() {
        // Setup an error callback. The default implementation
        // will print the error message in System.err.
        GLFWErrorCallback.createPrint(System.err).set();

        // Initialize GLFW. Most GLFW functions will not work before doing this.
        if ( !glfwInit() )
            throw new IllegalStateException("Unable to initialize GLFW");

        // Configure GLFW
        glfwDefaultWindowHints(); // optional, the current window hints are already the default
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable

        // Create the window
        window = glfwCreateWindow(300, 300, "Hello World!", NULL, NULL);
        if ( window == NULL )
            throw new RuntimeException("Failed to create the GLFW window");

        // Setup a key callback. It will be called every time a key is pressed, repeated or released.
        glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
            if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
                glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
        });

        // Get the thread stack and push a new frame
        try ( MemoryStack stack = stackPush() ) {
            IntBuffer pWidth = stack.mallocInt(1); // int*
            IntBuffer pHeight = stack.mallocInt(1); // int*

            // Get the window size passed to glfwCreateWindow
            glfwGetWindowSize(window, pWidth, pHeight);

            // Get the resolution of the primary monitor
            GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());

            // Center the window
            glfwSetWindowPos(
                    window,
                    (vidmode.width() - pWidth.get(0)) / 2,
                    (vidmode.height() - pHeight.get(0)) / 2
            );
        } // the stack frame is popped automatically

        // Make the OpenGL context current
        glfwMakeContextCurrent(window);
        // Enable v-sync
        glfwSwapInterval(1);

        // Make the window visible
        glfwShowWindow(window);
    }

    private void loop() {
        // This line is critical for LWJGL's interoperation with GLFW's
        // OpenGL context, or any context that is managed externally.
        // LWJGL detects the context that is current in the current thread,
        // creates the GLCapabilities instance and makes the OpenGL
        // bindings available for use.
        GL.createCapabilities();

        // Set the clear color
        glClearColor(1.0f, 1.0f, 1.0f, 0.0f);



        // Run the rendering loop until the user has attempted to close
        // the window or has pressed the ESCAPE key.
        while ( !glfwWindowShouldClose(window) ) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
            glLoadIdentity();

            /*GL11.glTranslatef(0f,0.0f,0f);
            GL11.glRotatef(45f,0.0f,1.0f,0.0f);
            GL11.glColor3f(0.5f,0.5f,1.0f);*/
            //glTranslatef(0.0f,0.0f,-1.5f);
            glRotatef(tri, 1.0f,1.0f,1.0f);

            glBegin(GL_QUADS);

            glColor3f(0.0f,1.0f,0.0f);              // Синий
            glVertex3f( 1.0f, 1.0f,-1.0f);          // Право верх квадрата (Верх)
            glVertex3f(-1.0f, 1.0f,-1.0f);          // Лево верх
            glVertex3f(-1.0f, 1.0f, 1.0f);          // Лево низ
            glVertex3f( 1.0f, 1.0f, 1.0f);          // Право низ

            glColor3f(1.0f,0.5f,0.0f);              // Оранжевый
            glVertex3f( 1.0f,-1.0f, 1.0f);          // Верх право квадрата (Низ)
            glVertex3f(-1.0f,-1.0f, 1.0f);          // Верх лево
            glVertex3f(-1.0f,-1.0f,-1.0f);          // Низ лево
            glVertex3f( 1.0f,-1.0f,-1.0f);          // Низ право

            glColor3f(1.0f,0.0f,0.0f);              // Красный
            glVertex3f( 1.0f, 1.0f, 1.0f);          // Верх право квадрата (Перед)
            glVertex3f(-1.0f, 1.0f, 1.0f);          // Верх лево
            glVertex3f(-1.0f,-1.0f, 1.0f);          // Низ лево
            glVertex3f( 1.0f,-1.0f, 1.0f);          // Низ право

            glColor3f(0.0f,0.0f,1.0f);              // Синий
            glVertex3f(-1.0f, 1.0f, 1.0f);          // Верх право квадрата (Лево)
            glVertex3f(-1.0f, 1.0f,-1.0f);          // Верх лево
            glVertex3f(-1.0f,-1.0f,-1.0f);          // Низ лево
            glVertex3f(-1.0f,-1.0f, 1.0f);          // Низ право

            glColor3f(1.0f,0.0f,1.0f);              // Фиолетовый
            glVertex3f( 1.0f, 1.0f,-1.0f);          // Верх право квадрата (Право)
            glVertex3f( 1.0f, 1.0f, 1.0f);          // Верх лево
            glVertex3f( 1.0f,-1.0f, 1.0f);          // Низ лево
            glVertex3f( 1.0f,-1.0f,-1.0f);          // Низ право

            glEnd();                                // Закончили квадраты

            glfwSwapBuffers(window); // swap the color buffers
            // Poll for window events. The key callback above will only be
            // invoked during this call.
            glfwPollEvents();

            tri +=0.2f;

        }
    }

    public static void main(String[] args) {
        new HelloWorld().run();
    }

}


Поставил спин на куб, вращение идет внутрь квадрата, получается полный бред
Но если убрать спин, то о никаком 3D и речи не идет, чистое 2D (Хотел видео записать, но думаю, что поймете):

5bb5012ba214e487981278.png
  • Вопрос задан
  • 318 просмотров
Решения вопроса 1
Беглым взглядом могу сказать что проблема у вас в скорее всего в том самом "переходе" от 2D к 3D. Точнее, в его отсутствии.

Недостаточно просто взять и вписать трёхмерные координаты. Вам нужно доучить матчать по видовым и проекционным матрицам и задействовать glMatrixMode с последующей загрузкой нужной матрицы. Сейчас вы, грубо говоря, не рисуете трёхмерный куб - вы рисуете его как двухмерную фигуру, не задействуя третью координату так как вы хотели бы.

И да, ещё важный момент. Не имел дела с указанной вами библиотекой, но похоже что вы сейчас пользуетесь вызовами OpenGL старых версий, и работаете в "старой" модели программирования. В целях обучения это может даже и лучше, но это не готовит вас к современному OpenGL из реального мира. В современном подходе для матричных преобразований используются шейдеры (и это лишь ничтожная часть того что можно сейчас делать с помощью шейдеров различных типов), а координаты примитивов задаются не последовательными вызовами glVertex (что крайне неэффективно с учётом производительности современных GPU), а построением буферов данных заранее и отрисовкой всего набора вершин целиком (см. glDrawElements и прочие функции).

Так что если вы делаете это всё исключительно для понимания мат. части - в принципе пока вам достаточно и этого, но если вам нужны актуальные умения - найдите книги/примеры/уроки посвежее. Это можно сделать и позже, когда вы будете к этому лучше подготовлены (к сожалению, современный OpenGL не может быть простым, хотя бы из-за очень больших возможностей современных граф. процессоров).
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы