OpenGL - poczatki sa trudne - nic sie nie rysuje na ekranie

0

Cześć,
próbuję się trochę przeszkolić z OpenGL, jestem początkujący i potrzebuję pomocy.

Zacząłem się uczyć z filmików Pana Cherno na youtube i utknąłem na tym filmiku:

Przepisałem dokładnie kod z tego filmu, jednak napotykam kłopoty.

  1. Jeżeli nie skompiluję Shadera, to zgodnie z komentarzem w filmie, powinien się uruchomić domyślny systemowy Shader (oczywiście jeżeli taki jest, bo podobno nie zawsze jest). U mnie ten domyślny uruchamia się jakby częściowo. Tzn. rysuje biały trójkąt, ale dopiero jak myszką złapię narożnik okna i zmienię jego rozmiar, a tak na dzień dobry zaraz po uruchomieniu nic nie wyświetla, tylko czarny ekran.

  2. Po skompilowaniu Shadera powinien się narysować czerwony trójkąt, natomiast u mnie się nic nie rysuje, nawet jak zmienię wielkość okna jak powyżej. Po prostu nie działa.

Bardzo proszę o pomoc i z góry dziękuję.

Kod wygląda dokładnie jak poniżej:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>


static unsigned int CompileShader(unsigned int type, const std::string &source)
{
    unsigned int id = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(id, 1, &src, nullptr);
    glCompileShader(id);
    
    // Tutaj jakis kod w razie erroru.
    int result;
    glGetShaderiv(id, GL_COMPILE_STATUS, &result);
    if(result == GL_FALSE)
    {
        int length;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
        char* message = (char*)alloca(length * sizeof(char));
        glGetShaderInfoLog(id, length, &length, message);
        std::cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader" << std::endl;
        std::cout << message << std::endl;
        glDeleteShader(id);
        return 0;
    }
    
    return id;
}


static unsigned int CreateShader(const std::string &vertexShader, const std::string &fragmentShader)
{
    unsigned int program = glCreateProgram();
    unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
    unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
    
    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    glValidateProgram(program);
    
    glDeleteShader(vs);
    glDeleteShader(fs);
    
    return program;
}




int main(void)
{
    GLFWwindow* window;
    
    /* Initialize the library */
    if (!glfwInit())
        return -1;

    
    // UWAGA PONIZSZYCH CZTERECH LINIJEK NIE MA W KODZIE Z FILMU.
    // ALE BEZ TEGO WYSKAKIWAL MI BLAD:
    // #version 330 core is not supported
    // PEWNIE NALEZY ZAZNACZYC, ZE PISZE POD MAC OS X
    // PODOBNO STAD WYNIKAL TEN PROBLEM, A PONIZSZE CZTERY LINIJKI
    // ZNALAZLEM W SIECI JAKO REMEDIUM. POMOGLO.
    // BLAD O BRAKU WSPARCIA DLA VERSION 330 ZNIKNAL
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)


   // TUTAJ JUZ DALSZA CZESC KODU Z FILMU
    
    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);

    if (!window)
    {
        glfwTerminate();
        return -1;
    }
    
    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    
    std::cout << "OpenGL - version: " << glGetString(GL_VERSION) << std::endl;
    
    if(glewInit() != GLEW_OK)
        std::cout << "Hej! to jest error" << std::endl;
    
    // Tutaj sa nasze dane ktore wklepiemy do buffera
    float positions[6] = {
        -0.5f, -0.5,
        -0.0f,  0.5,
        0.5f, -0.5
    };
    
    // Tutaj tworzymy buffer
    unsigned int buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, 6*sizeof(float), positions, GL_STATIC_DRAW);
    
    // Tutaj tworzymy i uruchamiamy nasz Vertex
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0);
    glEnableVertexAttribArray(0);
    
    // A teraz tworzymy naszego Shadera
    std::string vertexShader =
                "#version 330 core\n"
                "\n"
                "layout(location = 0) in vec4 position;\n"
                "\n"
                "void main()\n"
                "{\n"
                "   gl_Position = position;\n"
                "}\n";
    
    std::string fragmentShader =
                "#version 330 core\n"
                "\n"
                "layout(location = 0) out vec4 color;\n"
                "\n"
                "void main()\n"
                "{\n"
                "   color = vec4(1.0, 0.0, 0.0, 1.0);\n"
                "}\n";
    
    unsigned int shader = CreateShader(vertexShader, fragmentShader);
    
    glUseProgram(shader);
    
    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);
        
        glDrawArrays(GL_TRIANGLES, 0, 3);
        
        
        /* Swap front and back buffers */
        glfwSwapBuffers(window);
        
        /* Poll for and process events */
        glfwPollEvents();
    }
    
    glfwTerminate();
    return 0;
}
2
  1. Wywal maca.
  2. Wywal maca.
