Author Topic: [c] Trying on OpenGL 3..  (Read 7657 times)

0 Members and 1 Guest are viewing this topic.

Offline mziskandar

  • C= 64
  • **
  • Posts: 46
  • Karma: 1
    • View Profile
[c] Trying on OpenGL 3..
« on: June 14, 2009 »
 :hi:

I'm trying to learn OpenGL 3 right now. Here's the code to share.. using CodeBlocks, glut and glew (1.5.1)

Code: [Select]
#include <GL/glew.h>
#include <GL/glut.h>
#include <stdio.h>

const GLchar* vshaderSrc = "in vec3 pos;void main(){gl_Position = vec4(pos, 1);}";
const GLchar* fshaderSrc = "out vec4 color;void main(){color = vec4(1, 0.1, 0, 1);}";

GLuint compileShader(GLenum shaderType, const GLchar* source)
{
    GLuint shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, &source, NULL);
    glCompileShader(shader);
    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (!status) {
        printf("shader compile error");
        return 0;
    }
    return shader;
}


static void resize(int width, int height)
{
    const float ar = (float) width / (float) height;
    glViewport(0, 0, width, height);
}

void display(void) {

const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
    const double a = t*90.0;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* glLoadIdentity(); // mess
glRotatef( a*10, 1.0, 0.0, 0.0 ); // mess

glEnableClientState(GL_VERTEX_ARRAY); // mess */

glPolygonMode(GL_FRONT, GL_LINE);
glDrawArrays(GL_TRIANGLES, 0, 3);

// glDisableClientState(GL_VERTEX_ARRAY); // mess
    glutSwapBuffers();
}

void key(unsigned char key, int x, int y) {
if (key == 27)
exit(0);
glutPostRedisplay();
}

static void idle(void)
{
    glutPostRedisplay();
}

int main(int argc, char** argv) {
glutInit(&argc, argv);
    glutInitWindowSize(640,480);
    glutInitWindowPosition(10,10);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    glutCreateWindow("GLUT Shapes");

    glutReshapeFunc(resize);
    glutDisplayFunc(display);
    glutKeyboardFunc(key);
    glutIdleFunc(idle);

    glewExperimental = GL_TRUE; // this is needed for GLEW 1.5.1 to work correctly with OpenGL 3.0 context
    if (glewInit() != GLEW_OK) {
        printf("sglewExperimental error");
        return 1;
    }

    glewInit();

    // OpenGL init
    GLuint vshaderID = compileShader(GL_VERTEX_SHADER, vshaderSrc);
    GLuint fshaderID = compileShader(GL_FRAGMENT_SHADER, fshaderSrc);

    GLuint programID = glCreateProgram();
    glAttachShader(programID, vshaderID);
    glAttachShader(programID, fshaderID);
    glLinkProgram(programID);
    GLint status;
    glGetProgramiv(programID, GL_LINK_STATUS, &status);
    if (!status) {
        printf("GL_LINK_STATUS error");
    }

    // VAO
    GLuint vertexArrayID;
    glGenVertexArrays(1, &vertexArrayID);
    glBindVertexArray(vertexArrayID);

    // VBO
    GLuint bufferID;
    glGenBuffers(1, &bufferID);
    glBindBuffer(GL_ARRAY_BUFFER, bufferID);
    float vertexData[] = { 0.0f, 0.5f, 0.0f,  -0.5f, -0.5f, 0.0f,  0.5f, -0.5f, 0.0f };
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

    const GLuint posIndex = glGetAttribLocation(programID, "pos");

    glVertexAttribPointer(posIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posIndex);
    glUseProgram(programID);

    glutMainLoop();

    return 0;

}

Now I am stuck.. trying to rotate the triangle  ??? ... when done  :D , next step will be using gl3.h only.. no glut and glew..  ::)

Any tips/ideas how?

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [c] Trying on OpenGL 3..
« Reply #1 on: June 14, 2009 »
To get rid of glut you will need to manage your own window.
To create a window you need to know 3 things.
1) You need to register a window class using RegisterClass()
2) You need to create a window using CreateWindow()
3) You need a window proc, usually called WindowProc to handle the messages like the window size changing (message WM_SIZE), key presses (WM_KEYUP/WM_KEYDOWN) etc.

Let me know if you need more help with that - there are examples for doing that on here for DirectX (virtually identical setup), eg. http://www.dbfinteractive.com/forum/index.php/topic,1536.0.html

Jim
Challenge Trophies Won:

Offline mziskandar

  • C= 64
  • **
  • Posts: 46
  • Karma: 1
    • View Profile
Re: [c] Trying on OpenGL 3..
« Reply #2 on: June 14, 2009 »
Hi Jim..

For previous version of OpenGL I'm not using glut and glew - directly "glext.h". I'm a little confused about creating context in OpenGL 3 - That's why I'm using glew right now.

This is another code without glut and glew.. quite messy - experimenting..

I'm trying to understand this: Create gl3 context > vao > vbo > attached shader > object manipulation (eg: rotation, translate, etc)

Code: [Select]
#include <windows.h>
#include <gl/gl3.h>
#include <gl/wglext.h> //should i remove this?
#include <stdio.h>

char szAppName[] = "3D Viewer";
HWND  hWnd;
HDC   hDC;
HGLRC hRC;

#define WIDTH 640
#define HEIGHT 320

GLvoid drawScene(GLvoid);
GLvoid createObjects(GLvoid);

LONG WINAPI MainWndProc (HWND, UINT, WPARAM, LPARAM);

const GLchar* vshaderSrc = "in vec3 pos;void main(){gl_Position = vec4(pos, 1);}";
const GLchar* fshaderSrc = "out vec4 color;void main(){color = vec4(1, 0.1, 0, 1);}";

PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;

PFNGLCREATESHADERPROC glCreateShader = NULL;
PFNGLSHADERSOURCEPROC glShaderSource = NULL;
PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
PFNGLCOMPILESHADERPROC glCompileShader = NULL;

PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
PFNGLATTACHSHADERPROC glAttachShader = NULL;
PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL;
PFNGLGENBUFFERSPROC glGenBuffers = NULL;
PFNGLBINDBUFFERPROC glBindBuffer = NULL;
PFNGLBUFFERDATAPROC glBufferData = NULL;
PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL;

PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL;
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL;
PFNGLUSEPROGRAMPROC glUseProgram = NULL;

PFNGLDRAWARRAYSPROC glDrawArrays = NULL;
PFNGLCLEARPROC glClear = NULL;

GLuint compileShader(GLenum shaderType, const GLchar* source)
{
    GLuint shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, &source, NULL);
    glCompileShader(shader);
    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (!status) {
        printf("shader compile error");
        return 0;
    }
    return shader;
}



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
WNDCLASS wndclass;

// Register the frame class
wndclass.style         = 0;
wndclass.lpfnWndProc   = (WNDPROC)MainWndProc;
wndclass.cbClsExtra    = 0;
wndclass.cbWndExtra    = 0;
wndclass.hInstance     = hInstance;
wndclass.hIcon         = LoadIcon(hInstance, szAppName);
wndclass.hCursor       = LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wndclass.lpszMenuName  = szAppName;
wndclass.lpszClassName = szAppName;

if (!RegisterClass(&wndclass)) return FALSE;

// Create the frame
hWnd = CreateWindow ( szAppName,
"3D Viewer for Ababil",
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
CW_USEDEFAULT,
CW_USEDEFAULT,
WIDTH, HEIGHT,
NULL, NULL,
hInstance, NULL );

if (!hWnd){
MessageBox(NULL,"Windows creation failed", "Error",MB_OK);
return FALSE;
}

hDC = GetDC(hWnd);

PIXELFORMATDESCRIPTOR pfd, *ppfd;
int pixelformat;
ppfd = &pfd;

ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
ppfd->nVersion = 1;
ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
ppfd->dwLayerMask = PFD_MAIN_PLANE;
ppfd->iPixelType = PFD_TYPE_COLORINDEX;
ppfd->cColorBits = 16;
ppfd->cDepthBits = 16;
ppfd->cAccumBits = 0;
ppfd->cStencilBits = 0;

pixelformat = ChoosePixelFormat(hDC, ppfd);

