我正在努力将我的开源粒子引擎测试从SDL移植到SDL + OpenGL。我已经设法让它进行编译和运行,但无论我做什么,屏幕都会保持黑屏。 main.cpp中:
#include "glengine.h"
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//Create a glengine instance
ultragl::glengine *gle = new ultragl::glengine();
if(gle->init())
gle->run();
else
std::cout << "glengine initializiation failed!" << std::endl;
//If we can't initialize, or the lesson has quit we delete the instance
delete gle;
return 0;
};
glengine.h:
//we need to include window first because GLee needs to be included before GL.h
#include "window.h"
#include <math.h> // Math Library Header File
#include <vector>
#include <stdio.h>
using namespace std;
namespace ultragl
{
class glengine
{
protected:
window m_Window; ///< The window for this lesson
unsigned int m_Keys[SDLK_LAST]; ///< Stores keys that are pressed
float piover180;
virtual void draw();
virtual void resize(int x, int y);
virtual bool processEvents();
void controls();
private:
/*
* We need a structure to store our vertices in, otherwise we
* just had a huge bunch of floats in the end
*/
struct Vertex
{
float x, y, z;
Vertex(){}
Vertex(float x, float y, float z)
{
this->x = x;
this->y = y;
this->z = z;
}
};
struct particle
{
public :
double angle;
double speed;
Vertex v;
int r;
int g;
int b;
int a;
particle(double angle, double speed, Vertex v, int r, int g, int b, int a)
{
this->angle = angle;
this->speed = speed;
this->v = v;
this->r = r;
this->g = g;
this->b = b;
this->a = a;
}
particle()
{
}
};
particle p[500];
float particlesize;
public:
glengine();
~glengine();
virtual void run();
virtual bool init();
void glengine::test2(int num);
void glengine::update();
};
};
window.h中:
#include <string>
#include <iostream>
#include "GLee/GLee.h"
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <GL/glu.h>
using namespace std;
namespace ultragl
{
class window
{
private:
int w_height;
int w_width;
int w_bpp;
bool w_fullscreen;
string w_title;
public:
window();
~window();
bool createWindow(int width, int height, int bpp, bool fullscreen, const string& title);
void setSize(int width, int height);
int getHeight();
int getWidth();
};
};
glengine.cpp(主要看一下):
#include "glengine.h"
namespace ultragl{
glengine::glengine()
{
piover180 = 0.0174532925f;
}
glengine::~glengine()
{
}
void glengine::resize(int x, int y)
{
std::cout << "Resizing Window to " << x << "x" << y << std::endl;
if (y <= 0)
{
y = 1;
}
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)x/(GLfloat)y,1.0f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
bool glengine::processEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))//get all events
{
switch (event.type)
{
// Quit event
case SDL_QUIT:
{
// Return false because we are quitting.
return false;
}
case SDL_KEYDOWN:
{
SDLKey sym = event.key.keysym.sym;
if(sym == SDLK_ESCAPE) //Quit if escape was pressed
{
return false;
}
m_Keys[sym] = 1;
break;
}
case SDL_KEYUP:
{
SDLKey sym = event.key.keysym.sym;
m_Keys[sym] = 0;
break;
}
case SDL_VIDEORESIZE:
{
//the window has been resized so we need to set up our viewport and projection according to the new size
resize(event.resize.w, event.resize.h);
break;
}
// Default case
default:
{
break;
}
}
}
return true;
}
bool glengine::init()
{
srand( time( NULL ) );
for(int i = 0; i < 500; i++)
p[i] = particle(0, 0, Vertex(0.0f, 0.0f, 0.0f), 0, 0, 0, 0);
if (!m_Window.createWindow(640, 480, 32, false, "Paricle Test GL"))
{
return false;
}
particlesize = 0.01;
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glEnable(GL_BLEND);
glBlendFunc(GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
return true;
}
void glengine::test2(int num)
{
glPushMatrix();
glTranslatef(p[num].v.x, p[num].v.y, p[num].v.z);
glBegin(GL_QUADS);
glColor4i(p[num].r, p[num].g, p[num].b, p[num].a); // Green for x axis
glVertex3f(-particlesize, -particlesize, particlesize);
glVertex3f( particlesize, -particlesize, particlesize);
glVertex3f( particlesize, particlesize, particlesize);
glVertex3f(-particlesize, particlesize, particlesize);
glEnd();
glPopMatrix();
}
void glengine::draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
gluLookAt(0, 5, 20, 0, 0, 0, 0, 0, 0);
for(int i = 0; i < 500; i++)
test2(i);
}
void glengine::update()
{
for(int i = 0; i < 500; i++)
{
if(p[i].a <= 0)
p[i] = particle(5 + rand() % 360, (rand() % 10) * 0.1, Vertex(0.0f, 0.0f, 0.0f), 0, 255, 255, 255);
else
p[i].a -= 1;
p[i].v.x += (sin(p[i].angle * (3.14159265/180)) * p[i].speed);
p[i].v.y -= (cos(p[i].angle * (3.14159265/180)) * p[i].speed);
}
}
void glengine::run()
{
while(processEvents())
{
update();
draw();
SDL_GL_SwapBuffers();
}
}
};
最后是window.cpp:
#include "window.h"
namespace ultragl
{
window::window(): w_width(0), w_height(0), w_bpp(0), w_fullscreen(false)
{
}
window::~window()
{
SDL_Quit();
}
bool window::createWindow(int width, int height, int bpp, bool fullscreen, const string& title)
{
if( SDL_Init( SDL_INIT_VIDEO ) != 0 )
return false;
w_height = height;
w_width = width;
w_title = title;
w_fullscreen = fullscreen;
w_bpp = bpp;
//Set lowest possiable values.
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
//Set title.
SDL_WM_SetCaption(title.c_str(), title.c_str());
// Flags tell SDL about the type of window we are creating.
int flags = SDL_OPENGL;
if(fullscreen == true)
flags |= SDL_FULLSCREEN;
// Create window
SDL_Surface * screen = SDL_SetVideoMode( width, height, bpp, flags );
if(screen == 0)
return false;
//SDL doesn't trigger off a ResizeEvent at startup, but as we need this for OpenGL, we do this ourself
SDL_Event resizeEvent;
resizeEvent.type = SDL_VIDEORESIZE;
resizeEvent.resize.w = width;
resizeEvent.resize.h = height;
SDL_PushEvent(&resizeEvent);
return true;
}
void window::setSize(int width, int height)
{
w_height = height;
w_width = width;
}
int window::getHeight()
{
return w_height;
}
int window::getWidth()
{
return w_width;
}
};
无论如何,我真的需要完成这个,但我已经尝试过我能想到的一切。我在一个点上测试了glengine文件的许多不同方式:
#include "glengine.h"
#include "SOIL/SOIL.h"
#include "SOIL/stb_image_aug.h"
#include "SOIL/image_helper.h"
#include "SOIL/image_DXT.h"
namespace ultragl{
glengine::glengine()
{
piover180 = 0.0174532925f;
}
glengine::~glengine()
{
}
void glengine::resize(int x, int y)
{
std::cout << "Resizing Window to " << x << "x" << y << std::endl;
if (y <= 0)
{
y = 1;
}
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)x/(GLfloat)y,1.0f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
bool glengine::processEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))//get all events
{
switch (event.type)
{
// Quit event
case SDL_QUIT:
{
// Return false because we are quitting.
return false;
}
case SDL_KEYDOWN:
{
SDLKey sym = event.key.keysym.sym;
if(sym == SDLK_ESCAPE) //Quit if escape was pressed
{
return false;
}
m_Keys[sym] = 1;
break;
}
case SDL_KEYUP:
{
SDLKey sym = event.key.keysym.sym;
m_Keys[sym] = 0;
break;
}
case SDL_VIDEORESIZE:
{
//the window has been resized so we need to set up our viewport and projection according to the new size
resize(event.resize.w, event.resize.h);
break;
}
// Default case
default:
{
break;
}
}
}
return true;
}
bool glengine::init()
{
srand( time( NULL ) );
for(int i = 0; i < 500; i++)
p[i] = particle(0, 0, Vertex(0.0f, 0.0f, 0.0f), 0, 0, 0, 0);
if (!m_Window.createWindow(640, 480, 32, false, "Paricle Test GL"))
{
return false;
}
particlesize = 10.01;
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glEnable(GL_BLEND);
glBlendFunc(GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
return true;
}
void glengine::test2(int num)
{
//glPushMatrix();
//glTranslatef(p[num].v.x, p[num].v.y, p[num].v.z);
glColor4i(255, 255, 255, 255);
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glVertex3f(-particlesize, -particlesize, particlesize);
glVertex3f( particlesize, -particlesize, particlesize);
glVertex3f( particlesize, particlesize, particlesize);
glVertex3f(-particlesize, particlesize, particlesize);
glEnd();
// Back Face
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f,-1.0f);
glVertex3f(-particlesize, -particlesize, -particlesize);
glVertex3f(-particlesize, particlesize, -particlesize);
glVertex3f( particlesize, particlesize, -particlesize);
glVertex3f( particlesize, -particlesize, -particlesize);
glEnd();
// Top Face
glBegin(GL_QUADS);
glNormal3f( 0.0f, 1.0f, 0.0f);
glVertex3f(-particlesize, particlesize, -particlesize);
glVertex3f(-particlesize, particlesize, particlesize);
glVertex3f( particlesize, particlesize, particlesize);
glVertex3f( particlesize, particlesize, -particlesize);
glEnd();
// Bottom Face
glBegin(GL_QUADS);
glNormal3f( 0.0f,-1.0f, 0.0f);
glVertex3f(-particlesize, -particlesize, -particlesize);
glVertex3f( particlesize, -particlesize, -particlesize);
glVertex3f( particlesize, -particlesize, particlesize);
glVertex3f(-particlesize, -particlesize, particlesize);
glEnd();
// Right face
glBegin(GL_QUADS);
glNormal3f( 1.0f, 0.0f, 0.0f);
glVertex3f( particlesize, -particlesize, -particlesize);
glVertex3f( particlesize, particlesize, -particlesize);
glVertex3f( particlesize, particlesize, particlesize);
glVertex3f( particlesize, -particlesize, particlesize);
glEnd();
// Left Face
glBegin(GL_QUADS);
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-particlesize, -particlesize, -particlesize);
glVertex3f(-particlesize, -particlesize, particlesize);
glVertex3f(-particlesize, particlesize, particlesize);
glVertex3f(-particlesize, particlesize, -particlesize);
glEnd();
//glPopMatrix();
}
void glengine::draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
gluLookAt(0, 5, 20, 0, 0, 0, 0, 1, 0);
for(int i = 0; i < 500; i++)
test2(i);
}
void glengine::update()
{
for(int i = 0; i < 500; i++)
{
if(p[i].a <= 0)
p[i] = particle(5 + rand() % 360, (rand() % 10) * 0.1, Vertex(0.0f, 0.0f, -5.0f), 0, 255, 255, 255);
else
p[i].a -= 1;
p[i].v.x += (sin(p[i].angle * (3.14159265/180)) * p[i].speed);
p[i].v.y -= (cos(p[i].angle * (3.14159265/180)) * p[i].speed);
}
}
void glengine::run()
{
while(processEvents())
{
update();
draw();
SDL_GL_SwapBuffers();
}
}
};
它仍然无效。我真的很想知道这个。
答案 0 :(得分:4)
我没有检查过你的代码,但是在调试这类问题时我总是会做的一件事就是将清晰的颜色设置为彩色的东西,如(1,0,1)左右。
这将帮助您查看问题是您的绘制对象是完全黑色还是根本没有绘制。
编辑: 正如评论中提到的那样:如果清除操作清除到正确的颜色或者它保持黑色,它还会显示您是否有正确的GL上下文。
答案 1 :(得分:2)
好的,我设法使用了很多你的建议以及其他一些其他源代码来修复它。事实证明问题来自3个不同的行。
粒子大小= 0.01;应该更大:粒度= 1.01;
glColor4i(255, 255, 255, 255)
正在将立方体变成与清晰颜色相同的颜色,因为我使用它错了。我无法弄清楚如何正确使用它,所以我使用glColor4f(0.0f,1.0f,1.0f,0.5f)
代替,这是有效的。
最后gluLookAt(0, 5, 20, 0, 0, 0, 0, 0, 0)
需要gluLookAt(0, 5, 20, 0, 0, 0, 0, 1, 0)
谢谢大家的帮助和时间。
答案 2 :(得分:1)
您没有检查SDL-GL-SetAttribute()调用的返回值。
您的视频卡是否支持5/5/5/5 20-bpp颜色?
答案 3 :(得分:0)
检查OpenGL的错误状态。使用glslDevil
,glIntercept
或gDebugger
。检查glGetError
功能。你能测试一下SDL是否真的获得了设备上下文吗?
窗口是否反映了glClearColor调用中的变化?不要在glClearColor
中使用0.5作为alpha值。
尝试这些建议,并以Simucal建议的最小例子报告。