Jump to content
  • Advertisement
Sign in to follow this  
stu2000

OpenGL glOrtho 2d help

This topic is 2593 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello there, I am trying to develop a webcam application thingy and would really love this to be 2d rather than 3d, with the webcam feed always taking up the screen. I have spent hours trying to get glOrtho to work for me, but my display of the webcam feed is always offscreen, or just not drawn. I have spent hours on it messing around with disabling lighting/blending etc and experimenting with loadIdentities but for the life of me cannot figure out whats wrong.

The key thing is that i have a define ' #define USE_ORTHO ' which is used to switch between 2d and 3d as I dont feel like losing everything in this process and might want to go back at some point to 3d.

I have set up a 'setuportho' function which is maybe the cause:

void SetupOrtho(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.f, 2.f, 0.f, 2.f, 0.f, 100.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

and my render function is here:
void Render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();//reset matrix

glColor3f(0,1,0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);

#ifdef USE_ORTHO
glBegin(GL_QUADS);
glTexCoord2s(1,1); glVertex3f(0.1, 0.1, 0.9);
glTexCoord2s(1,0); glVertex3f(0.1, 0.9, 0.9);
glTexCoord2s(0,0); glVertex3f(0.9, 0.9, 0.9);
glTexCoord2s(0,1); glVertex3f(0.9, 0.1, 0.9);
glEnd();
#else
glBegin(GL_QUADS);
glTexCoord2s(1,1); glVertex3f(-8, -6, -10);
glTexCoord2s(1,0); glVertex3f(-8, 6, -10);
glTexCoord2s(0,0); glVertex3f(8, 6, -10);
glTexCoord2s(0,1); glVertex3f(8, -6, -10);
glEnd();
#endif

//glDeleteTextures(GL_TEXTURE_2D, &cameraImageTextureID);
//glDisable(GL_TEXTURE_2D);

glFlush();
SwapBuffers(g_HDC); //bring the back buffer to the foreground
}

but maybe the problem is burried in the rest of the code with lighting etc.

I have uploaded the entire project here: http://www.putfile2.com/f/1049/ntkdtp

for those of you who probably find it easier to work in MSVC rather than burying through this text. Hopefully you wont have issues as everything including libs are there. Done in MSVC++ 2008 express 32bit win7. People have had problems in the past figuring out how to download, hence I have got my bro to put in a MASSIVE green download button. That should help.


Here is the entire code dump, sorry its kind of long as everyhting is in one file DOH! I was hoping it wouldnt come to this and feel like a smeghead asking for help.

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <vector>

#include <windows.h>
#include <mmsystem.h>

#include "videoInput.h"
#include <gl/gl.h>
#include <gl/glu.h>

#include <tchar.h>


#define USE_ORTHO


//////Defines
//#define BITMAP_ID 0x4D42


//Global variables

HDC g_HDC; // global device context
bool fullScreen = false; // true = fullscreen;false = windowed
bool keyPressed[256]; // holds true for keys that are pressed
bool leftMouseButton = false; // is the left mouse button pressed
bool rigthMouseButton = false; // is the right mouse button pressed.

//unsigned char * pixel_buffer_1;
//unsigned char * pixel_buffer_2;


#pragma region GLOBLE VARIABLE

int size = 921600;
int device1 = 0;

GLuint cameraImageTextureID;
int frameWidth = 640;
int frameHeight = 480;

// Create a videoInput object
videoInput VI;

unsigned char * frame = new unsigned char[size];




//-----var about control fps
static float lasttime = 0.0f; // store the last time
static float lasttime2 = 0.0f;
static float currenttime; // store the current time

#ifndef USE_ORTHO
//light variables structure and names copied (values slightly edited) from 'OpenGL Game Programming' by Kevin Hawkins and Dave Astle, 2001
float ambientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // ambient light
float diffuseLight[] = { 1.0f, 1.0f, 1.0f, 1.0f}; // diffuse light
float lightPosition[] = { 0.0f, 0.0f, 1000.0f, 1.0f}; // the light position

float matAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f};
float matDiff[] = {1.0f, 1.0f, 1.0f, 1.0f};
//end of light variables and copied structure material
#endif

#pragma endregion

void SetupOrtho(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.f, 2.f, 0.f, 2.f, 0.f, 100.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void Render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();//reset matrix

glColor3f(0,1,0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);

#ifdef USE_ORTHO
glBegin(GL_QUADS);
glTexCoord2s(1,1); glVertex3f(0.1, 0.1, 0.9);
glTexCoord2s(1,0); glVertex3f(0.1, 0.9, 0.9);
glTexCoord2s(0,0); glVertex3f(0.9, 0.9, 0.9);
glTexCoord2s(0,1); glVertex3f(0.9, 0.1, 0.9);
glEnd();
#else
glBegin(GL_QUADS);
glTexCoord2s(1,1); glVertex3f(-8, -6, -10);
glTexCoord2s(1,0); glVertex3f(-8, 6, -10);
glTexCoord2s(0,0); glVertex3f(8, 6, -10);
glTexCoord2s(0,1); glVertex3f(8, -6, -10);
glEnd();
#endif

//glDeleteTextures(GL_TEXTURE_2D, &cameraImageTextureID);
//glDisable(GL_TEXTURE_2D);

glFlush();
SwapBuffers(g_HDC); //bring the back buffer to the foreground
}


void initGL()
{
glClearColor(0.3f,0.3f,1.0f,1.0f); //clear to blue
glFrontFace(GL_CW); //set it so that polygons are drawn clockwise (does have an affect for some reason).
glEnable(GL_TEXTURE_2D);


#ifndef USE_ORTHO
glEnable(GL_LIGHTING); //enable lighting
glEnable(GL_DEPTH_TEST); //hidden surface removal


glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glShadeModel(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE); //do not draw inside of polygons for performance
glMaterialfv(GL_FRONT, GL_AMBIENT, matAmbient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff);

//LIGHTING
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); //set up the ambient element
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); //set up the diffuse element
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); //place the light
glEnable(GL_LIGHT0);

glEnable(GL_COLOR_MATERIAL); //-----------------PUTH THIS BACK MAYBE
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
//END OF LIGHTING

glMatrixMode(GL_PROJECTION);
gluPerspective(60,1.0f,0.1f,1000.0f); //set the perspective for 60 degree FOV witha a 1:1 aspect ratio and a close clipping pane of 0.1 and far of 1000 units.
glMatrixMode(GL_MODELVIEW);

//gluLookAt(0, 100, 100, 0,0,0,0,0,1); //important that glulookat is in the modelview matrix
#else
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING); //enable lighting
glDisable(GL_DEPTH_TEST); //hidden surface removal
//glDisable(GL_BLEND);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
SetupOrtho(frameWidth, frameHeight);
#endif


}

void Initialize()
{
initGL();

// Get first camera frame here


//Prints out a list of available devices and returns num of devices found
int numDevices = VI.listDevices();


// If you want to capture at a different frame rate (default is 30) specify it here, you are not guaranteed to get this fps though.
VI.setIdealFramerate(0, 60);

// Setup the first device - there are a number of options:
// this could be any deviceID that shows up in listDevices
// VI.setupDevice(device1); // Setup the first device with the default settings
// VI.setupDevice(device1, VI_COMPOSITE); // or setup device with specific connection type
VI.setupDevice(device1, frameWidth, frameHeight); // or setup device with specified video size
// VI.setupDevice(device1, 320, 240, VI_COMPOSITE); // or setup device with video size and connection type
// VI.setFormat(device1, VI_NTSC_M); // if your card doesn't remember what format it should be
// call this with the appropriate format listed above
// NOTE: must be called after setupDevice!

// Optionally setup a second (or third, fourth ...) device - same options as above
// VI.setupDevice(device2);

// As requested width and height can not always be accomodated
// Make sure to check the size once the device is setup

frameWidth = VI.getWidth(device1);
frameHeight = VI.getHeight(device1);
size = VI.getSize(device1);


// pixel_buffer_1 = unsigned char[size];
// pixel_buffer_2 = unsigned char[size];

// To get the data from the device first check if the data is new
if (VI.isFrameNew(device1))
{
// VI.getPixels(device1, pixel_buffer_1, false, false); //fills pixels as a BGR (for openCV) unsigned char array - no flipping
// VI.getPixels(device1, pixel_buffer_2, true, true); //fills pixels as a RGB (for openGL) unsigned char array - flipping!
frame = VI.getPixels(device1, true, true); //fills pixels as a BGR (for openGL) unsigned char array - no flipping
}

// Same applies to device2 etc

// To get a settings dialog for the device
VI.showSettingsWindow(device1);

glGenTextures(1,&cameraImageTextureID);
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);


glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, frameWidth,frameHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, frame);
// gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, frameWidth, frameHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, frame);


// Shut down devices properly
// VI.stopDevice(device1);
// VI.stopDevice(device2);
}

void Reshape(int w, int h)
{
double ww = w;
double hh = h;

#ifndef USE_ORTHO
glViewport(0, 0, w, h); /* Establish viewing area to cover entire window. */
glMatrixMode(GL_PROJECTION);
glLoadIdentity (); //replace the current matrix with the Identity Matrix
gluPerspective(60, ww/hh,0.1f,1000.0f);
glMatrixMode(GL_MODELVIEW);
#else
SetupOrtho(w, h);
#endif


}

void GameLoop()
{
// Find out how much time has passed
// static double time = timeGetTime();
// double time2 = timeGetTime();
// double timeDiff = (time2 - time) / 1000;
// time = time2;

// Sort out user input
if(keyPressed['W']){}
if(keyPressed['S']){}
if(keyPressed['A']){}
if(keyPressed['D']){}
if(keyPressed['B']){}
if(keyPressed['R']){}


// Capture frame from camera here

if (VI.isFrameNew(device1))
{
// VI.getPixels(device1, pixel_buffer_1, false, false); // fills pixels as a BGR (for openCV) unsigned char array - no flipping
// VI.getPixels(device1, pixel_buffer_2, true, true); // fills pixels as a RGB (for openGL) unsigned char array - flipping!
VI.getPixels(device1, frame, false, true);
}

// End of capture frame from camera


/*

// Clear the tracker buffer
for(unsigned int y=0; y<frameHeight; y++)
{
for(unsigned int x=0; x<frameWidth; x++)
{
trackBuffer[x][y] = 0;
}
}


// Process the image
for(unsigned int i=0; i<frameHeight; i++)
{
for(unsigned int j=0; j<frameWidth; j++)
{


}
}

// Process the tracker buffer
for(unsigned int y=0; y<frameHeight; y++)
{
for(unsigned int x=0; x<frameWidth; x++)
{
trackBuffer[x][y] == 0;
}
}

// Render the tracker buffer
for(unsigned int y=0; y<frameHeight; y++)
{
for(unsigned int x=0; x<frameWidth; x++)
{
if(trackBuffer[x][y] == 1)
{

}
}
}

*/

// End of processing the image


// Turn image into texture
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);

glGenTextures(1,&cameraImageTextureID);
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, frameWidth, frameHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, frame);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frameWidth,frameHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,frame);

Render();
}


void SetupPixelFormat(HDC hDC)
{
int nPixelFormat; //our pixel format index

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); //chose matching pixel format
SetPixelFormat(hDC, nPixelFormat, &pfd); //set the pixel format to DC
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HGLRC hRC; // rendering context
static HDC hDC; // device context
int width, height; // window width and height
int oldMouseX, oldMouseY; // old mouse coordinates

double zDeltaDifference = 0;
static short zDelta;


switch(message)
{
case WM_CREATE:
hDC = GetDC(hwnd); // get current windows device context
g_HDC = hDC;
SetupPixelFormat(hDC); // call our pixel format setup function

//create rendering context and make it current
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);

return 0;
break;

case WM_CLOSE: // window is closing
// Deselect rendering context and delete it
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);

// Send WM_QUIT to message queue
PostQuitMessage(0);

return 0;
break;

case WM_SIZE:
height = HIWORD(lParam); //retrieve width and height
width = LOWORD(lParam);

if (height==0)
{
height=1;
}

// Reset the viewport to new dimensions
glViewport(0,0, width, height);

#ifndef USE_ORTHO
// Set projection matrix current matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

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

glMatrixMode(GL_MODELVIEW); //set the modelview matrix
glLoadIdentity(); //reset the modelview matrix
#else
SetupOrtho(width, height);
#endif
return 0;
break;

case WM_KEYDOWN: //is a key pressed?
keyPressed[wParam] = true;
// camera.MoveZ(1);
return 0;
break;

case WM_KEYUP:
keyPressed[wParam] = false;
return 0;
break;

case WM_LBUTTONDOWN:
leftMouseButton = true;
return 0;
break;

case WM_RBUTTONDOWN:
rigthMouseButton = true;
return 0;
break;

case WM_LBUTTONUP:
leftMouseButton = false;
return 0;
break;

case WM_RBUTTONUP:
rigthMouseButton = false;
return 0;
break;

case WM_MOUSEMOVE:

// Save old mouse coordinates
// oldMouseX = mouseX;
// oldMouseY = mouseY;

// Get mouse coordinates from Windows
// mouseX = LOWORD(lParam);
// mouseY = HIWORD(lParam);



// These lines limit the camera's range
// if (mouseY < 200)
{
// mouseY = 200;
}
// if (mouseY > 450)
{
// mouseY = 450;
}
if (leftMouseButton)
{
// camera.zoom += (mouseY - oldMouseY) * 0.50f;
// camera.pitch += (mouseY - oldMouseY) * 0.1f;
// camera.angle += (oldMouseX - mouseX) * 0.30f;
}

/*
if (mouseX - oldMouseX != 0)
{
mouseX - oldMouseX > 0 ? angle += 3.0f : angle -= 3.0f ;
}
*/

return 0;
break;

case WM_MOUSEWHEEL:
// zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
// camera.zoom = camera.zoom - (camera.zoom/8 * zDelta/120); //camera movement is proportional, so if your further away zooming is faster.
return 0;
break;

default:
break;
}

return (DefWindowProc(hwnd, message, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX windowClass; // windows class
HWND hwnd; // window handle
MSG msg; // message
bool done; // flag saying when our app is complete
DWORD dwExStyle; // window extended style
DWORD dwStyle; // window style
RECT windowRect;

// Screen/display attributes
int width = 800;
int height = 600;
int bits = 32;

windowRect.left =(long)0; // set left value to 0
windowRect.right =(long)width; // set right value to requested width
windowRect.top =(long)0; // set the top value to 0
windowRect.bottom =(long)height; // set bottom value to requested height

// Fill out the windows class structure
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = L"MyClass";
windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

// Register the windows class
if (!RegisterClassEx(&windowClass))
return 0;

if (fullScreen) //full screen
{
DEVMODE dmScreenSettings; //device mode
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = width; //screen width
dmScreenSettings.dmPelsHeight = height; //screen height
dmScreenSettings.dmBitsPerPel = bits;
dmScreenSettings.dmFields=DM_BITSPERPEL | DM_PELSWIDTH | DM_PANNINGHEIGHT;

if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
// Setting display mode failed, switch to windowed
MessageBox(NULL, L"Display mode failed", NULL, MB_OK);
fullScreen=FALSE;
}
}

if (fullScreen) //are we still in full screen mode
{
dwExStyle=WS_EX_APPWINDOW; //window extended style
dwStyle=WS_POPUP; //window style
ShowCursor(FALSE); //hide mouse pointer
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; //window exteded style
dwStyle=WS_OVERLAPPEDWINDOW; //window style
}

AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);

// Class registered so now create our window
hwnd = CreateWindowEx(NULL, L"MyClass", L"Stuart Page's Physics Game", dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0,0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, NULL, NULL, hInstance, NULL);

// Check if window creation failed (hwnd would equal NULL)
if(!hwnd)
return 0;

ShowWindow(hwnd, SW_SHOW); //display the window
UpdateWindow(hwnd); //update the window

done = false; //initialize the loop condition variable

// Main message loop
Initialize();

while (!done)
{
if(PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE)!=0) //there is a new message in the que
{
if(msg.message == WM_QUIT) //do we recieve a WM_QUIT message?
{
done = true;
}
else
{
//GAME LOOP HERE
GameLoop();
TranslateMessage(&msg);
DispatchMessage(&msg);
}

}
else //there are no new messages, so dont handle any
{
GameLoop();
}
}

if (fullScreen)
{
ChangeDisplaySettings(NULL, 0); //if so switch back to the desktop
ShowCursor(TRUE);
}
return msg.wParam;

}

Share this post


Link to post
Share on other sites
Advertisement

glOrtho(0.f, 2.f, 0.f, 2.f, 0.f, 100.f);

glTexCoord2s(1,1); glVertex3f(0.1, 0.1, 0.9);
glTexCoord2s(1,0); glVertex3f(0.1, 0.9, 0.9);
glTexCoord2s(0,0); glVertex3f(0.9, 0.9, 0.9);
glTexCoord2s(0,1); glVertex3f(0.9, 0.1, 0.9);
[/quote]

Can you try changing these z coordinates to -0.9, instead of +0.9? When calling glOrtho, the final 2 values are the zNear and zFar values. However the default camera in openGL looks down the negative z axis, so with this glOrtho command you'll be viewing coordinates in the box from (0,0,0) to (2,2,-100). This puts your quad right behind the camera.

Alternatively, you could leave the z coordinate at +0.9, and change the zFar plane to -100, which should have the same effect.

Share this post


Link to post
Share on other sites
its amazing how a fresh/different pair of eyes can spot the problem immediately. Thanks! That worked.
Stu

Share this post


Link to post
Share on other sites
by the way can someone look at this bit of code in there:


// Turn image into texture
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);

glGenTextures(1,&cameraImageTextureID);
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, frameWidth, frameHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, frame);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frameWidth,frameHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,frame);

It looks like im creating a texture based on webcam inpu each frame.
Is it possible and faster to just edit the texture from last frame rather than go through the whole process again?

Would this be better/same or could be improved upon?:

static bool generatedTexture = false;

if (!generatedTexture)
{
// Turn image into texture
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);

glGenTextures(1,&cameraImageTextureID);
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, frameWidth, frameHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, frame);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frameWidth,frameHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,frame);
generatedTexture = true;
}
else
{
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, frameWidth, frameHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, frame);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frameWidth,frameHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,frame);
}

Stu

Share this post


Link to post
Share on other sites
Yeah, I would say your second set of code is much preferable, though it has a few issues. I would clean it up like so:



//during constructor:
cameraImageTextureID = 0;
//

//during render loop:
//if (!generatedTexture) //don't need another variable, can use the ID to tell if its initialized or not
if(!cameraImageTextureID){

//this is bad, and probably generates an error. You can't bind the ID before the texture ID has been generated
//glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);

glGenTextures(1,&cameraImageTextureID);
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

//You need to decide if you want to use mipmaps or not. You're generating mipmaps
//everytime you load textures, but you're disabling using them here. If you want
//mipmaps, enable them in the minification filter. If you don't, then don't waste
//processing time by generating them each frame.

//glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

//when you first create the texture, just call glTexImage2D with '0' for the data,
//this initializes the texture with the parameters you set but does not fill it with data.
//then call glTexSubImage when you want to overwrite the pixels each frame
glTexImage2D(GL_TEXTURE_2D, 0, 0, 0, frameWidth,frameHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,0);

//gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, frameWidth, frameHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, frame);
//glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frameWidth,frameHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,frame);
//generatedTexture = true; //dont need this
} else {
glBindTexture(GL_TEXTURE_2D, cameraImageTextureID);
}


//If you want mipmaps, you should call it AFTER you load the texture data, not before
//gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, frameWidth, frameHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, frame);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frameWidth,frameHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,frame);
//gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, frameWidth, frameHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, frame);
//I think this is preferrable to the glu routine as it utilizes
//the GPU to generate mipmaps, so it should be faster. Can
//probably use either one you want.
glGenerateMipmap(GL_TEXTURE_2D);

//good practice to check for errors when generating new code
int err = glGetError();
if(err){
throw (something);
}


Share this post


Link to post
Share on other sites
The fastest way would be to render to a texture, take a look at framebuffer objects, draw buffers, and texture rectangle extensions, avoid the copy altogether and just render to a texture then display it.

Share this post


Link to post
Share on other sites

The fastest way would be to render to a texture, take a look at framebuffer objects, draw buffers, and texture rectangle extensions, avoid the copy altogether and just render to a texture then display it.


I think hes drawing some webcam data which is probably presented to him as an array of pixels. If you're actually rendering something then it makes more sense to draw it into a framebuffer, but I think his approach is fine for presenting data from a source outside the program.

Share this post


Link to post
Share on other sites
Thanks for the help - especially that long post from karwost with the comments explaining why each thing was bad and what should be done. I had always thought you needed to use mipmaps if you were going to apply a texture to something that wasnt the same size as the image you were passing in? TBH i only care about speed and not looks as I am doing this for objet recognition/tracking and not for a skype video call type thing. Once i have messed around with the example stuff you have given me I will get back to you .
Thanks again you guys are awesome!

Share this post


Link to post
Share on other sites
Dont want to sound like a little girl but...

Omg thank you, thank you, thank you. I put in your code and got rid of all mipmaps. The thing now runs SUPER fast at 960 x 720 resolution. Its running even faster than it was at 640 x 480 before. I tried not using mipmaps before but must have done something wrong as it would not render but does now. This is so much better than what i thought was possible. Now I can just focus on the tracking part of the project thanks!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By mmmax3d
      Hi everyone,
      I would need some assistance from anyone who has a similar experience
      or a nice idea!
      I have created a skybox (as cube) and now I need to add a floor/ground.
      The skybox is created from cubemap and initially it was infinite.
      Now it is finite with a specific size. The floor is a quad in the middle
      of the skybox, like a horizon.
      I have two problems:
      When moving the skybox upwards or downwards, I need to
      sample from points even above the horizon while sampling
      from the botton at the same time.  I am trying to create a seamless blending of the texture
      at the points of the horizon, when the quad is connected
      to the skybox. However, I get skew effects. Does anybody has done sth similar?
      Is there any good practice?
      Thanks everyone!
    • By mmmax3d
      Hi everyone,
      I would need some assistance from anyone who has a similar experience
      or a nice idea!
      I have created a skybox (as cube) and now I need to add a floor/ground.
      The skybox is created from cubemap and initially it was infinite.
      Now it is finite with a specific size. The floor is a quad in the middle
      of the skybox, like a horizon.
      I have two problems:
      When moving the skybox upwards or downwards, I need to
      sample from points even above the horizon while sampling
      from the botton at the same time.  I am trying to create a seamless blending of the texture
      at the points of the horizon, when the quad is connected
      to the skybox. However, I get skew effects. Does anybody has done sth similar?
      Is there any good practice?
      Thanks everyone!
    • By iArtist93
      I'm trying to implement PBR into my simple OpenGL renderer and trying to use multiple lighting passes, I'm using one pass per light for rendering as follow:
      1- First pass = depth
      2- Second pass = ambient
      3- [3 .. n] for all the lights in the scene.
      I'm using the blending function glBlendFunc(GL_ONE, GL_ONE) for passes [3..n], and i'm doing a Gamma Correction at the end of each fragment shader.
      But i still have a problem with the output image it just looks noisy specially when i'm using texture maps.
      Is there anything wrong with those steps or is there any improvement to this process?
    • By babaliaris
      Hello Everyone!
      I'm learning openGL, and currently i'm making a simple 2D game engine to test what I've learn so far.  In order to not say to much, i made a video in which i'm showing you the behavior of the rendering.
      Video: 
       
      What i was expecting to happen, was the player moving around. When i render only the player, he moves as i would expect. When i add a second Sprite object, instead of the Player, this new sprite object is moving and finally if i add a third Sprite object the third one is moving. And the weird think is that i'm transforming the Vertices of the Player so why the transformation is being applied somewhere else?
       
      Take a look at my code:
      Sprite Class
      (You mostly need to see the Constructor, the Render Method and the Move Method)
      #include "Brain.h" #include <glm/gtc/matrix_transform.hpp> #include <vector> struct Sprite::Implementation { //Position. struct pos pos; //Tag. std::string tag; //Texture. Texture *texture; //Model matrix. glm::mat4 model; //Vertex Array Object. VertexArray *vao; //Vertex Buffer Object. VertexBuffer *vbo; //Layout. VertexBufferLayout *layout; //Index Buffer Object. IndexBuffer *ibo; //Shader. Shader *program; //Brains. std::vector<Brain *> brains; //Deconstructor. ~Implementation(); }; Sprite::Sprite(std::string image_path, std::string tag, float x, float y) { //Create Pointer To Implementaion. m_Impl = new Implementation(); //Set the Position of the Sprite object. m_Impl->pos.x = x; m_Impl->pos.y = y; //Set the tag. m_Impl->tag = tag; //Create The Texture. m_Impl->texture = new Texture(image_path); //Initialize the model Matrix. m_Impl->model = glm::mat4(1.0f); //Get the Width and the Height of the Texture. int width = m_Impl->texture->GetWidth(); int height = m_Impl->texture->GetHeight(); //Create the Verticies. float verticies[] = { //Positions //Texture Coordinates. x, y, 0.0f, 0.0f, x + width, y, 1.0f, 0.0f, x + width, y + height, 1.0f, 1.0f, x, y + height, 0.0f, 1.0f }; //Create the Indicies. unsigned int indicies[] = { 0, 1, 2, 2, 3, 0 }; //Create Vertex Array. m_Impl->vao = new VertexArray(); //Create the Vertex Buffer. m_Impl->vbo = new VertexBuffer((void *)verticies, sizeof(verticies)); //Create The Layout. m_Impl->layout = new VertexBufferLayout(); m_Impl->layout->PushFloat(2); m_Impl->layout->PushFloat(2); m_Impl->vao->AddBuffer(m_Impl->vbo, m_Impl->layout); //Create the Index Buffer. m_Impl->ibo = new IndexBuffer(indicies, 6); //Create the new shader. m_Impl->program = new Shader("Shaders/SpriteShader.shader"); } //Render. void Sprite::Render(Window * window) { //Create the projection Matrix based on the current window width and height. glm::mat4 proj = glm::ortho(0.0f, (float)window->GetWidth(), 0.0f, (float)window->GetHeight(), -1.0f, 1.0f); //Set the MVP Uniform. m_Impl->program->setUniformMat4f("u_MVP", proj * m_Impl->model); //Run All The Brains (Scripts) of this game object (sprite). for (unsigned int i = 0; i < m_Impl->brains.size(); i++) { //Get Current Brain. Brain *brain = m_Impl->brains[i]; //Call the start function only once! if (brain->GetStart()) { brain->SetStart(false); brain->Start(); } //Call the update function every frame. brain->Update(); } //Render. window->GetRenderer()->Draw(m_Impl->vao, m_Impl->ibo, m_Impl->texture, m_Impl->program); } void Sprite::Move(float speed, bool left, bool right, bool up, bool down) { if (left) { m_Impl->pos.x -= speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(-speed, 0, 0)); } if (right) { m_Impl->pos.x += speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(speed, 0, 0)); } if (up) { m_Impl->pos.y += speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(0, speed, 0)); } if (down) { m_Impl->pos.y -= speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(0, -speed, 0)); } } void Sprite::AddBrain(Brain * brain) { //Push back the brain object. m_Impl->brains.push_back(brain); } pos *Sprite::GetPos() { return &m_Impl->pos; } std::string Sprite::GetTag() { return m_Impl->tag; } int Sprite::GetWidth() { return m_Impl->texture->GetWidth(); } int Sprite::GetHeight() { return m_Impl->texture->GetHeight(); } Sprite::~Sprite() { delete m_Impl; } //Implementation Deconstructor. Sprite::Implementation::~Implementation() { delete texture; delete vao; delete vbo; delete layout; delete ibo; delete program; }  
      Renderer Class
      #include "Renderer.h" #include "Error.h" Renderer::Renderer() { } Renderer::~Renderer() { } void Renderer::Draw(VertexArray * vao, IndexBuffer * ibo, Texture *texture, Shader * program) { vao->Bind(); ibo->Bind(); program->Bind(); if (texture != NULL) texture->Bind(); GLCall(glDrawElements(GL_TRIANGLES, ibo->GetCount(), GL_UNSIGNED_INT, NULL)); } void Renderer::Clear(float r, float g, float b) { GLCall(glClearColor(r, g, b, 1.0)); GLCall(glClear(GL_COLOR_BUFFER_BIT)); } void Renderer::Update(GLFWwindow *window) { /* Swap front and back buffers */ glfwSwapBuffers(window); /* Poll for and process events */ glfwPollEvents(); }  
      Shader Code
      #shader vertex #version 330 core layout(location = 0) in vec4 aPos; layout(location = 1) in vec2 aTexCoord; out vec2 t_TexCoord; uniform mat4 u_MVP; void main() { gl_Position = u_MVP * aPos; t_TexCoord = aTexCoord; } #shader fragment #version 330 core out vec4 aColor; in vec2 t_TexCoord; uniform sampler2D u_Texture; void main() { aColor = texture(u_Texture, t_TexCoord); } Also i'm pretty sure that every time i'm hitting the up, down, left and right arrows on the keyboard, i'm changing the model Matrix of the Player and not the others.
       
      Window Class:
      #include "Window.h" #include <GL/glew.h> #include <GLFW/glfw3.h> #include "Error.h" #include "Renderer.h" #include "Scene.h" #include "Input.h" //Global Variables. int screen_width, screen_height; //On Window Resize. void OnWindowResize(GLFWwindow *window, int width, int height); //Implementation Structure. struct Window::Implementation { //GLFW Window. GLFWwindow *GLFW_window; //Renderer. Renderer *renderer; //Delta Time. double delta_time; //Frames Per Second. int fps; //Scene. Scene *scnene; //Input. Input *input; //Deconstructor. ~Implementation(); }; //Window Constructor. Window::Window(std::string title, int width, int height) { //Initializing width and height. screen_width = width; screen_height = height; //Create Pointer To Implementation. m_Impl = new Implementation(); //Try initializing GLFW. if (!glfwInit()) { std::cout << "GLFW could not be initialized!" << std::endl; std::cout << "Press ENTER to exit..." << std::endl; std::cin.get(); exit(-1); } //Setting up OpenGL Version 3.3 Core Profile. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); /* Create a windowed mode window and its OpenGL context */ m_Impl->GLFW_window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL); if (!m_Impl->GLFW_window) { std::cout << "GLFW could not create a window!" << std::endl; std::cout << "Press ENTER to exit..." << std::endl; std::cin.get(); glfwTerminate(); exit(-1); } /* Make the window's context current */ glfwMakeContextCurrent(m_Impl->GLFW_window); //Initialize GLEW. if(glewInit() != GLEW_OK) { std::cout << "GLEW could not be initialized!" << std::endl; std::cout << "Press ENTER to exit..." << std::endl; std::cin.get(); glfwTerminate(); exit(-1); } //Enabling Blending. GLCall(glEnable(GL_BLEND)); GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); //Setting the ViewPort. GLCall(glViewport(0, 0, width, height)); //**********Initializing Implementation**********// m_Impl->renderer = new Renderer(); m_Impl->delta_time = 0.0; m_Impl->fps = 0; m_Impl->input = new Input(this); //**********Initializing Implementation**********// //Set Frame Buffer Size Callback. glfwSetFramebufferSizeCallback(m_Impl->GLFW_window, OnWindowResize); } //Window Deconstructor. Window::~Window() { delete m_Impl; } //Window Main Loop. void Window::MainLoop() { //Time Variables. double start_time = 0, end_time = 0, old_time = 0, total_time = 0; //Frames Counter. int frames = 0; /* Loop until the user closes the window */ while (!glfwWindowShouldClose(m_Impl->GLFW_window)) { old_time = start_time; //Total time of previous frame. start_time = glfwGetTime(); //Current frame start time. //Calculate the Delta Time. m_Impl->delta_time = start_time - old_time; //Get Frames Per Second. if (total_time >= 1) { m_Impl->fps = frames; total_time = 0; frames = 0; } //Clearing The Screen. m_Impl->renderer->Clear(0, 0, 0); //Render The Scene. if (m_Impl->scnene != NULL) m_Impl->scnene->Render(this); //Updating the Screen. m_Impl->renderer->Update(m_Impl->GLFW_window); //Increasing frames counter. frames++; //End Time. end_time = glfwGetTime(); //Total time after the frame completed. total_time += end_time - start_time; } //Terminate GLFW. glfwTerminate(); } //Load Scene. void Window::LoadScene(Scene * scene) { //Set the scene. m_Impl->scnene = scene; } //Get Delta Time. double Window::GetDeltaTime() { return m_Impl->delta_time; } //Get FPS. int Window::GetFPS() { return m_Impl->fps; } //Get Width. int Window::GetWidth() { return screen_width; } //Get Height. int Window::GetHeight() { return screen_height; } //Get Input. Input * Window::GetInput() { return m_Impl->input; } Renderer * Window::GetRenderer() { return m_Impl->renderer; } GLFWwindow * Window::GetGLFWindow() { return m_Impl->GLFW_window; } //Implementation Deconstructor. Window::Implementation::~Implementation() { delete renderer; delete input; } //OnWindowResize void OnWindowResize(GLFWwindow *window, int width, int height) { screen_width = width; screen_height = height; //Updating the ViewPort. GLCall(glViewport(0, 0, width, height)); }  
      Brain Class
      #include "Brain.h" #include "Sprite.h" #include "Window.h" struct Brain::Implementation { //Just A Flag. bool started; //Window Pointer. Window *window; //Sprite Pointer. Sprite *sprite; }; Brain::Brain(Window *window, Sprite *sprite) { //Create Pointer To Implementation. m_Impl = new Implementation(); //Initialize Implementation. m_Impl->started = true; m_Impl->window = window; m_Impl->sprite = sprite; } Brain::~Brain() { //Delete Pointer To Implementation. delete m_Impl; } void Brain::Start() { } void Brain::Update() { } Window * Brain::GetWindow() { return m_Impl->window; } Sprite * Brain::GetSprite() { return m_Impl->sprite; } bool Brain::GetStart() { return m_Impl->started; } void Brain::SetStart(bool value) { m_Impl->started = value; } Script Class (Its a Brain Subclass!!!)
      #include "Script.h" Script::Script(Window *window, Sprite *sprite) : Brain(window, sprite) { } Script::~Script() { } void Script::Start() { std::cout << "Game Started!" << std::endl; } void Script::Update() { Input *input = this->GetWindow()->GetInput(); Sprite *sp = this->GetSprite(); //Move this sprite. this->GetSprite()->Move(200 * this->GetWindow()->GetDeltaTime(), input->GetKeyDown("left"), input->GetKeyDown("right"), input->GetKeyDown("up"), input->GetKeyDown("down")); std::cout << sp->GetTag().c_str() << ".x = " << sp->GetPos()->x << ", " << sp->GetTag().c_str() << ".y = " << sp->GetPos()->y << std::endl; }  
      Main:
      #include "SpaceShooterEngine.h" #include "Script.h" int main() { Window w("title", 600,600); Scene *scene = new Scene(); Sprite *player = new Sprite("Resources/Images/player.png", "Player", 100,100); Sprite *other = new Sprite("Resources/Images/cherno.png", "Other", 400, 100); Sprite *other2 = new Sprite("Resources/Images/cherno.png", "Other", 300, 400); Brain *brain = new Script(&w, player); player->AddBrain(brain); scene->AddSprite(player); scene->AddSprite(other); scene->AddSprite(other2); w.LoadScene(scene); w.MainLoop(); return 0; }  
       
      I literally can't find what is wrong. If you need more code, ask me to post it. I will also attach all the source files.
      Brain.cpp
      Error.cpp
      IndexBuffer.cpp
      Input.cpp
      Renderer.cpp
      Scene.cpp
      Shader.cpp
      Sprite.cpp
      Texture.cpp
      VertexArray.cpp
      VertexBuffer.cpp
      VertexBufferLayout.cpp
      Window.cpp
      Brain.h
      Error.h
      IndexBuffer.h
      Input.h
      Renderer.h
      Scene.h
      Shader.h
      SpaceShooterEngine.h
      Sprite.h
      Texture.h
      VertexArray.h
      VertexBuffer.h
      VertexBufferLayout.h
      Window.h
    • By Cristian Decu
      Hello fellow programmers,
      For a couple of days now i've decided to build my own planet renderer just to see how floating point precision issues
      can be tackled. As you probably imagine, i've quickly faced FPP issues when trying to render absurdly large planets.
       
      I have used the classical quadtree LOD approach;
      I've generated my grids with 33 vertices, (x: -1 to 1, y: -1 to 1, z = 0).
      Each grid is managed by a TerrainNode class that, depending on the side it represents (top, bottom, left right, front, back),
      creates a special rotation-translation matrix that moves and rotates the grid away from the origin so that when i finally
      normalize all the vertices on my vertex shader i can get a perfect sphere.
      T = glm::translate(glm::dmat4(1.0), glm::dvec3(0.0, 0.0, 1.0)); R = glm::rotate(glm::dmat4(1.0), glm::radians(180.0), glm::dvec3(1.0, 0.0, 0.0)); sides[0] = new TerrainNode(1.0, radius, T * R, glm::dvec2(0.0, 0.0), new TerrainTile(1.0, SIDE_FRONT)); T = glm::translate(glm::dmat4(1.0), glm::dvec3(0.0, 0.0, -1.0)); R = glm::rotate(glm::dmat4(1.0), glm::radians(0.0), glm::dvec3(1.0, 0.0, 0.0)); sides[1] = new TerrainNode(1.0, radius, R * T, glm::dvec2(0.0, 0.0), new TerrainTile(1.0, SIDE_BACK)); // So on and so forth for the rest of the sides As you can see, for the front side grid, i rotate it 180 degrees to make it face the camera and push it towards the eye;
      the back side is handled almost the same way only that i don't need to rotate it but simply push it away from the eye.
      The same technique is applied for the rest of the faces (obviously, with the proper rotations / translations).
      The matrix that result from the multiplication of R and T (in that particular order) is send to my vertex shader as `r_Grid'.
      // spherify vec3 V = normalize((r_Grid * vec4(r_Vertex, 1.0)).xyz); gl_Position = r_ModelViewProjection * vec4(V, 1.0); The `r_ModelViewProjection' matrix is generated on the CPU in this manner.
      // No the most efficient way, but it works. glm::dmat4 Camera::getMatrix() { // Create the view matrix // Roll, Yaw and Pitch are all quaternions. glm::dmat4 View = glm::toMat4(Roll) * glm::toMat4(Pitch) * glm::toMat4(Yaw); // The model matrix is generated by translating in the oposite direction of the camera. glm::dmat4 Model = glm::translate(glm::dmat4(1.0), -Position); // Projection = glm::perspective(fovY, aspect, zNear, zFar); // zNear = 0.1, zFar = 1.0995116e12 return Projection * View * Model; } I managed to get rid of z-fighting by using a technique called Logarithmic Depth Buffer described in this article; it works amazingly well, no z-fighting at all, at least not visible.
      Each frame i'm rendering each node by sending the generated matrices this way.
      // set the r_ModelViewProjection uniform // Sneak in the mRadiusMatrix which is a matrix that contains the radius of my planet. Shader::setUniform(0, Camera::getInstance()->getMatrix() * mRadiusMatrix); // set the r_Grid matrix uniform i created earlier. Shader::setUniform(1, r_Grid); grid->render(); My planet's radius is around 6400000.0 units, absurdly large, but that's what i really want to achieve;
      Everything works well, the node's split and merge as you'd expect, however whenever i get close to the surface
      of the planet the rounding errors start to kick in giving me that lovely stairs effect.
      I've read that if i could render each grid relative to the camera i could get better precision on the surface, effectively
      getting rid of those rounding errors.
       
      My question is how can i achieve this relative to camera rendering in my scenario here?
      I know that i have to do most of the work on the CPU with double, and that's exactly what i'm doing.
      I only use double on the CPU side where i also do most of the matrix multiplications.
      As you can see from my vertex shader i only do the usual r_ModelViewProjection * (some vertex coords).
       
      Thank you for your suggestions!
       
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!