Jump to page: 1 2 3
Thread overview
Using OpenGL
Sep 02, 2016
Darren
Sep 03, 2016
Mike Parker
Sep 03, 2016
Darren
Sep 03, 2016
pineapple
Sep 03, 2016
Darren
Sep 03, 2016
Lodovico Giaretta
Sep 03, 2016
Darren
Sep 03, 2016
Lodovico Giaretta
Sep 03, 2016
Mike Parker
Sep 03, 2016
Darren
Sep 03, 2016
Mike Parker
Sep 03, 2016
Darren
Sep 03, 2016
Mike Parker
Sep 03, 2016
Mike Parker
Sep 03, 2016
Darren
Sep 05, 2016
Nicholas Wilson
Sep 05, 2016
Guillaume Piolat
Sep 14, 2016
Darren
Sep 15, 2016
Mike Parker
Sep 15, 2016
Darren
Sep 16, 2016
Mike Parker
Sep 16, 2016
Darren
Oct 04, 2016
Darren
Oct 05, 2016
Darren
September 02, 2016
I'm trying to teach myself OpenGL but I'm not sure how to set it up exactly.
I used "dub init" to create a project, I downloaded glew32.dll and glfw.dll and put them in this folder.  I added "derelict-gl3": "~>1.0.19" and "derelict-glfw3": "~>3.1.0" to dependencies, and imported them in the app.d file.  I add the load() and reload() functions where appropriate (I assume).

I can run a simple window program and it seems to work fine, but I notice that's when all the functions begin with "glfw".  If I try to follow a tutorial for loading a triangle, I get errors when trying to build.

Do I need to link an opengl.dll file, too?


September 03, 2016
On Friday, 2 September 2016 at 20:38:15 UTC, Darren wrote:
> I'm trying to teach myself OpenGL but I'm not sure how to set it up exactly.
> I used "dub init" to create a project, I downloaded glew32.dll and glfw.dll and put them in this folder.  I added "derelict-gl3": "~>1.0.19" and "derelict-glfw3": "~>3.1.0" to dependencies, and imported them in the app.d file.  I add the load() and reload() functions where appropriate (I assume).

You don't need GLEW. It's a library for C and C++ that loads all of the OpenGL functions and extensions available in the context you create. DerelictGL3 does that for you in D. DerelictGl3.load loads the OpenGL DLL and the functions up to OGL 1.1, and DerelictGL3.reload loads all the functions and extensions available in the current context.

>
> I can run a simple window program and it seems to work fine, but I notice that's when all the functions begin with "glfw".

Yes, GLFW is a simple windowing toolkit for creating windows & OpenGL contexts and managing window & input events in a cross-platform manner. Without it, you would need to use the system APIs yourself (such as Win32 on Windows) or another cross-platform library  like SDL or SFML.


> If I try to follow a tutorial for loading a triangle, I get errors when trying to build.
>
> Do I need to link an opengl.dll file, too?

No, you do not need to link to OpenGL. By default, Derelict loads shared libraries at runtime so you will never have a link-time dependency on the C libraries Derelict binds to.

Please post the errors you are seeing.


September 03, 2016
Thanks for the information.  The errors for the tutorial I _was_ trying to make work are as follows:

source\app.d(9,5): Error: undefined identifier 'Window', did you mean variable 'window'?
source\app.d(98,12): Error: undefined identifier 'Window', did you mean variable 'window'?
source\app.d(101,14): Error: undefined identifier 'GLBuffer'
source\app.d(104,14): Error: undefined identifier 'Shader'
source\app.d(107,13): Error: undefined identifier 'Program', did you mean variable 'program'?
source\app.d(110,15): Error: undefined identifier 'Attribute'

I thought I might have needed another package for these, and gfm seemed to contain what I need in the form of the opengl sub-package.  But even after importing that, it only gets rid of the GLBuffer error.

I tried to follow another tutorial.  Link to source code: http://www.learnopengl.com/code_viewer.php?code=getting-started/hellotriangle

