Rendering quad sized by screen pixels ( example rendering quad 10x15 pixels )

Started by
3 comments, last by Gyiove Sparkle 9 years, 4 months ago

Hello Everyone!

I have code here:


namespace grpc
{
	classwindow *window;
	fw *render;
	glm::mat4 modelMatrix;
	glm::mat4 viewMatrix;
	glm::mat4 projectionMatrix;
	glm::mat4 modelViewMatrix;
	glm::mat4 modelViewProjectionMatrix;
	glm::mat3 normalMatrix;
	shader simple;

}

struct vertexData{
	float position[3];
	float normal[3];
	float tangent[3];
	float color[3];
	float uv[2];
};

struct vertexID{
	unsigned int id[3];
};
unsigned int vbo, vbo2;
void graphic_frame()
{
	if( grpc::window->winactive ) 
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glClearColor(0,0,0,0);
		glEnable(GL_DEPTH_TEST);
		
		double size[2];
		size[0] = (double)grpc::window->size[0];
		size[1] = (double)grpc::window->size[1];
		grpc::projectionMatrix = glm::perspective(50.0, size[0]/size[1], 1.0, 9999.0);
		grpc::modelMatrix = glm::mat4(1.0);
		grpc::viewMatrix = glm::mat4(1.0);
		
		grpc::viewMatrix *= glm::rotate(0.0f, glm::vec3(1.0, 0.0, 0.0));
		grpc::viewMatrix *= glm::rotate(0.0f, glm::vec3(0.0, 1.0, 0.0));
		grpc::viewMatrix *= glm::rotate(0.0f, glm::vec3(0.0, 0.0, 1.0));
		grpc::viewMatrix *= glm::translate(glm::vec3(0.0, 0.0, -90.0));
		grpc::modelMatrix *= glm::scale(glm::vec3(1.0,1.0,1.0));

		grpc::modelViewMatrix=grpc::viewMatrix*grpc::modelMatrix;
		grpc::modelViewProjectionMatrix=grpc::projectionMatrix*grpc::viewMatrix*grpc::modelMatrix;
		grpc::normalMatrix=glm::mat3(grpc::modelViewProjectionMatrix);

		grpc::simple.use();

		glUniformMatrix4fv(glGetUniformLocation(grpc::simple.index,"modelMatrix"),1,GL_FALSE, &grpc::modelMatrix[0][0]);
		glUniformMatrix4fv(glGetUniformLocation(grpc::simple.index,"viewMatrix"),1,GL_FALSE, &grpc::viewMatrix[0][0]);
		glUniformMatrix4fv(glGetUniformLocation(grpc::simple.index,"projectionMatrix"),1,GL_FALSE, &grpc::projectionMatrix[0][0]);
		glUniformMatrix4fv(glGetUniformLocation(grpc::simple.index,"modelViewMatrix"),1,GL_FALSE, &grpc::modelViewMatrix[0][0]);
		glUniformMatrix4fv(glGetUniformLocation(grpc::simple.index,"modelViewProjectionMatrix"),1,GL_FALSE, &grpc::modelViewProjectionMatrix[0][0]);
		glUniformMatrix3fv(glGetUniformLocation(grpc::simple.index,"normalMatrix"),1,GL_FALSE, &grpc::normalMatrix[0][0]);

		int vertex=glGetAttribLocation(grpc::simple.index,"vertex"); //0
		int normal=glGetAttribLocation(grpc::simple.index,"normal"); //1
		int tangent=glGetAttribLocation(grpc::simple.index,"tangent"); //2
		int color=glGetAttribLocation(grpc::simple.index,"color"); //3
		int UV=glGetAttribLocation(grpc::simple.index,"UV"); //4
	
		glBindBuffer(GL_ARRAY_BUFFER,vbo);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo2);
	
		glEnableVertexAttribArray(vertex);
		glVertexAttribPointer(vertex,3,GL_FLOAT,GL_FALSE,sizeof(vertexData),0);
	
		glEnableVertexAttribArray(normal);
		glVertexAttribPointer(normal,3,GL_FLOAT,GL_FALSE,sizeof(vertexData),(void*)(3*sizeof(float)));
	
		glEnableVertexAttribArray(tangent);
		glVertexAttribPointer(tangent,3,GL_FLOAT,GL_FALSE,sizeof(vertexData),(void*)(6*sizeof(float)));
	
		glEnableVertexAttribArray(color);
		glVertexAttribPointer(color,3,GL_FLOAT,GL_FALSE,sizeof(vertexData),(void*)(9*sizeof(float)));
	
		glEnableVertexAttribArray(UV);
		glVertexAttribPointer(UV,2,GL_FLOAT,GL_FALSE,sizeof(vertexData),(void*)(12*sizeof(float)));
	
		glDrawElements(GL_TRIANGLES, 6,GL_UNSIGNED_INT,0);
	
		glDisableVertexAttribArray(vertex);
		glDisableVertexAttribArray(normal);
		glDisableVertexAttribArray(tangent);
		glDisableVertexAttribArray(color);
		glDisableVertexAttribArray(UV);
		glBindBuffer(GL_ARRAY_BUFFER,0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

		call_forward(grpc::render, tfunc::void_void); // that is doing nothing right now
		// after this func ends then SwapBuffers(win->render_device) will be called
	}
}

void graphic_end()
{
	grpc::simple.destroy();

}

void img_init();
void graphic_init()
{
	register_forward( "frame", func_add(graphic_frame) );
	glClearColor(0,0,0,0);
	glEnable(GL_DEPTH_TEST);

	grpc::modelMatrix = glm::mat4(1.0);
	grpc::viewMatrix = glm::mat4(1.0);
	grpc::projectionMatrix = glm::mat4(1.0);
	grpc::modelViewMatrix = glm::mat4(1.0);
	grpc::modelViewProjectionMatrix = glm::mat4(1.0);
	grpc::normalMatrix = glm::mat3(1.0);

	grpc::window = get_classwindow();
	create_forward("render", "void()");
	grpc::render = get_forward("render");
	grpc::simple.shader_load( "test", "hv;>y64:_72h6/8h4 3j<hxd-*y83'Simple,Test.SpShader' !*" );
	glBindFramebuffer(GL_FRAMEBUFFER,0);
	img_init();

	vertexData quad[4];

	quad[3].position[0] = -1.0f;
	quad[3].position[1] =  1.0f;
	quad[3].position[2] =  0.0f;
	quad[3].normal[0] = -1.0f;
	quad[3].normal[1] = -0.0f;
	quad[3].normal[2] = 0.0f;
	quad[3].uv[0] = 0.0f;
	quad[3].uv[1] = 1.0f;

	quad[2].position[0] =  1.0f;
	quad[2].position[1] =  1.0f;
	quad[2].position[2] =  0.0f;
	quad[2].normal[0] = -1.0f;
	quad[2].normal[1] = -0.0f;
	quad[2].normal[2] = 0.0f;
	quad[2].uv[0] = 1.0f;
	quad[2].uv[1] = 1.0f;

	quad[1].position[0] =  1.0f;
	quad[1].position[1] = -1.0f;
	quad[1].position[2] =  0.0f;
	quad[1].normal[0] = 1.0f;
	quad[1].normal[1] = 0.0f;
	quad[1].normal[2] = 0.0f;
	quad[1].uv[0] = 1.0f;
	quad[1].uv[1] = 0.0f;

	quad[0].position[0] = -1.0f;
	quad[0].position[1] = -1.0f;
	quad[0].position[2] =  0.0f;
	quad[0].normal[0] = -1.0f;
	quad[0].normal[1] = -0.0f;
	quad[0].normal[2] = 0.0f;
	quad[0].uv[0] = 0.0f;
	quad[0].uv[1] = 1.0f;

	glGenBuffers(1,&vbo);
	glBindBuffer(GL_ARRAY_BUFFER,vbo);
	glBufferData(GL_ARRAY_BUFFER,4*sizeof(vertexData), &quad,GL_STATIC_DRAW);
	vertexID id[2];
	id[0].id[0] = 0;
	id[0].id[1] = 1;
	id[0].id[2] = 2;
	id[1].id[0] = 0;
	id[1].id[1] = 2;
	id[1].id[2] = 3;
	
	glGenBuffers(1,&vbo2);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo2);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER,6*sizeof(unsigned int),&id,GL_STATIC_DRAW);
	
	glBindBuffer(GL_ARRAY_BUFFER,0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
}

Really hard to explain it but i want to make a gui system inside the opengl and i wish that everything would be pixel accurate.

If i wish that my quad would appear in screen for example 100 pixels tall and 50 pixels wide then so it would be it.

I guess my idea is just to fill screen with textures so i could make gui like thing...
Im really sorry about bad explanation, i hope you'll understand me.

Thanks!

Advertisement

Basically all you need to do is draw your UI elements directly to the back-buffer and sending the exact coordinates you want, rather than transforming them with a matrix. That's more or less how you do anything 'pixel-perfect' in any rendering API. Make sure you set an appropriate depth value and depth-test value. That leaves you at the mercy of the user's resolution (unless you prevent them from choosing) though, so you'd then need to deal with that -- many games simply allow the UI elements to grow or shrink as the resolution decreases or increases, this may be fine for your game. You can combine this approach with doing 1/2 or 2x pixel scaling when a certain threshhold is crossed so that UI elements never get absurdly large or small -- Then, you might also want to provide all UI bitmaps at 1/2, 1x, and 2x resolution that you can use when the those thresholds are met. It might not be necessary, depending on the range of resolutions you support or whether your graphical style is chunky and retro-looking anyways, but it'll help the UI remain sharp if that's your intention.

You might also want to implement a UI system where each window pane and its controls are rendered first to their own surface before the whole thing being drawn to the backbuffer. That will allow you to re-use the window with all its controls intact for many frames, as an optimization, but its some extra work to manage the extra texture resources up-front.

throw table_exception("(? ???)? ? ???");

Basically all you need to do is draw your UI elements directly to the back-buffer and sending the exact coordinates you want, rather than transforming them with a matrix.


I'm pretty sure you want to transform them by a matrix unless you're really keen on figuring out what your pixel-perfect coordinates look like in NDC space by hand. smile.png

You'll want an orthographic projection matrix sized to the surface's pixel dimensions (window width and height).

Sean Middleditch – Game Systems Engineer – Join my team!

Doesn't GL have equivalent of untransformed vertices that are just passed on through nowadays? Maybe that was a fixed-function thing.

throw table_exception("(? ???)? ? ???");

Basically all you need to do is draw your UI elements directly to the back-buffer and sending the exact coordinates you want, rather than transforming them with a matrix.


I'm pretty sure you want to transform them by a matrix unless you're really keen on figuring out what your pixel-perfect coordinates look like in NDC space by hand. smile.png

You'll want an orthographic projection matrix sized to the surface's pixel dimensions (window width and height).

Thanks, added this:


grpc::projectionMatrix = glm::ortho(0.0f, (float)size[0],(float)size[1], 0.0f, 0.1f, 100.0f);

And now its working like i wish.

This topic is closed to new replies.

Advertisement