Jump to content
  • Advertisement
Sign in to follow this  
Matija Martinec

OpenGL [SOLVED] OpenGL Texture working in a weird way

Recommended Posts

I've been dabbling in OpenGL for a past few days, and I've made a simple renderer which can display textures. Then after some time I realized that that will be too slow for a full game so i started researching Batching. I have successfully rendered a triangle/rect and managed to get it colored (whilst batching), but the texture have stumped me for a day.  For my texture loading reference I used this OpenGL tutorial. This is the picture I'm trying to render:

 sample.png.38f1508a6de4a804544cb4238434af05.png

When I start my project, this is what happens:

image.png.895724216125585e7ae0676b250f2714.png

I have tried to change the RGB to RGBA settings and so and nothing seemed to work. Also when i remove the

glBindTexture()

, the result is the same.

Here is my code:

Main.cpp

There is some initialization, but I doubt that'll be necessary.

VertexData one;
one.vertex	= glm::vec2(-0.5f, 0.5f);
one.color	= glm::vec3(1.0f, 0.0f, 0.0f);
one.texcoord = glm::vec2(0.0f, 0.0f);
VertexData two;
two.vertex	= glm::vec2(0.5f, 0.5f);
two.color	= glm::vec3(0.0f, 1.0f, 0.0f);
one.texcoord = glm::vec2(1.0f, 0.0f);
VertexData three;
three.vertex = glm::vec2(0.5f, -0.5f);
three.color	= glm::vec3(0.0f, 0.0f, 1.0f);
one.texcoord = glm::vec2(1.0f, 1.0f);
VertexData four;
four.vertex	= glm::vec2(-0.5f, -0.5f);
four.color	= glm::vec3(1.0f, 1.0f, 1.0f);
one.texcoord = glm::vec2(0.0f, 1.0f);


Shader shader(vertexSource, fragmentSource);

Batch renderer(shader);

while (!glfwWindowShouldClose(game.getWindow())) {
    glfwPollEvents();
    if (glfwGetKey(game.getWindow(), GLFW_KEY_ESCAPE) == GLFW_PRESS)
    glfwSetWindowShouldClose(game.getWindow(), GL_TRUE);

    renderer.Begin();

    renderer.Submit(&one);
    renderer.Submit(&two);
    renderer.Submit(&three);

    renderer.Submit(&three);
    renderer.Submit(&four);
    renderer.Submit(&one);

    renderer.End();

	glfwSwapBuffers(game.getWindow());
}

Batch.h

#pragma once
#include <GL\glew.h>
#include <iostream>
#include <SOIL2\SOIL2.h>

#include "Renderer.h"
#include "Shader.h"
#include "VertexArray.h"
#include "VertexBuffer.h"
#include "VertexBufferLayout.h"

#define RENDERER_MAX_VERTICES 10
#define WINWIDTH 800
#define WINHEIGHT 600

struct VertexData
{
	glm::vec2 vertex;
	glm::vec3 color;
	glm::vec2 texcoord;
};

class Batch
{
private:
	Renderer	 m_Renderer;
	unsigned int shaderProgram;
	unsigned int _vbo;
	unsigned int _vao;
	VertexData	*_buffer;
	unsigned int _vertexCount;
	bool		 m_Drawing;
public:
	Batch(Shader &shader)
		:_vertexCount(0), shaderProgram(shader.getProgram())
	{
		glGenBuffers(1, &_vbo);
		glGenVertexArrays(1, &_vao);

		glBindVertexArray(_vao);
		glBindBuffer(GL_ARRAY_BUFFER, _vbo);

		glBufferData(GL_ARRAY_BUFFER, RENDERER_MAX_VERTICES * sizeof(VertexData), NULL, GL_DYNAMIC_DRAW);

		// Specify the layout of the vertex data
		GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
		glEnableVertexAttribArray(posAttrib);
		glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(GLfloat), 0);

		GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
		glEnableVertexAttribArray(colAttrib);
		glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));

		GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
		glEnableVertexAttribArray(texAttrib);
		glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(GLfloat), (void*)(5 * sizeof(GLfloat)));


		// Load texture
		GLuint tex;
		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_2D, tex);

		int width, height;
		unsigned char* image = SOIL_load_image("sample.png", &width, &height, 0, SOIL_LOAD_RGB);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
		SOIL_free_image_data(image);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindVertexArray(0);
	}

	~Batch()
	{
	}

	void Begin()
	{
		glBindBuffer(GL_ARRAY_BUFFER, _vbo);
		_buffer = (VertexData*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
	}

	void Submit(VertexData* data)
	{
		*_buffer = *data;
		_buffer++;
		_vertexCount++;
	}

	void End()
	{
		glUnmapBuffer(GL_ARRAY_BUFFER);
		glBindBuffer(GL_ARRAY_BUFFER, 0);

		glClear(GL_COLOR_BUFFER_BIT);
		glBindVertexArray(_vao);
		glUseProgram(shaderProgram);
		glDrawArrays(GL_TRIANGLES, 0, _vertexCount);
		glBindVertexArray(0);

		_vertexCount = 0;
	}
};

Vertex and Fragment shaders

// Shader sources
const GLchar* vertexSource = R"glsl(
    #version 150 core
    in vec2 position;
    in vec3 color;
    in vec2 texcoord;
    out vec3 Color;
    out vec2 Texcoord;
    void main()
    {
        Color = color;
        Texcoord = texcoord;
        gl_Position = vec4(position, 0.0, 1.0);
    }
)glsl";
  
const GLchar* fragmentSource = R"glsl(
    #version 150 core
    in vec3 Color;
    in vec2 Texcoord;
    out vec4 outColor;
    uniform sampler2D tex;
    void main()
    {
        outColor = texture(tex, Texcoord) * vec4(Color, 1.0);
    }
)glsl";

I thank everyone in advance who tries to help :-), also im open to some optimization or better technique suggestions.

Edited by Matija Martinec

Share this post


Link to post
Share on other sites
Advertisement

You're only 4 vertices, two triangles should have 6.

Try using GL_QUADS (wich I think is deprecated on newer versions of opengl) or GL_TRIANGLE_STRIP, or specify elements using an GL_ELEMENT_ARRAY_BUFFER and draw using glDrawElements

Edited by qbicpp

Share this post


Link to post
Share on other sites

If you look closer, im actually asigning the 6 vertices, and they are properly rendered, as you can see by the submit in the main function. and gl draw elements would be kinda stupid, because this is batch rendering, and let's say i want to render 10000+ sprites, that means at least 60000 elements (too much).

But thank you for your reply, but I't doesn't work I already tried it.

Share this post


Link to post
Share on other sites

You're assigning texture coordinates to the first vertex 4 times and not setting the others at all?

Share this post


Link to post
Share on other sites

OMG HAhahahha,

1 minute ago, Sponji said:

You're assigning texture coordinates to the first vertex 4 times and not setting the others at all?

Thank you sponji..... I feel very stupid right now....

Share this post


Link to post
Share on other sites

Side note, your texture parameters must be specified before creating the actual texture with any glTexImage* functions.

Share this post


Link to post
Share on other sites

Thanks for the tip, but I don't think it matters, because everything is still working. Could you please elaborate why or give me some links to why is it so? Thank you :-)

Share this post


Link to post
Share on other sites

Don't have any links to share right now, but I've experience cases ( I want to say on AMD HW ) in the past where the texture parameters would not reflect unless specified before the call to create the texture store. That is not to say the texture would not display as the default params  would be enough. A quick test would be to change the filtering/wrap mode to see. However, if all is working well for you then now worries then.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!