0

A linuxa też wywalić?

3

Apps built using OpenGL and OpenCL will continue to run in macOS 10.14, but these legacy technologies are deprecated in macOS 10.14. Games and graphics-intensive apps that use OpenGL should now adopt Metal. Similarly, apps that use OpenCL for computational tasks should now adopt Metal and Metal Performance Shaders.

https://developer.apple.com/macos/whats-new/

0

Hej,
dzięki za info.
Czytałem to już wcześniej to co linkujesz, ale nie sądziłem, że słowo "deprecated" oznacza całkowite wyłączenie możliwości korzystania z OpenGL.
Skoro już zacząłem się uczyć tego OpenGL to przydałoby się aby mi działał. Czy naprawdę na Macu już tego nie zrobię? Muszę mieć Windowsa?
A co z Linuxem?
Za bardzo się na tym nie znam, ale z tego co zrozumiałem, słuchając różnych wypowiedzi, OpenGL jest zależny raczej od sprzętu (a konkretniej od karty graficznej) a nie od systemu operacyjnego.
Czy możecie coś doradzić poza wyrzuceniem Maca co jest dla mnie oczywiste. Ale tak póki go jeszcze mam, potrzebuję jakiegoś chociaż tymczasowego rozwiązania :)

1

To nie oznacza że od razu "nie działa", ale jeśli coś Ci się będzie krzaczyło to w zasadzie "deprecated" oznacza "radź sobie sam".
Dla OpenGL najlepsze byłoby pewnie środowisko Linux.
Na Maku też pewnie się da, tylko miej na uwadze link z oficjalnej strony.
Merytorycznie nie pomogę niestety...

0

OK, dzięki i tak za support :)

1
pajczur napisał(a):
  1. Jeżeli nie skompiluję Shadera, to zgodnie z komentarzem w filmie, powinien się uruchomić domyślny systemowy Shader

Powiedzmy.
Przy czym chodzi tu o użycie glUseProgram, a nie glCompileShader.

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)

W core profile nie ma „domyślnych shaderów”.

2

Jeśli dla celów edukacyjnych chciałbyś zobaczyć w akcji OpenGL bez shaderów (tzw. fixed-function pipeline), to zmodyfikowałem kod wprowadzając minimalne zmiany by to osiągnąć:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>