if((pixelformat = ChoosePixelFormat(hDC, ppfd)) == 0)
{
MessageBox(NULL,"ChoosePixelFormat failed", "Error",MB_OK);
return 0;
}

if(SetPixelFormat(hDC, pixelformat, ppfd) == FALSE)
{
MessageBox(NULL,"SetPixelFormat failed", "Error",MB_OK);
return 0;
}

ShowWindow(hWnd, nCmdShow);
//UpdateWindow(hWnd);


HGLRC tempContext = wglCreateContext(hDC);
    wglMakeCurrent(hDC,tempContext);

    int attribs[] =
    {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,//we want a 3.0 context
        WGL_CONTEXT_MINOR_VERSION_ARB, 0,
        //and it shall be forward compatible so that we can only use up to date functionality
        WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
        0
    }; //zero indicates the end of the array

    PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL; //pointer to the method
    wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB");
    if (wglCreateContextAttribsARB == NULL) //OpenGL 3.0 is not supported
    {
        MessageBox(NULL,"Cannot get Proc Adress for CreateContextAttribs", "ERROR",MB_OK);
        wglDeleteContext(tempContext);
        return 0;
    }

    if (!(hRC=wglCreateContextAttribsARB(hDC,0, attribs)))
    {
        wglDeleteContext(tempContext);
        MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
        return 0;
    }
    wglDeleteContext(tempContext);

    if (!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
    {
        MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
        return 0;
    }

    //ShowWindow(hWnd,SW_SHOW); // Show The Window
    //SetForegroundWindow(hWnd); // Slightly Higher Priority
    //SetFocus(hWnd); // Sets Keyboard Focus To The Window


    //createObjects();

glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");
glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource");
glGetShaderiv = (PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv");
glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");

glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");
glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram");
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)wglGetProcAddress("glGetProgramiv");
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays");
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray");
glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");

glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation");
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray");
glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram");

GLuint vshaderID = compileShader(GL_VERTEX_SHADER, vshaderSrc);
    GLuint fshaderID = compileShader(GL_FRAGMENT_SHADER, fshaderSrc);

    GLuint programID = glCreateProgram();
    glAttachShader(programID, vshaderID);
    glAttachShader(programID, fshaderID);
    glLinkProgram(programID);
    GLint status;
    glGetProgramiv(programID, GL_LINK_STATUS, &status);
    if (!status) {
        printf("GL_LINK_STATUS error");
    }

    // VAO
    GLuint vertexArrayID;
    glGenVertexArrays(1, &vertexArrayID);
    glBindVertexArray(vertexArrayID);

    // VBO
    GLuint bufferID;
    glGenBuffers(1, &bufferID);
    glBindBuffer(GL_ARRAY_BUFFER, bufferID);
    float vertexData[] = { 0.0f, 0.5f, 0.0f,  -0.5f, -0.5f, 0.0f,  0.5f, -0.5f, 0.0f };
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

    const GLuint posIndex = glGetAttribLocation(programID, "pos");
    // this binds currently binded VBO to VAO
    glVertexAttribPointer(posIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posIndex);
    glUseProgram(programID);

    glDrawArrays = (PFNGLDRAWARRAYSPROC)wglGetProcAddress("glDrawArrays");
glClear = (PFNGLCLEARPROC)wglGetProcAddress("glClear");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);

SwapBuffers(hDC);

while (1)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
{
if (GetMessage(&msg, NULL, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
return 1;
}
}
//drawScene();
}
}

LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
{
break;
}

    case WM_PAINT:
{
//drawScene();
break;
}

        case WM_CLOSE:
        /*if (hRC) wglDeleteContext(hRC);
if (hDC) ReleaseDC(hWnd, hDC);
hRC = 0;
hDC = 0;
DestroyWindow(hWnd);*/
            PostQuitMessage(0);
        break;

        case WM_DESTROY:
        /*if (hRC) wglDeleteContext(hRC);
if (hDC) ReleaseDC(hWnd, hDC);*/
            return 0;

        case WM_KEYDOWN:
        {
            switch (wParam)
            {
                case VK_ESCAPE:
                    PostQuitMessage(0);
                break;
            }
        }
        break;

        default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }

    return 0;
}