I'm having more success with this one.  I pretty much hacked away at this and did my best to convert from C-style code to D.  The window gets made and it has the green-ish background, but it's not drawing any triangles.  Should I copy/paste the code I'm using in case I made a mistake?
September 03, 2016
On Saturday, 3 September 2016 at 09:30:58 UTC, Darren wrote:
> Thanks for the information.  The errors for the tutorial I _was_ trying to make work are as follows:
>
> source\app.d(9,5): Error: undefined identifier 'Window', did you mean variable 'window'?
> source\app.d(98,12): Error: undefined identifier 'Window', did you mean variable 'window'?
> source\app.d(101,14): Error: undefined identifier 'GLBuffer'
> source\app.d(104,14): Error: undefined identifier 'Shader'
> source\app.d(107,13): Error: undefined identifier 'Program', did you mean variable 'program'?
> source\app.d(110,15): Error: undefined identifier 'Attribute'
>
> I thought I might have needed another package for these, and gfm seemed to contain what I need in the form of the opengl sub-package.  But even after importing that, it only gets rid of the GLBuffer error.
>
> I tried to follow another tutorial.  Link to source code: http://www.learnopengl.com/code_viewer.php?code=getting-started/hellotriangle
>
> I'm having more success with this one.  I pretty much hacked away at this and did my best to convert from C-style code to D.
>  The window gets made and it has the green-ish background, but it's not drawing any triangles.  Should I copy/paste the code I'm using in case I made a mistake?

It's not quite in a practically-usable state yet, but the SDL2 & OpenGL wrapper I'm working on may interest you as an example implementation if nothing else. https://github.com/pineapplemachine/mach.d/tree/master/mach/sdl

Here's an example of a functioning program using the package. At the moment I'm working on exposing SDL2's event and other input systems.

    import std.datetime;
    import mach.math.vector2;
    import mach.sdl.window;
    import mach.sdl.texture;
    import mach.sdl.color;
    import mach.sdl.primitives;

    void main(){
        // Create a window
        auto win = new Window(300, 300);
        win.position = Vector2!int(200, 200);
        // Load a texture
        auto tex = Texture("pineapple.png");
        // Loop for 5 seconds
        StopWatch sw;
        sw.start();
        auto maxms = 5000f;
        while(true){
            auto ms = sw.peek().msecs;
            if(ms >= maxms) break;
            // Fill with green
            win.clear(0, ms / maxms / 2, 0);
            // Draw centered image
            tex.draw((win.size - tex.size) / 2);
            // Draw red lines at top and bottom
            lines(Color!ubyte.Red,
                Vector2!int(8, 8), Vector2!int(292, 8),
                Vector2!int(292, 292), Vector2!int(8, 292)
            );
            // Display changes
            win.swap();
        }
    }

September 03, 2016
> It's not quite in a practically-usable state yet, but the SDL2 & OpenGL wrapper I'm working on may interest you as an example implementation if nothing else. https://github.com/pineapplemachine/mach.d/tree/master/mach/sdl

I'm going to take a look at this, once I get my bearings, on the merits of the name alone!
I'm sure there are a few tutorials that make use of SDL2 that I can use.  My hope is that once I know how to set up, learning OpenGL will be more a matter of D-ifying the C-code.

I'll post the modified code I'm trying to get work in full below.
Some code is commented out because I couldn't make it work.  Also any tips for making the code nicer would be welcome (e.g. would I change the const GLunit into enums?).

#####

import derelict.glfw3.glfw3;
import derelict.opengl3.gl3;
import std.stdio;

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}

const GLuint WIDTH = 800, HEIGHT = 600;

const GLchar* vertexShaderSource = "#version 330 core\n"
    "layout (location = 0) in vec3 position;\n"
    "void main()\n"
    "{\n"
    "gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
    "}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
    "out vec4 color;\n"
    "void main()\n"
    "{\n"
    "color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
    "}\n\0";

