Thitorkin Skrevet 15. mai 2011 Del Skrevet 15. mai 2011 Eg tror eg kan konsollen ganske bra/ bra nok nå, hvor bør eg starte med OpenGL? Eg vet hvordan man lager vindu med "hello world!" og hvordan man kan vise diverse figurer på skjermen; men alt dette er fra tutorials som eg har sett på nettet. Og for å vere ærlig så kan eg ikke såå mye. Har litt kontroll og kan lage en tilfeldig firkant, med tilfeldige punkter osv. Samme går for de andre figurene, hvertfall mesteparten. Det eg ønsker å lage er en terrain generator, men tror det er lenge til... Så for å lage en terrain generator, hva må eg kunne? Selv tenker eg kamera kontroll, og tilfeldig plasserte vertex, men eg vet ikke hva annet Takk på forhånd for alle svar. Lenke til kommentar
GeirGrusom Skrevet 16. mai 2011 Del Skrevet 16. mai 2011 (endret) Generering av terreng er et ganske stort prosjekt alene avhengig av hva du skal gjøre. Å bare generere en enkel seksjon med høyde-basert terreng er derimot ikke så vanskelig. Det blir ganske så mye verre når en detter borti geometry mip-maps, eller hvis en går så lang at en vil ha terreng som støtter overheng (vet dog ikke om et eneste sted dette noensinne er blitt gjort) Men begynn først med å bare lage et helt statisk enkel terreng seksjon. i = 0; for(x in 0 to xcount) for(y in 0 to ycount) { addvertex(x * cellwidth, y * cellwidth) if(x < (xcount - 1) and y < (ycount - 1)) { addtriangle(i, i + 1, i + xcount) addtriangle(i, i + xcount, i + xcount + 1) } } Noe slikt tenker jeg. Når du får det til å funke, kan du begynne å kikke på quadtree og octree algoritmene. Endret 16. mai 2011 av GeirGrusom 1 Lenke til kommentar
Thitorkin Skrevet 16. mai 2011 Forfatter Del Skrevet 16. mai 2011 Takk for svar GeirGrusom! Skal prøve den koden du har der sammen med resten av OpenGL programmet mitt Lenke til kommentar
Thitorkin Skrevet 16. mai 2011 Forfatter Del Skrevet 16. mai 2011 (endret) Koden fungerte i stad, før eg satte inn diverse void istedefor å ha alt i main funksjonen, og nå kommer det ingenting i vinduet slik det skulle. Eg aner ikke hva eg gjorde galt, noen som kan fortelle meg? #include <iostream> #include <stdlib.h> //Needed for "exit" function //Include OpenGL for Win/Mac #ifdef __APPLE__ #include <OpenGL/OpenGL.h> #include <GLUT/glut.h> #else #include <glut.h> #endif using namespace std; void handleKeypress(unsigned char key, int x, int y) { switch (key) { case 27: //Escape key exit(0); } } void DepthTest() { glEnable(GL_DEPTH_TEST); } //Called when the window is resized void handleResize(int w, int h) { //Tell OpenGL how to convert from coordinates to pixel values glClearColor(0.0, 0.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); } //Draws the Terrain void TerrainDraw() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glBegin(GL_TRIANGLES); glVertex3f(0.25, 0.25, 0.0); glVertex3f(0.75, 0.75, 0.0); glEnd(); glFlush(); } void GlutInit (int argc, char** argv){ //Initialize GLUT glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(200, 200); //Set the window size glutInitWindowPosition(200, 200); } void CreateAll(){ //Create the window cout << "Creating basic window..\n"; glutCreateWindow("Terrain Generator V.00001"); cout << "Succes, basic window created!\n"; cout << "testing depth..\n"; DepthTest(); cout << "Depth succesully tested!\n"; cout << "Drawing terrain...\n"; glutDisplayFunc(TerrainDraw); cout << "Terrain drawn on screen!\n"; cout << "Initializing keyboard functions..\n"; glutKeyboardFunc(handleKeypress); cout << "Keyboard succesfully initialized!\n"; glutReshapeFunc(handleResize); } int main(int argc, char** argv) { cout << " **********CONSOLE STARTED!**********\n\n\n"; cout << "initializing OpenGL..standby..\n"; GlutInit; cout << "Succes OpenGL initiated and Window size set to 200 by 200!\n"; cout << "Trying to create window..standby..\n"; CreateAll(); cout << "Succes, window created!"; glutMainLoop(); return 0; } Mhm prøvde å tegne en trekant med denne: glBegin(GL_TRIANGLES); glVertex3f(100.0f, 100.0f, 0.0f); glVertex3f(150.0f, 100.0f, 0.0f); glVertex3f(125.0f, 50.0f, 0.0f); glEnd( ); Og bortsett fra at skjermen ble hvit istedefor svart var det ikke til noen særlig nytte.. EDIT: Og prøver å forandre glutInitWindowSize(200, 200); til glutInitWindowSize(600, 400); Men vinduet er fremdeles like stort og sitter i hjørnet.. Endret 16. mai 2011 av Gabbe Lenke til kommentar
GeirGrusom Skrevet 16. mai 2011 Del Skrevet 16. mai 2011 glBegin(GL_TRIANGLES); { glVertex3f(0, 1, 0); glVertex3f(1, 1, 0); glVertex3f(1, 0, 0); } glEnd(); Burde lage en hvit trekant som dekker halve vinduet. Hvis ikke, kan det hende winding går andre veien, isåfall bytt to av verticene med hverandre. 1 Lenke til kommentar
Thitorkin Skrevet 16. mai 2011 Forfatter Del Skrevet 16. mai 2011 (endret) glBegin(GL_TRIANGLES); { glVertex3f(0, 1, 0); glVertex3f(1, 1, 0); glVertex3f(1, 0, 0); } glEnd(); Burde lage en hvit trekant som dekker halve vinduet. Hvis ikke, kan det hende winding går andre veien, isåfall bytt to av verticene med hverandre. Virket ikke, glBegin(GL_TRIANGLES); { glVertex3f(1, 1, 0); glVertex3f(0, 1, 0); glVertex3f(1, 0, 0); } glEnd(); Gjir fortsatt hvit skjerm, glBegin(GL_TRIANGLES); { glVertex3f(1, 0, 0); glVertex3f(0, 1, 0); glVertex3f(1, 1, 0); } glEnd(); Gjir også hvit skjerm. Har på følelsen av at dette ikke var det du mente eg skulle gjøre? Merk at skjermen uten noen tegnede objekter er svart, mens når eg tegner noe så blir den hvit. Størrelsen på vinduet justeres heller ikke som vanlig..Eg har prøvd i VSC++ Endret 16. mai 2011 av Gabbe Lenke til kommentar
GeirGrusom Skrevet 16. mai 2011 Del Skrevet 16. mai 2011 Hvis du bruker GL_DEPTH_TEST må du cleare det sammen med color-buffer: glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); Men det skal ikke egentlig ha noe å si. Les hva glOrtho faktisk gjøre: denne vil føre til at viewporten blir en slags "kube" der kamera linsen er hele veggen på z near. Det er derfor ikke noe poeng i å lage vertices som er større enn denne hvis du ønsker å se dem. Derfor tipper jeg at den koden du har laget for å rendre en trekant dekker hele vinduet (siden trekanten er vanvittig stor) 1 Lenke til kommentar
Thitorkin Skrevet 16. mai 2011 Forfatter Del Skrevet 16. mai 2011 (endret) void TerrainDraw() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); // the following code draws a triangle glBegin(GL_TRIANGLES); { glVertex3f(0, 1, 0); glVertex3f(1, 1, 0); glVertex3f(1, 0, 0); } glEnd(); } Altså slik? Men den er fremdeles helt hvit Burde eg heller bruke gluPersepctive? AAAAAAH så dum eg er, glFlush(); Endret 16. mai 2011 av Gabbe Lenke til kommentar
Thitorkin Skrevet 17. mai 2011 Forfatter Del Skrevet 17. mai 2011 Det er noe proglem med randomenes int, tror eg, men vet ikke hva desverre. Fytti Flate tenk at programmet faktisk ble så stort Men så nå fungerer det ikke, har prøvd å flytte rundt på litt int men skjønner ikke helt hvor det er programmet vil ha de.. #include <iostream> #include <stdio.h> #include <stdlib.h> #include <time.h> //Include OpenGL files, both for windows and apple (possibly Linux) #ifdef __APPLE__ #include <OpenGL/OpenGL.h> #include <GLUT/glut.h> #else #include <glut.h> #endif using namespace std; void handleKeypress(unsigned char key, int x, int y) { switch (key) { case 27: //Escape key used to stop program and display console message cout << "\n **********CONSOLE STTOPPED!**********\n\n\n"; exit(0); } } void DepthTest() { glEnable(GL_DEPTH_TEST); } //Called when the window is resized void handleResize(int w, int h) { //Tell OpenGL how to convert from coordinates to pixel values glClearColor(0.0, 0.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); } //Draws the Terrain void TerrainDraw(int Rvertex1, int Rvertex2, int Rvertex3, int Rvertex4) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); srand ( time(NULL) ); Rvertex1 = rand() % 0,9; Rvertex2 = rand() % 0,9; Rvertex3 = rand() % 0,9; Rvertex4 = rand() % 0,9; // the following code draws a triangle glBegin(GL_TRIANGLE_STRIP); { glVertex3f(0, Rvertex1, 0); glVertex3f(Rvertex4, Rvertex2, 0); glVertex3f(Rvertex3, 0, 0); } glEnd(); glFlush(); } void GlutInit (int argc, char** argv, int WH, int WW){ //Initialize GLUT glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); //Setting window Height and width WH = 800; WW = 600; //Defining window properties glutInitWindowSize(800, 600); //Set the window size glutInitWindowPosition(200, 200); //Set the window position } void CreateAll(int argc, char** argv, int WH, int WW, int Rvertex1, int Rvertex2, int Rvertex3, int Rvertex4){ //Create the window cout << "Creating basic window..\n"; glutCreateWindow("Terrain Generator V.00001"); cout << "Succes, basic window created!\n"; cout << "testing depth..\n"; DepthTest(); cout << "Depth succesully tested!\n"; cout << "Drawing terrain...\n"; glutDisplayFunc(TerrainDraw); cout << "Terrain drawn on screen!\n"; cout << "Initializing keyboard functions..\n"; glutKeyboardFunc(handleKeypress); cout << "Keyboard succesfully initialized!\n"; cout << "Trying to make window reziseable..standby..\n"; glutReshapeFunc(handleResize); cout << "Window now reziseable!\n"; cout << "initializing OpenGL..standby..\n"; GlutInit(argc, argv, WH, WW); cout << "Succes OpenGL initiated and Window size set!"; } int main(int argc, char** argv, int WH, int WW, int Rvertex1, int Rvertex2, int Rvertex3, int Rvertex4) { cout << " **********CONSOLE STARTED!**********\n\n________________________________________________\n STARTUP BEGIN\n\n"; //cout << "Please enter the height resolution you want, else we use standard: "; //cin >> WH; //cout << "Please enter the wide resolution you want, else we use standard: "; //cin >> WW; cout << "Trying to create window..standby..\n"; CreateAll(argc, argv, WH, WW, Rvertex1, Rvertex2, Rvertex3, Rvertex4); cout << "\nSucces, window created!"; cout << "\nApplication is now running properly with everything loaded!\n\n"; cout << " STARTUP END\n"; cout << "________________________________________________"; glutMainLoop(); return 0; } Lenke til kommentar
GeirGrusom Skrevet 17. mai 2011 Del Skrevet 17. mai 2011 Bruk STL istedet da (#include <random>) Den har en random_device som du heller kan bruke. Jeg håper du forøvrig vet dette er legacy OpenGL? Lenke til kommentar
GeirGrusom Skrevet 17. mai 2011 Del Skrevet 17. mai 2011 Eksempel (uten GLUT dog): #define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <gl\GL.h> #include <gl\GLU.h> #include <random> #include <vector> struct VertexFormat { struct { float x; float y; float z; }position, normal; struct { float x; float y; }texcoord; }; std::random_device rnd; // max er et medlem av rnd, og må derfor undef'es #undef max void GenerateTerrain(const int size, const float cell_size, std::vector<VertexFormat>& vertex_array, std::vector<unsigned short>& index_array) { unsigned short index = 0; const float s2 = (size * cell_size) / 2; for(int i = 0; i < size; i++) { for(int j = 0; j < size; j++, index++) { VertexFormat vertex; vertex.position.x = i * cell_size - s2; vertex.position.y = rnd() / (float)rnd.max(); vertex.position.z = j * cell_size - s2; vertex.normal.x = 0; vertex.normal.y = 1; vertex.normal.z = 0; vertex_array.push_back(vertex); if( j < (size - 1) && i < (size - 1) ) { index_array.push_back(index); index_array.push_back(index + 1); index_array.push_back(index + size + 1); index_array.push_back(index); index_array.push_back(index + size + 1); index_array.push_back(index + size); } } } } std::vector<VertexFormat> vb; std::vector<unsigned short> ib; void Render() { glRotatef(0.1f, 0, 1, 0); glColor3f(0, .5, 0); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glVertexPointer(3, GL_FLOAT, sizeof(VertexFormat), &vb[0]); glEnableClientState(GL_VERTEX_ARRAY); glDrawElements(GL_TRIANGLES, ib.size(), GL_UNSIGNED_SHORT, &ib[0]); } void InitViewport() { glPushAttrib(GL_MATRIX_MODE); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, 1, .1, 128); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(-32, 32, -32, 0, 0, 0, 0, 1, 0); glPopAttrib(); } int main(int argc, char** argv) { // Setup OpenGL Window with 1.1 context WNDCLASSEX cl; ZeroMemory(&cl, sizeof(cl)); cl.hbrBackground = (HBRUSH)COLOR_WINDOW; cl.lpfnWndProc= DefWindowProc; cl.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; cl.cbSize = sizeof(cl); cl.lpszClassName = "DEF_OPENGL"; auto wnd_class = RegisterClassEx(&cl); auto wnd = CreateWindow(cl.lpszClassName, "OpenGL Test", WS_TILEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); auto hdc = GetDC(wnd); PIXELFORMATDESCRIPTOR pxd; ZeroMemory(&pxd, sizeof(pxd)); pxd.nSize = sizeof(pxd); pxd.nVersion = 1; pxd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; pxd.cColorBits = 32; pxd.cDepthBits = 32; int format = ChoosePixelFormat(hdc, &pxd); SetPixelFormat(hdc, format, &pxd); // OpenGL 1.1 Context auto gl_ctx = wglCreateContext(hdc); wglMakeCurrent(hdc, gl_ctx); glEnable(GL_DEPTH_TEST); ShowWindow(wnd, SW_SHOW); GenerateTerrain(64, 1, vb, ib); MSG message; InitViewport(); while(IsWindowEnabled(wnd)) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Render(); glFinish(); SwapBuffers(hdc); if(PeekMessage(&message, wnd, 0, 0, PM_REMOVE)) { DispatchMessage(&message); } } } 1 Lenke til kommentar
Thitorkin Skrevet 17. mai 2011 Forfatter Del Skrevet 17. mai 2011 Skal bare lære meg OpenGL Derfor eg prøver å lage programmer med det Skal se gjennom eksempel-koden din der... Lenke til kommentar
GeirGrusom Skrevet 17. mai 2011 Del Skrevet 17. mai 2011 (endret) Det er litt Windows spesifikk kode der, ettersom jeg ikke brukte GLUT. Det er også fortsatt legacy kode da, men samme det ^^ Her er en som tar med lys også, litt mer kompleks dog, og ikke optimal. #define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <gl\GL.h> #include <gl\GLU.h> #include <random> #include <vector> struct VertexFormat { struct { float x; float y; float z; }position, normal; struct { float x; float y; }texcoord; }; // Crosses two vectors template<typename T> const T cross(const T& a, const T& b) { T result; result.x = a.y * b.z - a.z * b.y; result.y = a.z * b.x - a.x * b.z; result.z = a.x * b.y - a.y * b.x; return result; } // Subtracts two vectors template<typename T> const T sub(const T& a, const T& b) { T result; result.x = a.x - b.x; result.y = a.y - b.y; result.z = a.z - b.z; return result; } // Adds to vectors template<typename T> const T add(const T& a, const T& b) { T result; result.x = a.x + b.x; result.y = a.y + b.y; result.z = a.z + b.z; return result; } std::random_device rnd; // max er et medlem av rnd, og må derfor undef'es #undef max void GenerateTerrain(const int size, const float cell_size, std::vector<VertexFormat>& vertex_array, std::vector<unsigned short>& index_array) { unsigned short index = 0; const float s2 = (size * cell_size) / 2; // Generate vertex positions for(int i = 0; i < size; i++) { for(int j = 0; j < size; j++, index++) { VertexFormat vertex; vertex.position.x = i * cell_size - s2; vertex.position.y = rnd() / (float)rnd.max(); vertex.position.z = j * cell_size - s2; vertex.normal.x = 0; vertex.normal.y = 0; vertex.normal.z = 0; vertex_array.push_back(vertex); if( j < (size - 1) && i < (size - 1) ) { index_array.push_back(index); index_array.push_back(index + 1); index_array.push_back(index + size + 1); index_array.push_back(index); index_array.push_back(index + size + 1); index_array.push_back(index + size); } } } // Generate vertex normals // Keep counter on each vertex so that we know how many triangles are connected to it int* count = new int[size * size]; ZeroMemory(count, size * size * sizeof(int)); for(auto itr = index_array.begin(); itr != index_array.end(); ) { auto i1 = *itr++; auto i2 = *itr++; auto i3 = *itr++; ++count[i1]; ++count[i2]; ++count[i3]; auto v1 = sub(vertex_array[i1].position, vertex_array[i2].position); auto v2 = sub(vertex_array[i1].position, vertex_array[i3].position); auto cr = cross(v1, v2); vertex_array[i1].normal = add(vertex_array[i1].normal, cr); vertex_array[i2].normal = add(vertex_array[i2].normal, cr); vertex_array[i3].normal = add(vertex_array[i3].normal, cr); } for(int i = 0; i < size * size; i++) { auto& v = vertex_array[i]; v.normal.x /= count[i]; v.normal.y /= count[i]; v.normal.z /= count[i]; } delete[] count; } std::vector<VertexFormat> vb; std::vector<unsigned short> ib; void Render() { glRotatef(0.1f, 0, 1, 0); glColor3f(0, .5, 0); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(VertexFormat), &vb[0].position); glNormalPointer(GL_FLOAT, sizeof(VertexFormat), &vb[0].normal); glDrawElements(GL_TRIANGLES, ib.size(), GL_UNSIGNED_SHORT, &ib[0]); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); } void InitViewport() { glPushAttrib(GL_MATRIX_MODE); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, 1, .1, 128); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(-32, 32, -32, 0, 0, 0, 0, 1, 0); glPopAttrib(); } int main(int argc, char** argv) { // Setup OpenGL Window with 1.1 context WNDCLASSEX cl; ZeroMemory(&cl, sizeof(cl)); cl.hbrBackground = (HBRUSH)COLOR_WINDOW; cl.lpfnWndProc= DefWindowProc; cl.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; cl.cbSize = sizeof(cl); cl.lpszClassName = "DEF_OPENGL"; auto wnd_class = RegisterClassEx(&cl); auto wnd = CreateWindow(cl.lpszClassName, "OpenGL Test", WS_TILEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); auto hdc = GetDC(wnd); PIXELFORMATDESCRIPTOR pxd; ZeroMemory(&pxd, sizeof(pxd)); pxd.nSize = sizeof(pxd); pxd.nVersion = 1; pxd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; pxd.cColorBits = 32; pxd.cDepthBits = 32; int format = ChoosePixelFormat(hdc, &pxd); SetPixelFormat(hdc, format, &pxd); // OpenGL 1.1 Context auto gl_ctx = wglCreateContext(hdc); wglMakeCurrent(hdc, gl_ctx); glEnable(GL_DEPTH_TEST); ShowWindow(wnd, SW_SHOW); // Generate our terrain model GenerateTerrain(64, 1, vb, ib); MSG message; InitViewport(); struct { float x; float y; float z; float w; }lightpos; ZeroMemory(&lightpos, sizeof(lightpos)); lightpos.w = 1; lightpos.y = 32; // Enble lighting glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_POSITION, (GLfloat*)&lightpos); while(IsWindowEnabled(wnd)) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Render(); glFinish(); SwapBuffers(hdc); while(PeekMessage(&message, wnd, 0, 0, PM_REMOVE)) { DispatchMessage(&message); } } } Endret 17. mai 2011 av GeirGrusom 1 Lenke til kommentar
TheMaister Skrevet 17. mai 2011 Del Skrevet 17. mai 2011 Spenstig med C++0x-kode ... Lenke til kommentar
GeirGrusom Skrevet 17. mai 2011 Del Skrevet 17. mai 2011 Beklager at det ble litt rotete :/ men du kan i stor grad ignorere main funksjonen. Den gjør for det meste bare setup-greier. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå