Gå til innhold

Når skal en begynne med OpenGL?


Anbefalte innlegg

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
Videoannonse
Annonse

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 av GeirGrusom
  • Liker 1
Lenke til kommentar

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 av Gabbe
Lenke til kommentar

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 av Gabbe
Lenke til kommentar

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)

  • Liker 1
Lenke til kommentar

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 :hmm: Burde eg heller bruke gluPersepctive?

 

AAAAAAH så dum eg er, glFlush(); :roll:

Endret av Gabbe
Lenke til kommentar

Det er noe proglem med randomenes int, tror eg, men vet ikke hva desverre. Fytti Flate tenk at programmet faktisk ble så stort :D 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

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);
	}
}	
}

  • Liker 1
Lenke til kommentar

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 av GeirGrusom
  • Liker 1
Lenke til kommentar

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...