void main()
{
    DerelictGLFW3.load();
    DerelictGL3.load();
	
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", null, null);
    glfwMakeContextCurrent(window);
	
    DerelictGL3.reload();

    //glfwSetKeyCallback(window, key_callback);

    int width, height;
    glfwGetFramebufferSize(window, &width, &height);
    glViewport(0, 0, width, height);

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, null);
    glCompileShader(vertexShader);
	
    GLint success;
    GLchar[512] infoLog;
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        //glGetShaderInfoLog(vertexShader, 512, null, infoLog);
        writeln("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n", infoLog);
    }

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, null);
    glCompileShader(fragmentShader);

    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        //glGetShaderInfoLog(fragmentShader, 512, null, infoLog);
        writeln("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n", infoLog);
    }

    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        //glGetProgramInfoLog(shaderProgram, 512, null, infoLog);
        writeln("ERROR::SHADER::PROGRAM::LINKING_FAILED\n", infoLog);
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    GLfloat[] vertices = [
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f,  0.5f, 0.0f
    ];
    GLuint VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, vertices.sizeof, cast(void*)vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * GLfloat.sizeof, cast(GLvoid*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glBindVertexArray(0);
        glfwSwapBuffers(window);
    }

    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glfwTerminate();
}
September 03, 2016
On Saturday, 3 September 2016 at 10:30:13 UTC, Darren wrote:
> [...]

I never used OpenGL in D, but from a quick glance at your code, I'll suggest trying the following changes:

>         //glGetShaderInfoLog(vertexShader, 512, null, infoLog);

glGetShaderInfoLog(vertexShader, 512, null, &infoLog[0]);

>     //glfwSetKeyCallback(window, key_callback);

glfwSetKeyCallback(window, &key_callback);
September 03, 2016
On Saturday, 3 September 2016 at 11:02:11 UTC, Lodovico Giaretta wrote:
>
>>//glGetShaderInfoLog(vertexShader, 512, null, infoLog);
>
> glGetShaderInfoLog(vertexShader, 512, null, &infoLog[0]);

Thank you, I knew I had to do something like this!

>
>>//glfwSetKeyCallback(window, key_callback);
>
> glfwSetKeyCallback(window, &key_callback);

I actually tried this before but it doesn't work.  I get the following error:

Error: function pointer glfwSetKeyCallback (GLFWwindow*, extern (C) void function(GLFWwindow*, int, int, int, int) nothrow) is not callable using argument types (GLFWwindow*, void function(GLFWwindow* window, int key, int scancode, int action, int mode))


September 03, 2016
On Saturday, 3 September 2016 at 11:10:00 UTC, Darren wrote:
> On Saturday, 3 September 2016 at 11:02:11 UTC, Lodovico Giaretta wrote:
>>>//glfwSetKeyCallback(window, key_callback);
>>
>> glfwSetKeyCallback(window, &key_callback);
>
> I actually tried this before but it doesn't work.  I get the following error:
>
> Error: function pointer glfwSetKeyCallback (GLFWwindow*, extern (C) void function(GLFWwindow*, int, int, int, int) nothrow) is not callable using argument types (GLFWwindow*, void function(GLFWwindow* window, int key, int scancode, int action, int mode))

Ah! Well, providing error messages is always useful. Now I see your issue: your callback has D linkage, but OpenGL expects a function with C linkage. So you have to put `extern(C)` on your callback declaration.
September 03, 2016
On Saturday, 3 September 2016 at 11:13:30 UTC, Lodovico Giaretta wrote:
> 
> Ah! Well, providing error messages is always useful. Now I see your issue: your callback has D linkage, but OpenGL expects a function with C linkage. So you have to put `extern(C)` on your callback declaration.

Well, it's GLFW, not OpenGL, but yes they do need to be extern (C) and also nothrow, as that is how the callback types are declared in Derrlict:

```
extern(C) nothrow
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}
```
September 03, 2016
On Saturday, 3 September 2016 at 11:27:09 UTC, Mike Parker wrote:
> On Saturday, 3 September 2016 at 11:13:30 UTC, Lodovico Giaretta wrote:
>> 
>> Ah! Well, providing error messages is always useful. Now I see your issue: your callback has D linkage, but OpenGL expects a function with C linkage. So you have to put `extern(C)` on your callback declaration.
>
> Well, it's GLFW, not OpenGL, but yes they do need to be extern (C) and also nothrow, as that is how the callback types are declared in Derrlict:
>
> ```
> extern(C) nothrow
> void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) {
>     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
>         glfwSetWindowShouldClose(window, GL_TRUE);
> }
> ```

Hey, it worked!  Thanks a lot, I know what to do in the future now.  Just need to figure out why this triangle isn't showing up and I should be well on my way.
« First   ‹ Prev
1 2 3