Rendering fonts with Freetype and OpenGL - opengl

I have problem freetype and OpenGL. I need just draw all loaded symbols on single texture. Here's:
FT_Init_FreeType(&lib);
FT_New_Face(lib, "C:\\verdana.ttf", 0, &face);
FT_Set_Pixel_Sizes(face, 0, size);
auto ww = 256 * size;
auto hh = size;
std::vector<unsigned char> buffer(ww * hh, 0);
int off = 0;
for (int c = 0; c < 256; c++)
{
FT_UInt GlyphIndex;
GlyphIndex = FT_Get_Char_Index(face, c);
FT_Load_Char(face, GlyphIndex, FT_LOAD_RENDER);
FT_Bitmap bmp = face->glyph->bitmap;
int advance = (face->glyph->advance.x >> 6);
int bW = bmp.width;
int bH = bmp.rows;
for (int h = 0; h < bH; ++h) {
for (int w = 0; w < bW; ++w) {
buffer[h * bW + off + w] = bmp.buffer[w + bW * h];
}
}
off += advance;
}
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, ww, hh, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &buffer[0]);
I tried many ways to do this. But all I get is absolutely black texture...
What's wrong with my code?

I think the problem is that some values between 0-255 is not visible or drawable character and that's why you get nothing.
you should check for GlyphIndex:
GlyphIndex = FT_Get_Char_Index(face, c);
if (!GlyphIndex) continue;
then you can expect freetype to draw the rest of characters for you.

hallelujah, I got solution!
This should look like this:
for (int c = 0; c < 256; c++)
{
FT_UInt GlyphIndex;
GlyphIndex = FT_Get_Char_Index(face, c);
FT_Load_Char(face, GlyphIndex, FT_LOAD_RENDER);
FT_Bitmap bmp = face->glyph->bitmap;
int advance = (face->glyph->advance.x >> 6);
int bW = bmp.width;
int bH = bmp.rows;
for (int h = 0; h < bH; ++h) {
for (int w = 0; w < bW; ++w) {
buffer[h * ww + off + w] = bmp.buffer[w + bW * h];
}
}
off += advance;
}
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, ww, hh, 0, GL_RED, GL_UNSIGNED_BYTE, &buffer[0]);

Related

Multiple cube map textures behaving strangely when amount of textures increases [duplicate]

This question already has answers here:
In a fragment shader, why can't I use a flat input integer to index a uniform array of sampler2D?
(1 answer)
Why are glsl variables not working as expected?
(2 answers)
Why are Uniform variables not working in GLSL?
(1 answer)
Closed 2 years ago.
So I've managed to successfully implement batching into my engine, but have come across some weird behavior with the array of samplerCubes in my fragment shader. The batch renderer works fine with 2 texture units - I can successfully draw cubes with the right textures if I only bind 2 textures, but as soon as I add a 3rd to the mTextures vector, and use glUniform1i for that index in the samplerCube array, the wrong texture is displayed, even though the texture id (TexID) is correct (I checked this in the fragment shader).
The issue appears to be with my understanding of OpenGL as for some reason, the texture what should be displayed by textureCubes[2] (fragment shader uniform) is displayed by textureCubes[1], and textureCubes[2] displays the same texture as textureCubes[0]. What should be displayed by textureCubes[1] just doesn't exist with the 3rd texture bound.
Here's my code:
Main.cpp
#include "Window.h"
#include "Block.h"
#include "BatchRenderer.h"
#include "Shader.h"
#include "Camera.h"
void Submit(gfx::BatchRenderer* renderer, float height) //temporary to test batching
{
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
gfx::Block* block = new gfx::Block(j % 2 == 0 ? (i % 2 == 0 ? gfx::BlockType::DIRT : gfx::BlockType::GRASS) : gfx::BlockType::COBBLE, math::Vec3f(i * 5.0, height, j * 5.0));
renderer->Submit(block);
}
}
}
int main()
{
gfx::Window* window = new gfx::Window("MineClone", 800, 800);
gfx::Shader* shader = new gfx::Shader();
shader->FromFile(GL_VERTEX_SHADER, "Resources/ModelTest.vert");
shader->FromFile(GL_FRAGMENT_SHADER, "Resources/ModelTest.frag");
shader->RefreshProgram();
math::Mat4f projection = math::Mat4f::Perspective(70.0, window->GetWidth() / window->GetHeight(), 0.1, 1000.0);
gfx::Camera* camera = new gfx::Camera(projection, 0.05, 0.0015);
gfx::BatchRenderer* renderer = new gfx::BatchRenderer();
gfx::TextureCube* grass = new gfx::TextureCube("Resources/top.png", "Resources/dirt.png", "Resources/sides.png");
renderer->Submit(grass);
gfx::TextureCube* dirt = new gfx::TextureCube("Resources/dirt.png");
renderer->Submit(dirt);
gfx::TextureCube* cobble = new gfx::TextureCube("Resources/cobble.png");
renderer->Submit(cobble);
Submit(renderer, 0.0);
Submit(renderer, 5.0);
Submit(renderer, 10.0);
Submit(renderer, 15.0);
Submit(renderer, 20.0);
Submit(renderer, 25.0);
Submit(renderer, 30.0);
Submit(renderer, 35.0);
while (!window->IsClosed())
{
window->Update();
if (window->GetInputHandler()->IsKeyDown(VK_ESCAPE))
window->SwitchMouseState();
if (window->IsSynced())
camera->Update(window->GetInputHandler());
shader->Bind();
math::Mat4f projection = camera->GetProjection();
shader->SetUniform("projection", projection);
math::Mat4f view = camera->GetView();
shader->SetUniform("view", view);
shader->SetUniform("cubeTextures[0]", 0);
shader->SetUniform("cubeTextures[1]", 1);
shader->SetUniform("cubeTextures[2]", 2);
renderer->Render();
shader->Unbind();
}
return 0;
}
BatchRenderer.cpp
#include "BatchRenderer.h"
namespace gfx
{
BatchRenderer::BatchRenderer()
: mMesh(NULL)
{
}
BatchRenderer::~BatchRenderer()
{
mBlocks.clear();
mTextures.clear();
delete mMesh;
}
void BatchRenderer::Submit(Block* block)
{
MeshData data = block->GetMesh();
mMeshData.vertices.insert(mMeshData.vertices.end(),
data.vertices.begin(),
data.vertices.end());
for (int i = 0; i < 36; i++)
{
data.indices[i] += mBlocks.size() * 8;
}
mMeshData.indices.insert(mMeshData.indices.end(),
data.indices.begin(),
data.indices.end());
mMesh = Mesh::Make(mMeshData);
mBlocks.push_back(block);
}
void BatchRenderer::Submit(TextureCube* texture)
{
mTextures.push_back(texture);
}
void BatchRenderer::Render()
{
for (int i = 0; i < mTextures.size(); i++)
{
mTextures[i]->Bind(i);
}
mMesh->Render();
for (int i = 0; i < mTextures.size(); i++)
{
mTextures[i]->Unbind(i);
}
}
}
TextureCube.cpp
#include "TextureCube.h"
namespace gfx
{
TextureCube::TextureCube(std::string paths[6])
: Texture(TextureEnum::TEXTURE_CUBE)
{
glGenTextures(1, &mHandle);
glBindTexture(GL_TEXTURE_CUBE_MAP, mHandle);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
for (int i = 0; i < 6; i++)
{
std::vector<byte> pixels;
lodepng::decode(pixels, mWidth, mHeight, paths[i].c_str());
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
TextureCube::TextureCube(std::string path)
: Texture(TextureEnum::TEXTURE_CUBE)
{
glGenTextures(1, &mHandle);
glBindTexture(GL_TEXTURE_CUBE_MAP, mHandle);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
std::vector<byte> pixels;
lodepng::decode(pixels, mWidth, mHeight, path.c_str());
for (int i = 0; i < 6; i++)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
TextureCube::TextureCube(std::string top, std::string bottom, std::string sides)
: Texture(TextureEnum::TEXTURE_CUBE)
{
glGenTextures(1, &mHandle);
glBindTexture(GL_TEXTURE_CUBE_MAP, mHandle);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
std::vector<byte> topPixels;
lodepng::decode(topPixels, mWidth, mHeight, top.c_str());
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, topPixels.data());
std::vector<byte> bottomPixels;
lodepng::decode(bottomPixels, mWidth, mHeight, bottom.c_str());
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, bottomPixels.data());
std::vector<byte> sidesPixels;
lodepng::decode(sidesPixels, mWidth, mHeight, sides.c_str());
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, sidesPixels.data());
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, sidesPixels.data());
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, sidesPixels.data());
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, sidesPixels.data());
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
TextureCube::~TextureCube()
{
glDeleteTextures(1, &mHandle);
mHandle = NULL;
}
void TextureCube::Bind(uint32_t slot)
{
glBindTextureUnit(slot, mHandle);
}
void TextureCube::Unbind(uint32_t slot)
{
glBindTextureUnit(slot, 0);
}
}
ModelTest.vert
#version 450 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 offset;
layout (location = 3) in float textureID;
uniform mat4 projection;
uniform mat4 view;
out vec3 TexPos;
out flat float TexID;
void main()
{
gl_Position = projection * view * vec4(position, 1.0);
TexPos = position - offset;
TexID = textureID;
}
ModelTest.frag
#version 450 core
out vec4 FragColour;
in vec3 TexPos;
in flat float TexID;
uniform samplerCube cubeTextures[3];
void main()
{
vec3 norm = normalize(TexPos);
int id = int(TexID);
FragColour = texture(cubeTextures[id], norm);
}
For anyone looking for a solution, it took me a while but I found it (I'm relatively new to OpenGL). The issue was I was setting the texture sampler slots individually using glUniform1i. To fix this, as cubeTextures is an array of samplerCubes, I created a struct for sampler data containing an int array and a length, and set the texture sampler slots using glUniform1iv.

How to create bitmap font texture in OpenGL?

So I was trying to learn OpenGL from learnopengl.com and I'm currently on the topic of text rendering and I thought about combining scalable font textures in my program to one big texture, but for some reason, I get an exception bc of glCopyImageSubData(...).
First I try to measure how big the texture should be and then copy textures I already created to one big texture, and I was playing with this function for quite a while now but I can't find a solution.
Here is the original code with texture used for each face.
I tried to create fbo and attach a texture to it, but after research, I found this function that was far more clear to me so I decided to use it instead.
So I added xoffset to Character structure:
struct Character {
GLuint textureID;
glm::ivec2 size;
glm::ivec2 bearing;
GLuint advance;
GLuint xoffset;
};
I add this offset to each face in the first for loop:
Character character = {
texture,
glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
face->glyph->advance.x,
font_texture_width
};
font_texture_width += character.size.x;
characters.insert(std::pair<GLchar, Character>(c, character));
And then I try to paste each face texture to fontTexture:
glGenTextures(1, &fontTexture);
glBindTexture(GL_TEXTURE_2D, fontTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED,
font_texture_width, 100, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
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);
std::cout << glGetError();
for (GLubyte c = 0; c < 128; ++c)
glCopyImageSubData( characters[c].textureID, GL_TEXTURE_2D, 0, 0, 0, 0,
fontTexture, GL_TEXTURE_2D, 0, characters[c].xoffset, 0, 0,
characters[c].size.x, characters[c].size.y, 0);
Here is modyfied renderText function:
void renderText(Shader &s, std::string text, GLfloat x, GLfloat y, GLfloat scale, glm::vec3 color)
{
s.use();
s.setVec3("textColor", color);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(VAO);
std::string::const_iterator c;
glBindTexture(GL_TEXTURE_2D, fontTexture);
for (c = text.begin(); c != text.end(); ++c)
{
Character ch = characters[*c];
GLfloat xpos = x + ch.bearing.x * scale;
GLfloat ypos = y - (ch.size.y - ch.bearing.y) * scale;
GLfloat w = ch.size.x * scale;
GLfloat h = ch.size.y * scale;
GLfloat vertices[6][4] = {
{ xpos + characters[*c].xoffset, ypos + h, 0.0, 0.0 },
{ xpos + characters[*c].xoffset, ypos, 0.0, 1.0 },
{ xpos + w + characters[*c].xoffset, ypos, 1.0, 1.0 },
{ xpos + characters[*c].xoffset, ypos + h, 0.0, 0.0 },
{ xpos + w + characters[*c].xoffset, ypos, 1.0, 1.0 },
{ xpos + w + characters[*c].xoffset, ypos + h, 1.0, 0.0 }
};
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
x += (ch.advance >> 6) * scale;
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
Exception is being thrown where I call glCopyImageSubData.
Here is my whole program: https://pastebin.com/vAeeX3Xh
EDIT:
Now I figured out that it would be better to use glTexSubImage2D instead, so this is how it looks like (instead of this block of code with glCopyImageSubData)
glGenTextures(1, &fontTexture);
glBindTexture(GL_TEXTURE_2D, fontTexture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RED,
face->glyph->bitmap.width * 250,
face->glyph->bitmap.rows * 250,
0,
GL_RED,
GL_UNSIGNED_BYTE,
NULL
);
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);
for (GLubyte c = 0; c < 128; ++c)
{
if (FT_Load_Char(face, c, FT_LOAD_RENDER))
{
std::cout << "ERROR::FREETYPE: Failed to load Glyph" << std::endl;
continue;
}
glTexSubImage2D(GL_TEXTURE_2D, 0, characters[c].xoffset, 0, characters[c].size.x, characters[c].size.y, GL_RED, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer);
}
Now when I render this texture it looks like this:
https://imgur.com/a/A0gDy6T

Applying textures to only one object in opengl

I'm programming in c++ in opengl.
I'm supposed to make a texture and I made the following code:
void makeCheckImage(void){
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
}
void init(void){
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
checkImage);
}
my problem is that this beautiful piece of code (or maybe not) is applying textures to the whole scene! And I just want it to apply to one object...
Can anybody help me?
glEnable(GL_TEXTURE_2D);
//Draw object
glDisable(GL_TEXTURE_2D);

opengl texturing

I am trying to create a normal map in opengl that I can load into the shader and change dynamically, though currently i am stuck at how to create the texture.
I currently have this:
glActiveTexture(GL_TEXTURE7);
glGenTextures(1, &normals);
glBindTexture(GL_TEXTURE_2D, normals);
texels = new Vector3f*[256];
for(int i = 0; i < 256; ++i){
texels[i] = new Vector3f[256];
}
this->setup_normals();
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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_FLOAT, texels);
...
void setup_normals(){
for(int i = 0; i < 256; ++i){
for(int j = 0; j < 256; ++j){
texels[i][j][0] = 0.0f;
texels[i][j][1] = 1.0f;
texels[i][j][2] = 0.0f;
}
}
}
where Vector3f is: typedef float Vector3f[3];
and texels is: Vector3f** texels;
When I draw this texture to a screenquad using an orthogonal matrix( which works for textures loaded in) I get .
I am unsure why it does not appear fully green and also what is causing the black streaks to appear within it. Any help appreciated.
Your array needs to be contiguous since glTexImage2D() doesn't take any sort of stride or row mapping parameters:
texels = new Vector3f[256*256];

