Advertisement

Particle (star) rendering not working.

Started by September 28, 2019 11:37 PM
21 comments, last by Sword7 5 years, 4 months ago

I am working on my new routines for rendering star (or particle) points (varying size and brightness) for starry sky.  It did not work so well because it did not display stars except legacy glVertex calls (or glDrawArrays without GLSL programs).  With my GLSL programs, it displayed nothing.  I did enabled GL_PROGRAM_POINT_SIZE before glDrawArrays calls.

That's why I am developing orbital flight simulator myself for space travels like Orbiter or MS Space Simulator and interstellar travels like Star Trek.

Here are my GLSL programs.  That should render square points as expected (very simple at this time).  It happened nothing.  Does anyone have any solution for GLSL 4.x codes for OpenGL core profile 4.x? 

I googled for particle/star rendering demos and found some sources.  But they are using old OpenGL legacy calls or old GLSL codes that may not work with modern OpenGL core 4.x.  I found only one source (Gaiasky) that uses newer version core 330 but GLSL codes looks more complex.

 


#version 420

layout (location = 0) in vec3  vPosition;
layout (location = 1) in vec4  vColor;
layout (location = 2) in float vSize;

uniform mat4 mvp;

out vec4 starColor;

void main()
{
    gl_Position  = mvp * vec4(vPosition, 1.0);
    gl_PointSize = vSize;
    starColor = vColor;
}

#version 420

in vec4  starColor;
out vec4 fragColor;

void main()
{
    fragColor = starColor;
}

 

No one answer that?!   I played some code and discovered that something erased particles/stars rendering before displayed earth.  When I commented out rendering for earth, stars (point sprites) appeared on my screen!  When I re-enable earth rendering, stars disappeared!  I can't display earth and stars in the same frame! any solution?

Advertisement

guess: maybe you clear the framebuffer in between ?

Another possible causes: you change the value of some OpenGL state variables in order to render the Earth, and don't change them back in order to render the stars.

You haven't posted nearly enough information to diagnose your problem, so this is just a wild guess.

I did cleared framebuffer before starting star rendering then planet rendering.  I think that problem is GL_DEPTH_TEST cause old rendering erase.

Trying to rendering stars and planets in the same framebuffer.


glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

renderStars(*universe->getStarCatalogue(), *player, 6.0);

// glDepthMask(GL_FALSE);
vobj->render(prm);
// glDepthMask(GL_TRUE);

 

To initializing routines when start program.


glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

 

To rendering stars at beginning


glDisable(GL_DEPTH_TEST);
glEnable(GL_PROGRAM_POINT_SIZE);
glPointSize(1.0);


glDrawArrays(GL_POINTS, 0, nStars);

To finishing star rendering


glDisable(GL_PROGRAM_POINT_SIZE);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);

 

To rendering planet (very simple):


glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawElements(GL_TRIANGLES, nidx, GL_UNSIGNED_SHORT, 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glDisable(GL_CULL_FACE);

 

I tried to commented all GL_DEPTH_TEST enable and disable calls out but stars and earth are not visible - just blank screen.  I commented earth rendering out and stars are now displayed.  I tried to comment glUseProgram(0) out after star rendering but it happened nothing. Not needed anymore.

Also I tried to comment cull face calls out but stars are still not visible but earth looks distorted. I can't still resolve that issues and have to study more.

I updated star-fs.glsl to render circular points now instead of squares (default rendering).


#version 420

in vec4  starColor;
out vec4 fragColor;

//layout (binding = 0) uniform sampler2D starTex;

void main()
{
	// Rendering circular points
	vec2 circCoord = (gl_PointCoord * 2.0) - 1.0;
	if (dot(circCoord, circCoord) > 1.0)
		discard;

	fragColor = /* texture(starTex, gl_PointCoord) * */ starColor;
}

 

Advertisement

I am unable resolve a problem with rendering stars while rendering earth.  Both can't be rendered in the same time.  Either objects can be rendered once at this time because earth rendering unseenly wiped out rendered stars.  I tried rendered stars after rendered earth but it did not work.  Without earth rendering, I can only see stars.  Star's positions are very very distant away (trillion miles).   Near and far settings are 0.0001 and 1.0e15 for perspective.  I created 2nd earth as testing and I can now see two earths in the same time but still no stars.  Two shader programs (for stars and planet) have separated VAO/VBO buffer assignments for vertex streaming.

I see two problems here, gl state and depth buffer:

First the gl state, which appears a little confused to me. Maybe ask yourself "what settings do my render objects need ?" and "how do i order them so that everything is rendered the way i want ?". Second the depth buffer. These settings don't work. The book on globe rendering has a chapter on depth buffer precision and limits (pp. 181ff).

Suggestion (but there are probably other ways): render the background to a skybox, which is a simple object to render and doesn't influence the depth range at all. The depth range is then free to float in and out as the current viewer's position demand but will never need these values and ranges that are impossible to resolve within a 24 or 32 bit depth buffer.

Maybe i am wrong, then hopefully somebody will correct me.

Ok, I found a problem that was vertex arrays (VAOs) when I implemented constellation lines through GPU process.  That went into crash during rendering and displayed weird colorful lines much like line demo programs because they are using wrong vertex buffers.  When I commented rendering stars out, it correctly displayed constellation lines.

I put some additional bind/unbind calls and everything went erratic. I tried to render earth, stars and constellation lines.  Mixed oversized stars (circular points), randomly colorful lines and earth all messed up.  Each rendered objects have separated own VAOs.

I have to re-write my vertex buffer handler for VAOs, VBOs and EBOs to clear mess up.

I tried many different ways of VAO/VBO but it did not work so well. When attempted to two rendered objects with own separated VAOs, vertex buffers went garbage (overwritten).  Here are my codes about vertex buffer calls.  I will update this for multi-buffer handling later.
It only use one buffer at all time for now.  I can only render one rendered object at this time and it worked fine.  It displays constellation lines or varying-size star points clearly. When I attempted to display rendered star objects and rendered constellation line objects, display  garbage like colorful lines and oversized star points instead.


class VertexBuffer
{
public:
    enum BufferType {
        VAO, VBO, EBO
    };

    VertexBuffer(const Context &gl, int nArrays = 1);
    ~VertexBuffer();

    inline void bind() const { glBindVertexArray(vao); };
    inline void unbind() const { glBindVertexArray(0); };

    void createBuffer(BufferType type, uint32_t nBuffers);
    void assign(BufferType type, void *data, uint32_t size);

private:
    const Context ≷

    GLuint vao, vbo, ebo;
};

VertexBuffer::VertexBuffer(const Context &gl, int nArrays)
: gl(gl), vao(0), vbo(0), ebo(0)
{
    glGenVertexArrays(nArrays, &vao);
}

VertexBuffer::~VertexBuffer()
{
    if (vbo > 0)
        glDeleteBuffers(1, &vbo);
    if (ebo > 0)
        glDeleteBuffers(1, &ebo);
    if (vao > 0)
        glDeleteVertexArrays(1, &vao);
}

void VertexBuffer::createBuffer(BufferType type, uint32_t nBuffers)
{
	bind();
	switch (type) {
	case VBO:
		glGenBuffers(nBuffers, &vbo);
		break;
	case EBO:
		glGenBuffers(nBuffers, &ebo);
		break;
	}
}

void VertexBuffer::assign(BufferType type, void *data, uint32_t size)
{
    bind();
	switch (type) {
	case VBO:
		glBindBuffer(GL_ARRAY_BUFFER, vbo);
		glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
		break;
	case EBO:
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
		break;
	}
    // glBindBuffer(GL_ARRAY_BUFFER, 0);
    // unbind();
}

 

Here is one of rendered objects - constellation lines rendering.


void Scene::initConstellations(const Universe &universe)
{
	const Constellations &constellations = universe.getAsterism();
	const StarCatalogue &starlib = *universe.getStarCatalogue();
	const vector<Asterism *> &asterisms = constellations.getAsterisms();

	pgmAsterism = smgr.createShader("line");

	pgmAsterism->use();

	vbufAsterism = new VertexBuffer(gl, 1);
	vbufAsterism->createBuffer(VertexBuffer::VBO, 1);

	int cLines = 0;
	for (int idx = 0; idx < asterisms.size(); idx++) {
		Asterism *aster = asterisms[idx];
		cLines += aster->hip.size();
	}
	bufAsterism = new VertexLine[cLines];

	cout << "VertexLine Size: " << sizeof(VertexLine) << endl;
}

void Scene::renderConstellations(const Universe &universe, const Player &player)
{
	const Constellations &constellations = universe.getAsterism();
	const StarCatalogue &starlib = *universe.getStarCatalogue();
	const vector<Asterism *> &asterisms = constellations.getAsterisms();

	Camera *cam = player.getCamera(0);
	vec3d_t cpos = cam->getPosition();
	int cLines = 0;

	pgmAsterism->use();
	vbufAsterism->bind();

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexLine), (void *)0);
	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexLine), (void *)(3 * sizeof(float)));
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

	int rLines = 0;
	for (int idx = 0; idx < asterisms.size(); idx++) {
		Asterism *aster = asterisms[idx];
		for (int sidx = 0; sidx < aster->hip.size(); sidx += 2) {
			CelestialStar *star1 = starlib.getHIPStar(aster->hip[sidx]);
			CelestialStar *star2 = starlib.getHIPStar(aster->hip[sidx+1]);

			if (star1 == nullptr)
				std::cout << "HIP " << aster->hip[sidx] << " Missing" << std::endl;
			if (star2 == nullptr)
				std::cout << "HIP " << aster->hip[sidx+1] << " Missing" << std::endl;
			if (star1 == nullptr || star2 == nullptr)
				continue;

			bufAsterism[rLines].lpos   = vec3f_t(star1->getPosition(0) * KM_PER_PC);
			bufAsterism[rLines].color  = Color(0.2, 0.2, 0.2, 1.0);
			rLines++;
			bufAsterism[rLines].lpos   = vec3f_t(star2->getPosition(0) * KM_PER_PC);
			bufAsterism[rLines].color  = Color(0.2, 0.2, 0.2, 1.0);
			rLines++;

//			std::cout << "HIP: " << aster->hip[sidx]
//					  << " Name: " << star->name(0) << std::endl;
		}
//		std::cout << std::endl;
	}

	vbufAsterism->assign(VertexBuffer::VBO, bufAsterism, sizeof(VertexLine)*rLines);

	mat4f_t mvp = mat4f_t (prm.dmProj * prm.dmView * mat4d_t(1.0));

	uint32_t mvpLoc = glGetUniformLocation(pgmAsterism->getID(), "mvp");
    glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(mvp));

	glDrawArrays(GL_LINES, 0, rLines);

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);
	vbufAsterism->unbind();

	glUseProgram(0);
}

 

This topic is closed to new replies.

Advertisement