Help with C++ and OpenGL Code

Started by
7 comments, last by erissian 16 years, 9 months ago
EDIT: UPDATED CODE Hello, I am trying to write some terrain code at the moment and this is what i have so far: Main.cpp:

#define WIN32_LEAN_AND_MEAN

#include "Main.h"

using namespace std;

HINSTANCE	hInstance;
HDC gHDC;

void SetupPixelFormat(HDC hDC)
{
    int nPixelFormat;

    static PIXELFORMATDESCRIPTOR pfd={
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW |
        PFD_SUPPORT_OPENGL |
        PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,
        32,
        0, 0, 0, 0, 0, 0,
        0,
        0,
        0,
        0, 0, 0, 0,
        16,
        0,
        0,
        PFD_MAIN_PLANE,
        0,
        0, 0, 0,};

        nPixelFormat=ChoosePixelFormat(hDC, &pfd);
        SetPixelFormat(hDC, nPixelFormat, &pfd);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HGLRC hRC;               //Rendering Context
    static HDC hDC;                 //Device Context
    int width, height;
    PAINTSTRUCT paintStruct;
    switch(message)
    {
        case WM_CREATE:
        {
            hDC=GetDC(hwnd);
            gHDC=hDC;
            SetupPixelFormat(hDC);
            hRC=wglCreateContext(hDC);
            wglMakeCurrent(hDC, hRC);
            break;
        }
        case WM_CLOSE:
        {
            wglMakeCurrent(hDC, NULL);
            wglDeleteContext(hRC);
            PostQuitMessage(0);
            return true;
        }
        case WM_PAINT:
        {
            hDC=BeginPaint(hwnd, &paintStruct);

//            Change text colour to blue
//            SetTextColor(hDC, COLORREF(0x00FF000));
//
//            Write text in middle of window
//            TextOut(hDC, 100, 125, string, sizeof(string)-1);

            EndPaint(hwnd, &paintStruct);
            return 0;
            break;
        }
        case WM_SIZE:
        {
            height=HIWORD(lParam);  //Get height and width of window
            width=LOWORD(lParam);

            Resize(height, width);
        }

        default:
            break;
    }
    //Pass all unhandled messages to DefWindowProc
    return DefWindowProc(hwnd, message, wParam, lParam);
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    MSG msg;
    bool done=false;

    MakeWindow("Confusing Compounds", 300, 300);
    Init();

    while(!done)
    {
        Render();
        SwapBuffers(gHDC);
        PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);

        if(msg.message==WM_QUIT)
        {
            done=true;
        }

            TranslateMessage(&msg);
            DispatchMessage(&msg);

    }
    return msg.wParam;

    return true;
}

bool MakeWindow(char* name, int height, int width)
{
    WNDCLASSEX windowClass;
    HWND hwnd;

    windowClass.cbSize=sizeof(WNDCLASSEX);
    windowClass.style=CS_VREDRAW | CS_HREDRAW;
    windowClass.lpfnWndProc=WndProc;
    windowClass.cbClsExtra=0;
    windowClass.cbWndExtra=0;
    windowClass.hInstance=hInstance;
    windowClass.hIcon=LoadIcon(NULL, IDI_WINLOGO);
    windowClass.hCursor=LoadCursor(NULL, IDC_ARROW);
    windowClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    windowClass.lpszMenuName=NULL;
    windowClass.lpszClassName="MyWinClass";
    windowClass.hIconSm=LoadIcon(NULL, IDI_WINLOGO);

    //Register the window class
    if(!RegisterClassEx(&windowClass))
    {
        return false;
    }

    hwnd=CreateWindowEx(NULL, "MyWinClass", name, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                            0, 0, height, width, NULL, NULL, hInstance, NULL);

    if(!hwnd)
    {
        return false;
    }

    ShowWindow(hwnd, SW_SHOW);
    UpdateWindow(hwnd);
	}

void PauseGame(int pause)
{
    int time=GetTickCount();
    if(GetTickCount()-time>=pause)
    {
        time=GetTickCount();
    }
}

void Resize(int height, int width)
{
            if(height==0)   //Stops divide by zeroes
            {
                height=1;
            }

            //Reset the viewport with the new dimensions
            glViewport(0, 0, width, height);
            glMatrixMode(GL_PROJECTION); //Make the projection matrix the current matrix
            glLoadIdentity();   //Reset projection matrix

            //Calculate aspect ratio of window
            gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 1.0f, 1000.0f);

            glMatrixMode(GL_MODELVIEW); //Make the modelview matrix the current matrix
            glLoadIdentity(); //Reset modelview matrix
}





Main.h:

#ifndef MAIN_H
#define MAIN_H

#include <iostream>
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>