Special parameters for texture binding?

Do I have to set up my gl context in a certain way to bind textures. I'm following a tutorial. I start by doing:
#define checkImageWidth 64
#define checkImageHeight 64
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLuint texName;
void makeCheckImage(void)
{
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
}
void initt(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
checkImage);
engineGL.current.tex = texName;
}
In my rendering I do:
PolygonTesselator.Begin_Contour();
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, current.tex);
if(layer[currentlayer].Shapes[i].Contour[c].DrawingPoints.size() > 0)
{
glColor4f(
layer[currentlayer].Shapes[i].Color.r,
layer[currentlayer].Shapes[i].Color.g,
layer[currentlayer].Shapes[i].Color.b,
layer[currentlayer].Shapes[i].Color.a);
}
for(unsigned int j = 0; j < layer[currentlayer].Shapes[i].Contour[c].DrawingPoints.size(); ++j)
{
gluTessVertex(PolygonTesselator.tobj,&layer[currentlayer].Shapes[i].Contour[c].DrawingPoints[j][0],
&layer[currentlayer].Shapes[i].Contour[c].DrawingPoints[j][0]);
}
PolygonTesselator.End_Contour();
}
glDisable(GL_TEXTURE_2D);
}
However it still renders the color and not the texture at all. I'd atleast expect to see black or something but its as if the bind fails. Am I missing something?
Thanks
It looks like from that code that you don't set any UVs.
Edit: Does it make any difference using GL_MODULATE instead of GL_DECAL? (Am taking guesses here because I suspect the problem lies in code you haven't provided, or in gluTessVertex itself ...