int main(void)
{
	GLFWwindow* window;

	/* Initialize the library */
	if (!glfwInit())
		return -1;

		/* Create a windowed mode window and its OpenGL context */
		window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);

	if (!window)
	{
		glfwTerminate();
		return -1;
	}

	/* Make the window's context current */
	glfwMakeContextCurrent(window);

	std::cout << "OpenGL - version: " << glGetString(GL_VERSION) << std::endl;

	if (glewInit() != GLEW_OK)
		std::cout << "Hej! to jest error" << std::endl;

	// Tutaj sa nasze dane ktore wklepiemy do buffera
	float positions[6] = {
		-0.5f, -0.5,
		-0.0f,  0.5,
		0.5f, -0.5
	};

	// Tutaj tworzymy buffer
	unsigned int buffer;
	glGenBuffers(1, &buffer);
	glBindBuffer(GL_ARRAY_BUFFER, buffer);
	glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);

	// Tutaj tworzymy i uruchamiamy nasz Vertex
	glVertexPointer(2, GL_FLOAT, 2 * sizeof(float), 0);
	glEnableClientState(GL_VERTEX_ARRAY);

	glColor3f(1.0, 0.0, 0.0);

	/* Loop until the user closes the window */
	while (!glfwWindowShouldClose(window))
	{
		/* Render here */
		glClear(GL_COLOR_BUFFER_BIT);

		glDrawArrays(GL_TRIANGLES, 0, 3);

		/* Swap front and back buffers */
		glfwSwapBuffers(window);

		/* Poll for and process events */
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}

Działanie pod makiem nie gwarantowane.

0

Super, wielkie dzięki. A jeszcze pytanko jak to wszystko zrozumieć? Wydaje się to tak zagmatwane jak mało co. Czy są jakieś utarte sposoby jak nauczyć się tym posługiwać?
Przeleciełem już ze 2 tutoriale (każdy tylko do połowy), ale tam gadają tylko o tym jak działa OpenGL, objaśniają funkcje, zmienne, to oczywiście najważniejsze jest. Ale pytanie jak to wszystko spamiętać?
Nie sposób zapamiętać tych wszystkich funkcji, tych zmiennych typu GL_XXXX_XX_XXX, i innych rzeczy, kiedy co użyć, zauważyłem, że często jedna literka może wszystko zepsuć. Wydaje mi się, że to jest o wiele bardziej zagmatwane niż nauka samego C++.

0

Ale pytanie jak to wszystko spamiętać?

Spamiętać to raczej nie spamiętasz. Wydaje mi się, że praca z takimi rzeczami przypomina trochę pracę z WinAPI. Po prostu bez ciągle otwartej dokumentacji ani rusz. Z czasem nabierzesz pewnych, powtarzalnych nawyków i to ułatwi Ci pracę ale programując tak złożone rzeczy raczej nie sposób być super szybkim koderem.

0

@pajczur: Nie zapamiętasz (chyba, że byś siedział w temacie przez kilka miesięcy). Najważniejsze moim zdaniem to zrozumieć, bo wtedy jak zapomnisz to wiesz czego szukać, w którymi miejscu i wiesz od razu jak działa.

0

No też myślę, że to chyba jedyny sposób. Dzięki

1
pajczur napisał(a):

Super, wielkie dzięki. A jeszcze pytanko jak to wszystko zrozumieć? Wydaje się to tak zagmatwane jak mało co.

OpenGL jest zagmatwany, bo wielokrotnie zmieniał się zamysł jak wszystko ma działać, przez co teraz jest milijon sposobów na to samo, a do tego jeszcze jest OpenGL ES na smartfony i tablety tak-sobie kompatybilny z OpenGLem desktopowym.

Nie pomagają twórcy tutoriali i spece na forach kiedy zamiast sprecyzować używaną wersję OpenGL-a mówią o "modern GL" – i weź tu się po kilku latach domyślaj co dla nich było "modern" w momencie pisania. Albo kiedy wytykają człowiekowi że coś tam jest deprecated w najnowszej wersji (bo twórcy standardu radośnie deprecjonują użyteczne ficzery na prawo i lewo) podczas gdy rzadko kiedy chcemy pisać pod najnowszą wersję z powodów kompatybilnościowych (czytaj: mało użytkowników ma najnowszą). Albo kiedy mają słabe pojęcie na temat co weszło w której wersji i po prostu wprowadzają w błąd.

Ja czytam specyfikacje OpenGL – w różnych wersjach by wiedzieć co się z czym je a czego z czym nie. Przy okazji wychodzi na wierzch sporo bzdur kopiowanych z jednego tutoriala do drugiego…

1 użytkowników online, w tym zalogowanych: 0, gości: 1