Offline ferris

  • Pentium
  • *****
  • Posts: 841
  • Karma: 84
    • View Profile
    • Youth Uprising Home
Re: [c] Trying on OpenGL 3..
« Reply #3 on: June 15, 2009 »
For your vertex shader, try something more like:

Code: [Select]
gl_Position = ftransform();

which is [roughly] the [unoptimized] equivalent to:

Code: [Select]
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// ^ NOTE: MATRIX MULTIPLICATION *IS* ORDER-SENSITIVE

That should make whatever you're drawing correctly transformed as necessary.

Also, why are there the "in" and "out" var's? They're not necessary nor are they correct to my knowledge..
« Last Edit: June 15, 2009 by Ferris »
http://iamferris.com/
http://youth-uprising.com/

Where the fun's at.
Challenge Trophies Won:

Offline ferris

  • Pentium
  • *****
  • Posts: 841
  • Karma: 84
    • View Profile
    • Youth Uprising Home
Re: [c] Trying on OpenGL 3..
« Reply #4 on: June 15, 2009 »
Also, the OGL 3 spec's really aren't different than the OGL 2.1 specs except for geometry shaders...so thus far you're only working with OGL2 to clarify ;)
« Last Edit: June 15, 2009 by Ferris »
http://iamferris.com/
http://youth-uprising.com/

Where the fun's at.
Challenge Trophies Won:

Offline mziskandar

  • C= 64
  • **
  • Posts: 46
  • Karma: 1
    • View Profile
Re: [c] Trying on OpenGL 3..
« Reply #5 on: June 15, 2009 »
Hi Ferris...

The "in and "out" is just testing.. found it somewhere in some forum - I can't recall where, it doesn't effect either its included or not as far as I know.  :trans:

From what I've read... "It turns out it's not that straight forward. Essentially what we need to do is to call wglCreateContextAttribsARB instead of wglCreateContext, the tricky part is that wglCreateContextAttribsARB is an extension and to be able to use it with the help of wglGetProcAddress we need a rendering context, which is exactly what wglCreateContextAttribsARB does, so we need to trick it." - http://flashbang.se/index.php?id=56

I'm also not sure on how to properly/efficiently shading polygons.. then manipulate it..  :carrot:

Offline ferris

  • Pentium
  • *****
  • Posts: 841
  • Karma: 84
    • View Profile
    • Youth Uprising Home
Re: [c] Trying on OpenGL 3..
« Reply #6 on: June 15, 2009 »
The in/out thing works in function variables ("void func(in x,out y,inout z) {...") but for globals from the program uniforms are used. If you're just getting a white poly on screen, chances are that even though your frag shader is making white pixels, an error has occurred in the shader compilation which means code error 99 percent of the time on cards that support the shader model (In making two-triangle 4k's, we use straight colored quads to tell us our shader isn't working properly).

Edit: Just looked again and noticed your code checks for compilation errors, so disregard that white poly thing.

Try this:
Code: [Select]
const GLchar* vshaderSrc = "void main(){gl_Position = ftransform();}";
const GLchar* fshaderSrc = "void main(){gl_FragColor = vec4(1, 0.1, 0, 1);}";

I'd be surprised if your code worked before...this new code is the OGL spec correct way.

But one thing that puzzles me is that when your code is incorrectly compiled, OpenGL will default to the fixed-functionality rendering pipeline, where the glRotate command would work as planned anyway.
http://iamferris.com/
http://youth-uprising.com/

Where the fun's at.
Challenge Trophies Won:

Offline mziskandar

  • C= 64
  • **
  • Posts: 46
  • Karma: 1
    • View Profile
Re: [c] Trying on OpenGL 3..
« Reply #7 on: June 15, 2009 »
Ahh.. no wonder the second code (without glut and glew) takes few sec even to pop a white window..  :o
Thanks Ferris.. I will try again..

attached, is the first code + bin (with glut and glew)

Offline mziskandar

  • C= 64
  • **
  • Posts: 46
  • Karma: 1
    • View Profile
Re: [c] Trying on OpenGL 3..
« Reply #8 on: June 26, 2009 »
..and finally (last week) I found out that my gfx didn't support opengl 3 (100%).. sticking to 2.1  :bananaphallus: