我有问题通过OpenGL显示我的渲染引擎的内容 [英] Am having problem displaying the content of my rendering engine through OpenGL
问题描述
我正在尝试使用OpenGL来显示渲染引擎的结果,但是我得到一个没有显示的空白屏幕。下面是我使用OpenGL调用的主要c ++文件和带有渲染引擎的文件。请问我做错了什么。 Jacco Bikker的原始光线跟踪使用Windows API(WinMain)显示结果,我遇到的问题是,在尝试使用cilk ++并行化代码时,它不适用于WinMain()方法。它只适用于c ++中的main()方法,这就是我使用OpenGL显示的原因。
请那些能帮助我的人...我非常感激。下面是进行OpenGL调用的主要c ++文件:
I am trying to use OpenGL to display the result of my rendering engine but I get a blank screen with no display. Below is my main c++ file with OpenGL calls and the file with the rendering engine. Please what am I doing wrongly. The original raytracing by Jacco Bikker displays the result alright using Windows API (WinMain), the problem I have with that is that while trying to parallelize the code using cilk++ it will not work with WinMain() method. It only works with main() method in c++ that is why am using OpenGL to display.
Please anyone there who can help me out...I deeply appreciate it. Below is the main c++ file where the OpenGL calls are made:
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include "common.h"
#include "raytracer.h"
#include "scene.h"
#include "surface.h"
#include "cilk.h"
#include "cilkview.h"
#include <cstdio>
#include <cassert>
#include <vector>
//#define SCRWIDTH 640
//#define SCRHEIGHT 480
#define SCRWIDTH 800
#define SCRHEIGHT 600
GLuint texture = 0;
Raytracer::Surface* surface = 0;
Pixel* buffer = 0;
Raytracer::Engine* tracer = 0;
void start(){
// prepare output canvas
surface = new Raytracer::Surface( SCRWIDTH, SCRHEIGHT );
buffer = surface->GetBuffer();
surface->Clear( 0 );
surface->InitCharset();
surface->Print( "timings:", 2, 2, 0xffffffff );
// prepare renderer
tracer = new Raytracer::Engine();
tracer->GetScene()->InitScene();
tracer->SetTarget( surface->GetBuffer(), SCRWIDTH, SCRHEIGHT );
int tpos = 60;
FILE *outFile;
outFile = fopen("RayTracing.out","a");
if (!outFile){
printf("Cannot open output file");
exit(1);
}
//Displaying the Trace Depth to output file
fprintf (outFile, "Tracing Depth : %d\n", TRACEDEPTH);
// go
while (1)
{
int fstart = GetTickCount();
tracer->InitRender();
while (!tracer->Render()) glutSwapBuffers();
int ftime = GetTickCount() - fstart;
char t[] = "00:00.000";
t[6] = (ftime / 100) % 10 + '0';
t[7] = (ftime / 10) % 10 + '0';
t[8] = (ftime % 10) + '0';
int secs = (ftime / 1000) % 60;
int mins = (ftime / 60000) % 100;
t[3] = ((secs / 10) % 10) + '0';
t[4] = (secs % 10) + '0';
t[1] = (mins % 10) + '0';
t[0] = ((mins / 10) % 10) + '0';
float par_time = ftime / 1000.f; //Time accumulated is converted to seconds and stored in a variable
fprintf (outFile, "%.3f\n", par_time);
fflush (stdout);
surface->Print( t, tpos, 2, 0xffffffff );
tpos += 100;
}
}
void render(void) {
start();
glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2i(0, 0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, texture);
glDrawPixels(SCRWIDTH, SCRHEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glutSwapBuffers();
glutPostRedisplay();
}
void reshape(int x, int y) {
glViewport(0, 0, x, y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
}
void appInit(int w, int h) {
glGenBuffersARB(1, &texture);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, texture);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, w * h * sizeof(GLubyte) * 4, 0, GL_STREAM_DRAW_ARB);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
}
void idle() { glutPostRedisplay(); }
void cleanup(){
glDeleteBuffersARB(1, &texture);
}
int main(int argc, char **argv) {
atexit(cleanup);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(SCRWIDTH, SCRHEIGHT);
glutCreateWindow("Cilk Plus raytracer");
glewInit();
appInit(SCRWIDTH, SCRHEIGHT);
glutDisplayFunc(render);
glutIdleFunc(idle);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
光线跟踪引擎位于以下文件中:
raytracer.cpp
The raytracing engine is in the following file:
raytracer.cpp
// -----------------------------------------------------------
// raytracer.cpp
// 2004 - Jacco Bikker - jacco@bik5.com - www.bik5.com - <><
// -----------------------------------------------------------
#include "raytracer.h"
#include "scene.h"
#include "common.h"
#include "windows.h"
#include "winbase.h"
#include "cilk.h"
namespace Raytracer {
Ray::Ray( vector3& a_Origin, vector3& a_Dir ) :
m_Origin( a_Origin ),
m_Direction( a_Dir )
{
}
Engine::Engine()
{
m_Scene = new Scene();
}
Engine::~Engine()
{
delete m_Scene;
}
// -----------------------------------------------------------
// Engine::SetTarget
// Sets the render target canvas
// -----------------------------------------------------------
void Engine::SetTarget( Pixel* a_Dest, int a_Width, int a_Height )
{
// set pixel buffer address & size
m_Dest = a_Dest;
m_Width = a_Width;
m_Height = a_Height;
}
// -----------------------------------------------------------
// Engine::Raytrace
// Naive ray tracing: Intersects the ray with every primitive
// in the scene to determine the closest intersection
// -----------------------------------------------------------
Primitive* Engine::Raytrace( Ray& a_Ray, Color& a_Acc, int a_Depth, float a_RIndex, float& a_Dist )
{
if (a_Depth > TRACEDEPTH) return 0;
// trace primary ray
a_Dist = 1000000.0f;
vector3 pi;
Primitive* prim = 0;
int result;
// find the nearest intersection
for ( int s = 0; s < m_Scene->GetNrPrimitives(); s++ )
{
Primitive* pr = m_Scene->GetPrimitive( s );
int res;
if (res = pr->Intersect( a_Ray, a_Dist ))
{
prim = pr;
result = res; // 0 = miss, 1 = hit, -1 = hit from inside primitive
}
}
// no hit, terminate ray
if (!prim) return 0;
// ---- Handle intersection ----
if (prim) {
// Update statistics
//m_statisticsDataStructCpp->rayIntersectionsCount[0]++;
if (prim->IsLight())
{
// we hit a light, stop tracing
a_Acc =Color( 1.0f, 1.0f, 1.0f );
}
else
{
// determine color at point of intersection
pi = a_Ray.GetOrigin() + a_Ray.GetDirection() * a_Dist;
// trace lights
for ( int l = 0; l < m_Scene->GetNrPrimitives(); l++ )
{
Primitive* p = m_Scene->GetPrimitive( l );
if (p->IsLight())
{
Primitive* light = p;
// handle point light source
float shade = 1.0f;
if (light->GetType() == Primitive::SPHERE)
{
vector3 L = ((Sphere*)light)->GetCentre() - pi;
float tdist = LENGTH( L );
NORMALIZE(L);
vector3 TempVector3(pi + L * EPSILON);
Ray r = Ray( TempVector3, L );
for ( int s = 0; s < m_Scene->GetNrPrimitives(); s++ )
{
Primitive* pr = m_Scene->GetPrimitive( s );
if ((pr != light) && (pr->Intersect( r, tdist )))
{
shade = 0;
break;
}
}
}
if (shade > 0)
{
vector3 L = ((Sphere*)light)->GetCentre() - pi;
NORMALIZE( L );
vector3 N = prim->GetNormal( pi );
// determine diffuse component
if (prim->GetMaterial()->GetDiffuse() > 0)
{
float dot = DOT( L, N );
if (dot > 0)
{
float diff = dot * prim->GetMaterial()->GetDiffuse() * shade;
// add diffuse component to ray color
Color ncol = diff * prim->GetMaterial()->GetColor();
// Scale back the color, if necessary
if (ncol.r > 1.0f || ncol.g > 1.0f || ncol.b > 1.0f)
{
float max = 1.0f;
if (ncol.r > max) max = ncol.r;
if (ncol.g > max) max = ncol.g;
if (ncol.b > max) max = ncol.b;
ncol *= 1.0f/max;
}
a_Acc += ncol;
}
}
// determine specular component
if (prim->GetMaterial()->GetSpecular() > 0)
{
// point light source: sample once for specular highlight
vector3 V = a_Ray.GetDirection();
vector3 R = L - 2.0f * DOT( L, N ) * N;
float dot = DOT( V, R );
if (dot > 0)
{
float spec = powf( dot, 20 ) * prim->GetMaterial()->GetSpecular() * shade;
// add specular component to ray color
Color ncol = spec * light->GetMaterial()->GetColor();
// Adjust specular component to be within 0 <-> 1.0
if (ncol.r > 1.0f) ncol.r = 1.0f; else if (ncol.r < 0.0f) ncol.r = 0.0f;
if (ncol.g > 1.0f) ncol.g = 1.0f; else if (ncol.g < 0.0f) ncol.g = 0.0f;
if (ncol.b > 1.0f) ncol.b = 1.0f; else if (ncol.b < 0.0f) ncol.b = 0.0f;
a_Acc += ncol;
}
}
}
}
}
// Scale back the local color contribution, if necessary
if (a_Acc.r > 1.0f || a_Acc.g > 1.0f || a_Acc.b > 1.0f)
{
float max = 1.0f;
if (a_Acc.r > max) max = a_Acc.r;
if (a_Acc.g > max) max = a_Acc.g;
if (a_Acc.b > max) max = a_Acc.b;
a_Acc *= 1.0f/max;
}
// -- Calculate reflection --
float refl = prim->GetMaterial()->GetReflection();
if ((refl > 0.0f) && (a_Depth < TRACEDEPTH))
{
vector3 N = prim->GetNormal( pi );
vector3 R = a_Ray.GetDirection() - 2.0f * DOT( a_Ray.GetDirection(), N ) * N;
Color rcol( 0.0f, 0.0f, 0.0f );
float dist;
vector3 TempVector3(pi + R * EPSILON);
Ray TempRay(TempVector3, R);
Raytrace( TempRay, rcol, a_Depth + 1, a_RIndex, dist );
a_Acc += refl * rcol;
}
}
}
else {
// -- No intersection occured; stop tracing --
// Update statistics
//m_statisticsDataStructCpp->rayMissesCount[0]++;
// Do nothing
}
// return pointer to primitive hit by primary ray
return prim;
}
// -----------------------------------------------------------
// Engine::InitRender
// Initializes the renderer, by resetting the line / tile
// counters and precalculating some values
// -----------------------------------------------------------
void Engine::InitRender()
{
// set firts line to draw to
m_CurrLine = 20;
// set pixel buffer address of first pixel
m_PPos = 20 * m_Width;
// screen plane in world space coordinates
m_WX1 = -4, m_WX2 = 4, m_WY1 = m_SY = 3, m_WY2 = -3;
// calculate deltas for interpolation
m_DX = (m_WX2 - m_WX1) / m_Width;
m_DY = (m_WY2 - m_WY1) / m_Height;
m_SY += 20 * m_DY;
// allocate space to store pointers to primitives for previous line
m_LastRow = new Primitive*[m_Width];
memset( m_LastRow, 0, m_Width * 4 );
// statistics
m_RayMissesCount = 0;
m_RayIntersectionsCount = 0;
}
void Engine::PreRender() {
// Prepare linearized data
m_spheres.clear();
m_planes.clear();
Sphere* tempSphere;
PlanePrim* tempPlane;
int sphereCount;
int planesCount;
Primitive* prim;
for (int i = 0; i < m_Scene->GetNrPrimitives(); i++) {
prim = m_Scene->GetPrimitive(i);
tempSphere = dynamic_cast<Sphere*> (prim);
if (dynamic_cast<Sphere*> (prim) != 0){
m_spheres.push_back(tempSphere);
// continue;
}
tempPlane = dynamic_cast<PlanePrim*> (prim);
if (dynamic_cast<PlanePrim*> (prim) != 0)
m_planes.push_back(tempPlane);
}
// Spheres
m_sphereDataStructCpp = new SphereDataStructCpp(m_spheres.size());
for (int i = 0; i < m_spheres.size(); i++) {
tempSphere = m_spheres[i];
// Geometric Data
m_sphereDataStructCpp->centerX[i] = tempSphere->GetCentre().x;
m_sphereDataStructCpp->centerY[i] = tempSphere->GetCentre().y;
m_sphereDataStructCpp->centerZ[i] = tempSphere->GetCentre().z;
m_sphereDataStructCpp->recRadius[i] = tempSphere->GetRecRadius();
m_sphereDataStructCpp->sqRadius[i] = tempSphere->GetSqRadius();
// Material Data
m_sphereDataStructCpp->diffuse[i] = tempSphere->GetMaterial()->GetDiffuse();
m_sphereDataStructCpp->specular[i] = tempSphere->GetMaterial()->GetSpecular();
m_sphereDataStructCpp->reflection[i] = tempSphere->GetMaterial()->GetReflection();
m_sphereDataStructCpp->refraction[i] = tempSphere->GetMaterial()->GetRefraction();
m_sphereDataStructCpp->refrIndex[i] = tempSphere->GetMaterial()->GetRefrIndex();
// Color Data
m_sphereDataStructCpp->red[i] = tempSphere->GetMaterial()->GetColor().r;
m_sphereDataStructCpp->green[i] = tempSphere->GetMaterial()->GetColor().g;
m_sphereDataStructCpp->blue[i] = tempSphere->GetMaterial()->GetColor().b;
// Light?
m_sphereDataStructCpp->isLight[i] = tempSphere->IsLight();
}
// Planes
m_planeDataStructCpp = new PlaneDataStructCpp(m_planes.size());
for (int i = 0; i < m_planes.size(); i++) {
tempPlane = m_planes[i];
// Geometric data
m_planeDataStructCpp->normalX[i] = tempPlane->GetNormal().x;
m_planeDataStructCpp->normalY[i] = tempPlane->GetNormal().y;
m_planeDataStructCpp->normalZ[i] = tempPlane->GetNormal().z;
m_planeDataStructCpp->d[i] = tempPlane->GetD();
// Material data
m_planeDataStructCpp->diffuse[i] = tempPlane->GetMaterial()->GetDiffuse();
m_planeDataStructCpp->specular[i] = tempPlane->GetMaterial()->GetSpecular();
m_planeDataStructCpp->reflection[i] = tempPlane->GetMaterial()->GetReflection();
m_planeDataStructCpp->refraction[i] = tempPlane->GetMaterial()->GetRefraction();
m_planeDataStructCpp->refrIndex[i] = tempPlane->GetMaterial()->GetRefrIndex();
// Color data
m_planeDataStructCpp->red[i] = tempPlane->GetMaterial()->GetColor().r;
m_planeDataStructCpp->green[i] = tempPlane->GetMaterial()->GetColor().g;
m_planeDataStructCpp->blue[i] = tempPlane->GetMaterial()->GetColor().b;
// Light data
m_planeDataStructCpp->isLight[i] = tempPlane->IsLight();
}
// Statistics
m_RayMissesCount = 0;
m_RayIntersectionsCount = 0;
m_statisticsDataStructCpp = new StatisticsDataStructCpp((size_t)m_CohortPSize);
}
// -----------------------------------------------------------
// Engine::Render
// Fires rays in the scene one scanline at a time, from left
// to right
// -----------------------------------------------------------
bool Engine::Render()
{
// render scene
vector3 o( 0, 0, -5 );
// initialize timer
int msecs = GetTickCount();
// reset last found primitive pointer
Primitive* lastprim = 0;
// render remaining lines
for ( int y = m_CurrLine; y < (m_Height - 20); y++ )
{
m_SX = m_WX1;
// render pixels for current line
for ( int x = 0; x < m_Width; x++ )
{
// fire primary ray
Color acc( 0, 0, 0 );
vector3 dir = vector3( m_SX, m_SY, 0 ) - o;
NORMALIZE( dir );
Ray r( o, dir );
float dist;
Primitive* prim = Raytrace( r, acc, 1, 1.0f, dist );
int red = (int)(acc.r * 256);
int green = (int)(acc.g * 256);
int blue = (int)(acc.b * 256);
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
m_Dest[m_PPos++] = (red << 16) + (green << 8) + blue;
m_SX += m_DX;
}
m_SY += m_DY;
// see if we've been working to long already
if ((GetTickCount() - msecs) > 100)
{
// return control to windows so the screen gets updated
m_CurrLine = y + 1;
return false;
}
}
// all done
return true;
}
}; // namespace Raytracer
推荐答案
这篇关于我有问题通过OpenGL显示我的渲染引擎的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!