void Render();
void Init();
bool MakeWindow(char* name, int height, int width);
void PauseGame(int);
void Resize(int, int);

#endif






Graphics.cpp:

#include "Main.h"
#include "Graphics.h"

using namespace std;

void Render()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(-1.0, 0.0, -1.0);

    for(float i=0.0; i<128; i++)
    {
        for(float j=0.0; j<128; j++)
        {
            switch(black)
            {
                case true:
                    color=0.0;
                    black=false;
                    break;

                case false:
                    color=1.0;
                    black=true;
                    break;
            }
            glBegin(GL_POINTS);
                glColor3f(color, color, color);
                glVertex3f(i, j, terrainHeight[j]);
            glEnd();
            zDepth-=0.5;
        }
        zDepth=-1;
    }
    black=false;
    zDepth=-1.0;
}

void Init()
{
    glClearColor(0.3, 0.7, 0.1, 0.0);
//    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    for(int i=0; i<128; i++)
    {
        for(int j=0; j<128; j++)
        {
            terrainHeight[j]=-1;
            cout<<terrainHeight[j]<<endl;
        }
    }
}







Graphics.h:

#ifndef GRAPHICS_H
#define GRAPHICS_H

#include <iostream>

bool black=true;
float color=0.0;
float zDepth=-1;
float terrainHeight[128][128]={0, 0};
#endif






There are two main things I am looking for help with. 1) I want to only have to draw one line where two square edges meet, so I'm not drawing as many lines. 2) I want to be able to add height to the terrain. And also any general code cleanliness help would be appreciated. Thanks for any help you can give me, Ser Bob [Edited by - Ser Bob on July 10, 2007 5:16:10 AM]
Advertisement
ugh, i wrote quite a long reply to this but then IE crashed :/

for your second problem, consider representing the terrain by a 2d array of points, eg

float myTerrain[128][128];

and then in this array you store the heights of the vertices of the the terrain

for(int i...128)
for(int j...128)
myTerrain[j] = whatever;

when rendering, you then use this data....

for(int i...128)
for(int j...128)
...
glVertex3f(i,j,myTerrain[j]);
...


obviously you can scale the i and j positions as your design requires.

EDIT: theres a pretty good nehe example for this.
Thanks Winegums,

I tried that and I am getting this error "Invalid types 'float[128][128][float]' for array subscript." Do you know what might be causing it?

Thanks for all your help.

Ser Bob
Are you using positive integers for your array indices? I looks like you have something like "some_array[5][43][6.5]" Does your compiler tell you which error the line is on? Post that too.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Hi Erissian,

The error is on line 30 of graphics.cpp, which is this:

glVertex3f(i, j, terrainHeight[j]);

terrainHeight was declared as:

float terrainHeight[128][128]={0, 0};

I have updated the code in the first post.

Ser Bob.
Ah, there you go. i and j are both floats, which you can't use for an array index.

The best way to do this would be to change i and j to ints, and then cast them like this:
glVertex3f( (float)i, (float)j, arrayHeight[j] );


Also, as a style note, here's how I would arrange that function:

Note: was sDepth used anywhere?

void Render(){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glLoadIdentity();    glTranslatef(-1.0, 0.0, -1.0);    black = false;    glBegin(GL_POINTS);    for(int i=0; i<128; i++)    {        for(int j=0; j<128; j++)        {            if (black) {              glColor3f( 0.0f, 0.0f, 0.0f );            } else {              glColor3f( 1.0f, 1.0f, 1.0f );            }            black = !black;            glVertex3f((float)i, (float)j, terrainHeight[j]);        }    }    glEnd();}
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
OP: Just so you know, don't update your original post, make a new one. This way others can learn from your original code and see the progression. Thanks.

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

Hello again, this is my current graphics loop

glBegin(GL_TRIANGLE_STRIP);{   for(int i=0; i<5; i++)   {      for(int j=0; j<2; j++)      {         Colour();                  glColor3f(color, color, color);         glVertex3f(i, j, terrainHeight[j]);       }   }}glEnd();


I changed it to triangles so I had a bit more flexiblity with the shape of the land.

The main problem with it is that I cant draw any more than one row or else it will mess up. I figure I need to glEnd() the code at the end of every row but I am just having trouble implementing it. Any ideas?
Colour();glColor3f(color, color, color);for(int i=0; i<NUM_STRIPS; i++) {  glBegin(GL_TRIANGLE_STRIP);    for(int j=0; j<STRIP_LENGTH; j++) {         glVertex3f(i,   j, terrainHeight[j]);         glVertex3f(i+1, j, terrainHeight[j]);    }  glEnd();}


Roughly, anyways. This may be a good time to start investigating Vertex Buffer Objects.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)

This topic is closed to new replies.

Advertisement