PDA

View Full Version : Problems with textureing



3DPrgmer
08-27-2016, 06:06 AM
Hi,

i just started to learn OpenGL. I used a tutorial for the beginning and worte starting from it my own program (not allowed to post lins. When it is done it'll display a msh file including the textures, bumpmaps, normalmaps, specmaps,... and display a lot of information.

But my texture projection does not what it should do.
I have a hardcoded cube with simple texture projection. But for some reason the RGB colours are swap R=B and B=R. But as you can see in the hex editor and at the debug values of the vector, the values are read in correctly RGB (i used that small 10x10 texture). The result is shown at the upper left corner. What the hell happend??

I tried a bigger texture 256x256 (attention now the upper colour from the source is red not blue!!) and the texture is shown a bit better. Only the Colors R and B are swapped and the first row looks wired. Any ideas about that??

2285

And here is my code: main.cpp


#ifndef _DEBUG
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
#endif // DEBUG
#include <iostream>
#include <Windows.h>
#include <gl\glut.h>
#include "typedefs.h"
#include "tga.h"
#include "texture.h"


void init(void)
{
glClearColor(0.3000, 0.4000, 1.0000, 0.0000); // This clear the background color to dark blue
glShadeModel(GL_SMOOTH); // Type of shading for the polygons
glViewport(0, 0, screen_width, screen_height); // Viewport transformation

// Projection transformation
glMatrixMode(GL_PROJECTION); // Specifies which matrix stack is the target for matrix operations
glLoadIdentity(); // We initialize the projection matrix as identity
gluPerspective(45.0f, (GLfloat)screen_width / (GLfloat)screen_height, 1.0f, 1000.0f); // We define the "viewing volume"

glEnable(GL_DEPTH_TEST); // We enable the depth test (also called z buffer)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled)

glEnable(GL_TEXTURE_2D);
cube.id_texture = 1; // LoadBitmap("texture1.bmp");

try
{
TextureTGA texture("3x3H.tga");
glBindTexture(GL_TEXTURE_2D, cube.id_texture);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image is repeated
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // The magnification function ("linear" produces better results)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //The minifying function

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // We don't combine the color with the original surface color, use only the texture map.

glTexImage2D(GL_TEXTURE_2D, 0, texture.hasAlpha() ? GL_RGBA : GL_RGB, texture.getWidth(), texture.getHeight(), 0, texture.hasAlpha() ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, texture.getData().data());
gluBuild2DMipmaps(GL_TEXTURE_2D, texture.hasAlpha() ? GL_RGBA : GL_RGB, texture.getWidth(), texture.getHeight(), texture.hasAlpha() ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, texture.getData().data());
}
catch (std::invalid_argument e)
{
MessageBox(NULL, e.what(), "MeshViewer 2.0 Error", MB_OK | MB_ICONERROR);
exit(0);
}


}

void resize(int width, int height)
{
screen_width = width; // We obtain the new screen width values and store it
screen_height = height; // Height value

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // We clear both the color and the depth buffer so to draw the next frame
glViewport(0, 0, screen_width, screen_height); // Viewport transformation

glMatrixMode(GL_PROJECTION); // Projection transformation
glLoadIdentity(); // We initialize the projection matrix as identity
gluPerspective(45.0f, (GLfloat)screen_width / (GLfloat)screen_height, 1.0f, 1000.0f);

glutPostRedisplay(); // This command redraw the scene (it calls the same routine of glutDisplayFunc)
}

void keyboard(unsigned char key, int x, int y)
{

switch (key)
{

case ' ':
rotation_x = 0;
rotation_y = 0;
rotation_z = 0;
translate = -50;
break;
case 't': case 'T':
if (filling == 0)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled)
filling = 1;
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Polygon rasterization mode (polygon outlined)
filling = 0;
}
break;
case 'r': case 'R':
glClearColor(1.0000, 0.0000, 0.0000, 0.0000);
break;
case 'g': case 'G':
glClearColor(0.0000, 1.0000, 0.0000, 0.0000);
break;
case 'b': case 'B':
glClearColor(0.0000, 0.0000, 1.0000, 0.0000);
break;
case '+':
translate++;
//glTranslatef(0.0, 0.0, translate);
break;
case '-':
translate--;
//glTranslatef(0.0, 0.0, translate);
break;
}
}

void keyboard_s(int key, int x, int y)
{

switch (key)
{
case GLUT_KEY_UP:
rotation_x++;
break;
case GLUT_KEY_DOWN:
rotation_x--;
break;
case GLUT_KEY_LEFT:
rotation_y++;
break;
case GLUT_KEY_RIGHT:
rotation_y--;
break;
}
}

void mouse(int button, int state, int x, int y)
{

std::cout << "mouse action: " << button << ", " << state << ", " << x << ", " << y << std::endl;

}

void display(void)
{
int l_index;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // This clear the background color to dark blue
glMatrixMode(GL_MODELVIEW); // Modeling transformation
glLoadIdentity(); // Initialize the model matrix as identity

glTranslatef(0.0, 0.0, translate); // We move the object 50 points forward (the model matrix is multiplied by the translation matrix)

if (rotation_x > 359) rotation_x = 0;
if (rotation_y > 359) rotation_y = 0;
if (rotation_z > 359) rotation_z = 0;

glRotatef(rotation_x, 1.0, 0.0, 0.0); // Rotations of the object (the model matrix is multiplied by the rotation matrices)
glRotatef(rotation_y, 0.0, 1.0, 0.0);
glRotatef(rotation_z, 0.0, 0.0, 1.0);

glBindTexture(GL_TEXTURE_2D, cube.id_texture);

glBegin(GL_TRIANGLES); // GlBegin and glEnd delimit the vertices that define a primitive (in our case triangles)
for (l_index = 0; l_index < 12; l_index++)
{
int knotA = cube.polygon[l_index].a;
int knotB = cube.polygon[l_index].b;
int knotC = cube.polygon[l_index].c;

// knot a from polygon l_index
glTexCoord2f(cube.mapcoord[knotA].u,
cube.mapcoord[knotA].v);
glVertex3f(cube.vertex[knotA].x,
cube.vertex[knotA].y,
cube.vertex[knotA].z);

// knot b from polygon l_index
glTexCoord2f(cube.mapcoord[knotB].u,
cube.mapcoord[knotB].v);
glVertex3f(cube.vertex[knotB].x,
cube.vertex[knotB].y,
cube.vertex[knotB].z);

//knot c from polygon l_index
glTexCoord2f(cube.mapcoord[knotC].u,
cube.mapcoord[knotC].v);
glVertex3f(cube.vertex[knotC].x,
cube.vertex[knotC].y,
cube.vertex[knotC].z);
}
glEnd();

glFlush(); // This force the execution of OpenGL commands
glutSwapBuffers(); // In double buffered mode we invert the positions of the visible buffer and the writing buffer
}

int main(int argc, char** argv)
{
// We use the GLUT utility to initialize the window, to handle the input and to interact with the windows system
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(screen_width, screen_height);
glutInitWindowPosition(0, 0);
glutCreateWindow("MeshViewer 2.0 pre-alpha");

glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(resize);
glutKeyboardFunc(keyboard);
glutSpecialFunc(keyboard_s);
glutMouseFunc(mouse);
init();
glutMainLoop();

return 0;
}


texture.cpp


#include "texture.h"
#include <iostream>
#include <fstream>
#include <Windows.h>

TextureTGA::TextureTGA(const char * filePath)
{
std::fstream fsPicture(filePath, std::ios::in | std::ios::binary);

if (!fsPicture.is_open())
throw std::invalid_argument(std::string("file not found: ") += filePath);

OutputDebugStringW(L"read in picture header");
std::uint8_t ui8x18Header[18] = { 0 };
fsPicture.read(reinterpret_cast<char*>(&ui8x18Header), sizeof(ui8x18Header));

ui32IDLength = ui8x18Header[0];
bColorTabel = ui8x18Header[1] == 1;
ui32PicType = ui8x18Header[2];
ui32PaletteBegin = ui8x18Header[4] * 0xFF + ui8x18Header[3];
ui32PaletteLength = ui8x18Header[6] * 0xFF + ui8x18Header[5];
ui32PaletteBpP = ui8x18Header[7];
ui32Width = ui8x18Header[13] * 0xFF + ui8x18Header[12];
ui32Height = ui8x18Header[15] * 0xFF + ui8x18Header[14];
ui32BpP = ui8x18Header[16];
ui32Attribut = ui8x18Header[17];

ui32Size = ui32Width * ui32Height * ui32BpP/8;
bCompressed = ui32PicType == 9 || ui32PicType == 10;
vui8Pixels.resize(ui32Size);

std::cout << "Header\n"
<< "ID länge: " << ui32IDLength << std::endl
<< "Farbtabelle: " << (int)bColorTabel << std::endl
<< "Bildtype: " << ui32PicType << std::endl
<< "Palletenbegin: " << ui32PaletteBegin << std::endl
<< "Palletenlängen: " << ui32PaletteLength << std::endl
<< "Bits pro Palleteneintrag: " << ui32PaletteBpP << std::endl
<< "Breite: " << ui32Width << std::endl
<< "Höhe: " << ui32Height << std::endl
<< "Bit pro Pixel: " << ui32BpP << std::endl
<< "Bild Attribute: " << ui32Attribut << std::endl;

fsPicture.seekg(ui32IDLength + ui32PaletteLength, std::ios_base::cur);


if (ui32PicType == 2) // not compressed
{
if (ui32BpP == 24) // 24 bit = no alpha
{
fsPicture.read(reinterpret_cast<char*>(vui8Pixels.data()), ui32Size);
}
else if (ui32BpP == 32) // 32 bit = alpha
{
fsPicture.read(reinterpret_cast<char*>(vui8Pixels.data()), ui32Size);
}
else // that shouldn't happen
{
fsPicture.close();
throw std::invalid_argument("Invaild File Format! Required 24 or 31 Bit Image.");
}


}
else if (ui32PicType == 10) // compressed
{
if (ui32BpP == 24) // 24 bit = no alpha
{

}
else if (ui32BpP == 32) // 32 bit = alpha
{

}
else // that shouldn't happen
{
fsPicture.close();
throw std::invalid_argument("Invaild File Format! Required 24 or 31 Bit Image.");
}
}
else // not practable Image type
{
fsPicture.close();
throw std::invalid_argument("Invaild File Format! Required 24 or 31 Bit Image.");
}

/*
//fix color mix
std::uint8_t temp;
std::uint32_t it = 0;
while (it + 2 < ui32Size)
{
temp = vui8Pixels[it];
vui8Pixels[it] = vui8Pixels[it + 2];
vui8Pixels[it + 2] = temp;
ui32BpP == 32 ? it += 2 : it += 3;
}*/

fsPicture.close();

}

TextureTGA::~TextureTGA()
{
}

std::vector<std::uint8_t> TextureTGA::getData() const
{
return vui8Pixels;
}

bool TextureTGA::hasAlpha() const
{
return ui32BpP == 32;
}

std::uint32_t TextureTGA::getWidth() const
{
return ui32Width;
}

std::uint32_t TextureTGA::getHeight() const
{
return ui32Height;
}

std::uint32_t TextureTGA::getSize() const
{
return ui32Size;
}


i wrote this simple work around for the correct colour, but i don't think it's a good idea to work with an workaround. The values in the vector are one pixel after the other rgb. So why does OpenGL display it as bgr even when i wrote that it is RGB format??

john_connor
08-27-2016, 06:59 AM
maybe your image loader has a bug regarding the color channels, i would first try to use a suitable library:
https://www.opengl.org/wiki/Image_Libraries#SOIL

GClements
08-27-2016, 09:35 AM
Have you tried a different texture? Specifically, one which doesn't have equal amounts of red, green and blue?

As it is, you can't tell if it's swapping the channels or the texture is upside-down (which is a fairly common problem; texture coordinates of (0,0) refer to the first pixel in the buffer, which is more often the top-left than the bottom-left).

3DPrgmer
08-27-2016, 11:40 AM
i tried different internet solutions, but they all did not work properly.

http://stackoverflow.com/questions/20595340/loading-a-tga-bmp-file-in-c-opengl just works with 24 bit tgas
http://stackoverflow.com/questions/7046270/loading-a-tga-file-and-using-it-with-opengl works with 24 and 32, but for 32 bit the rows are shifted and the colour were swapped, too.

So i decided to write my own one. I tested with an different picture first
2286

i just used this simple texture so i could check the values to fix that upper row. But as you can see on the first pictures, the values upper row is just fine. With the other readin functions it worked fine. So i have no idea what's wrong with mine.

Does anyone know why i'm not allowed to post links and why my uploaded pictures (jpeg) are always not valid picture files?? I always need to upload on imgur and then (because i'm not allowed to post links) upload from URL

GClements
08-27-2016, 02:37 PM
i just used this simple texture so i could check the values to fix that upper row. But as you can see on the first pictures, the values upper row is just fine. With the other readin functions it worked fine. So i have no idea what's wrong with mine.

If you're using GL_RGB and the texture width isn't a multiple of 4, you need to use glPixelStorei(GL_UNPACK_ALIGNMENT,1); the default alignment is 4, i.e. each row is assumed to be aligned to a multiple of 4 bytes.

Also, this looks odd:


ui32PaletteBegin = ui8x18Header[4] * 0xFF + ui8x18Header[3];
ui32PaletteLength = ui8x18Header[6] * 0xFF + ui8x18Header[5];
ui32PaletteBpP = ui8x18Header[7];
ui32Width = ui8x18Header[13] * 0xFF + ui8x18Header[12];
ui32Height = ui8x18Header[15] * 0xFF + ui8x18Header[14];
Normally you'd multiply by 0x100 (=256), not 0xFF (=255).



Does anyone know why i'm not allowed to post links and why my uploaded pictures (jpeg) are always not valid picture files?? I always need to upload on imgur and then (because i'm not allowed to post links) upload from URL
New accounts aren't allowed to use links, to discourage abuse by spammers.

3DPrgmer
08-28-2016, 03:36 AM
WOW!! That fixed some problems. My pictures actually was power of two. But because of a wrong conversion openGL always thought it was 255x255 instead of 256x256 I don't know why i didn't noticed that for the 10x10 picture.
Even the picture with alpha channel (32bit) is displayed correctly now.
Only problem is still that colour swap. Any ideas about that??

An other question, i read the documentation of the functions glTexImage2D and gluBuild2DMipmaps and i read something about compressed input. I still do not understand the arguments well. Can you explain them to me? Would it be possible to not uncompress the image data to use it with OpenGL with the correct parameters?


GLint level, what does the level of detail exact do?? Does this improve the picture quality?
GLint internalFormat, what is this exactly good for?
GLint border, "This value must be 0", why? What is it good for?
GLenum format, how to use these different values? Does this need to be the same as internalFormat?
GLenum type, what is this good for?

john_connor
08-28-2016, 11:19 AM
GLint level, what does the level of detail exact do?? Does this improve the picture quality?
GLint internalFormat, what is this exactly good for?
GLint border, "This value must be 0", why? What is it good for?
GLenum format, how to use these different values? Does this need to be the same as internalFormat?
GLenum type, what is this good for?


the difference between "internalformat" and "format":
"internalformat" describes how opengl stores the data internally, how many bytes / components (rgba)
"format" describes the image data you want to store in that texture object

the last 3 arguments (format, type, data) describes the memory layout of the image data you want to store in that texture object

"level" (level-of-detail):
a texture object can have (store) the same image data in different resolutions for performance reasons
https://www.opengl.org/wiki/Texture#Mip_maps
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/

3DPrgmer
08-29-2016, 07:21 AM
Alright thank you for your help. I read that newer tutorial and remembered that i was using "old" OpenGL. And that glut is old and ugly.

So i'd like to know what would you use?? i read the first two chapters of the tutorial and now i have a colored triangle. Wuhu my other old state was a cube that read in a texture and could be moved and rotated by mouse or keyboard.

So does it pays off to change the whole project to use the new OpenGL and glfw instead of glut??

john_connor
08-29-2016, 09:11 AM
I read that newer tutorial and remembered that i was using "old" OpenGL. And that glut is old and ugly.

So i'd like to know what would you use??

depends on what you need for your project
simple drawings (like 2D shapes) can be done using glut + "old" opengl API
if you want to be able to draw more complex models (like that (http://tf3dm.com/3d-model/uh-60-blackhawk-helicopter-93546.html)) you have to use "modern" openGL API
using the "modern" openGL API, you also have the control over what get processed on you GPU (using your own shaders)

the windowing-system hasnt anything to do with opengl, the main difference between glfw ant glut is:
glfw is a lightwgeighted library, which also let you control the main loop
glut instead "owns" the main loop itself

3DPrgmer
08-29-2016, 11:20 AM
i wann display things like this:

http://i.imgur.com/ypggG9B.jpg

The old viewer is not very good, so i wanna make a new one using OpenGL to apply normal and spec maps, too. So i see it's better to switch to the new one...

how long does it take until i'm allowed to post links??

==EDIT==

I tried to understand the new tutorial, but there are still things i don't really understand.
1) What is the fragment shader good for?
2) Why do we first glEnableVertexAttribArray(0); and then glDisableVertexAttribArray(0); ?
3) What is glfwSwapBuffers(window); good for? Just noticed, that it doesn't work without.
4) glfwPollEvents(); this monitors the events i enabled before with glfwSetInputMode, right?
5) But I'm even more interest in the roll of VAO and VBO.

Cornix
08-29-2016, 02:07 PM
1) What is the fragment shader good for?
It is one part of a complete shader program. A shader program is at least a vertex and a fragment shader. The vertex shader is run once per vertex and the fragment shader is run once per fragment. A fragment is similar to a pixel but it does not have to be mapped 1:1. Within the fragment shader you define the color, depth, etc of each fragment. You can use the fragment shader to read the color for each fragment from a texture, you can mix several textures, compute the color value, apply lighting effects, etc.



2) Why do we first glEnableVertexAttribArray(0); and then glDisableVertexAttribArray(0); ?
Disabling the vertex attribute indices is not strictly needed at the end, its just good form. If you dont disable them after binding your VAO you might need to disable them later if you want to bind a different VAO. If you only have 1 (or all of them use the same vertex attribute indices) you dont need to ever disable them.



3) What is glfwSwapBuffers(window); good for? Just noticed, that it doesn't work without.
It flips the front and back buffers. Read up on double buffering if you want to know more.



4) glfwPollEvents(); this monitors the events i enabled before with glfwSetInputMode, right?
It polls events from the operating system. These can be input events (mouse, keyboard, joystick, etc), resizing of the window, or other kinds of events. This is not OpenGL but GLFW and you should find detailed information about all kinds of events in the GLFW documentation.



5) But I'm even more interest in the roll of VAO and VBO.
These are 2 different kinds of buffer objects. They store your (client) data on the server-side's memory (graphics card).
The Vertex-Buffer-Object (VBO) stores the raw rendering data like positions, colors, texture-coordinates, indices and many more. It can basically store whatever you want because you can use a custom shader to read from it.
The Vertex-Array-Object (VAO) stores management data about the raw rendering data. It will tell your shader program how to use the VBO's that you provide. You can read the OpenGL documentation to find out what kind of data is store within a VAO. All other data is stored either in a VBO or in uniforms / textures.

john_connor
08-29-2016, 02:29 PM
I tried to understand the new tutorial, but there are still things i don't really understand.
1) What is the fragment shader good for?
2) Why do we first glEnableVertexAttribArray(0); and then glDisableVertexAttribArray(0); ?
3) What is glfwSwapBuffers(window); good for? Just noticed, that it doesn't work without.
4) glfwPollEvents(); this monitors the events i enabled before with glfwSetInputMode, right?
5) But I'm even more interest in the roll of VAO and VBO.

1) the "data flow" goes like that:
-- you first put data points or "vertices" into a buffer object
-- then you make a vertex array object which describes how to interpret you data in that buffer
-- then you build your "program object" which consists (for now ..) of 1 vertex and 1 fragment shader
---- both are separate sub-programs which will process the data that streams through the "pipeline"
---- each vertex (data point) will be processed by the vertex shader, its task is (basically ..) to put the point to the correct screen position
---- after 3 vertices (for a triangle) are processed, openGL determines what pixels are covered by that triangle
---- each of those pixels will be processed by the fragment shader (which basically gives the pixel its color ..)
(fragment shader is also called pixel shader)

2) using your own "vertex array object", you only enable those attribures once (and dont disable them again .. regularly)

3) read about "double buffering": your window has actually 2 framebuffers, a "front" and "back" buffer
all your openGL calls will render into the back buffer
but only the front buffer is shown in your window
to make your rendered scene appear on screen, you "swap" both buffers

4) if you Xed out your window (or pressed ALT+F4) to close it, it will only happen after you've polled those events

5) read about it in the wiki (https://www.opengl.org/wiki/), read books, do tutorials ..
just for comparison: the old way you would have to call about 500.000 function calls to render the model i've linked above
the "modern" way you just put the points in a buffer / vertexarray, and call glDrawArrays(...)
the vertex shader will then get invoked about 150.000 times directly on the GPU (which processes the data mostly in parallel VERY FAST)

3DPrgmer
08-30-2016, 06:30 AM
All right thank you both :D

I'm at the matrices multiplication right now. This communication between my program and the shader program and who does what, is still driving me crazy. But maybe it's gonna become clearer when i continue with the tutorial and get some more vertices then the simple triangle :D

==EDIT==

Guys you are awesome!! I think i got it now :D I think my big problem is that i'm always tree steps ahead with my mind.

Just one question. You know i want to make that viewer. Would you use a static camera and move/rotate the object, or a static object and moving/rotating the camera? I think the better idea is to have a static camera but i'd like to know what you think about it

yentrangkorea
08-30-2016, 10:36 AM
maybe your image loader has a bug regarding the color channels, i would first try to use a suitable library:
https://www.opengl.org/wiki/Image_Libraries#SOIL
That was the problem I'm having right
Thank you so much

john_connor
08-30-2016, 02:59 PM
You know i want to make that viewer. Would you use a static camera and move/rotate the object, or a static object and moving/rotating the camera? I think the better idea is to have a static camera but i'd like to know what you think about it

i personally HATE a fixed camera which only looks steadily to the origin
my advice: make a dynamic camera

struct Camera {
vec3 Position{0, 0, 3};
quat Rotation{1, 0, 0, 0};
vec3 Velocity{0, 0, 0};
} camera;

when cursor scrolled up/down:
-- determine cameras forward direction
-- in/decrease velocity in forward direction

when cursor moved left/right:
-- rotate around cameras up direction

when key RETURN pressed:
-- camera.Velocity = vec3(0, 0, 0);

each frame:
-- camera.Position += camera.Velocity * timestep;// usually 0.016f

3DPrgmer
09-03-2016, 04:21 AM
Hi,

i'm back at my old new problem. The texture. It's not shown. The whole cube is black.

main.cpp


#define _CRT_SECURE_NO_WARNINGS
#ifndef _DEBUG
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
#endif // DEBUG

#include <GL/glew.h>
#include <glm/gtc/matrix_transform.hpp>

#include "setup.h"
#include "callback.h"

int main(int argc, char** argv)
{
oglVariables scene;

// init everything
setupGLFW();
scene.window = createWindow();
setupGLEW();
initVariables(scene);
glBindVertexArray(scene.vertexArrayID);

// Set callback functions
glfwSetMouseButtonCallback(scene.window, mouseButton);
glfwSetCursorPosCallback(scene.window, mouseMove);
glfwSetWindowSizeCallback(scene.window, windowResize);
glfwSetScrollCallback(scene.window, mouseWheel);
glfwSetKeyCallback(scene.window, keyPress);

// set background color 0,5 0,8 1,0
glClearColor(0.0000f, 0.0000f, 0.4000f, 0.0000f);

// enable z-order
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);

// load object to OGL
glBindBuffer(GL_ARRAY_BUFFER, scene.vertexBufferID);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(scene.object.data) * scene.object.data.size(),
scene.object.data.data(),
GL_STATIC_DRAW
);

// load color to OGL
/*glBindBuffer(GL_ARRAY_BUFFER, scene.colorBufferID);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(scene.object.color) * scene.object.color.size(),
scene.object.color.data(),
GL_STATIC_DRAW
);*/

// load UV to OGL
glBindBuffer(GL_ARRAY_BUFFER, scene.uvBufferID);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(scene.object.uv) * scene.object.uv.size(),
scene.object.uv.data(),
GL_STATIC_DRAW
);

// Main loop
do {
//processInteraction(scene.window);
calcMatrices(scene);

// clear the scene
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// use shader prgram
glUseProgram(scene.shaderPrgmID);

// tell shader transformation
glUniformMatrix4fv(scene.matrix.id, 1, GL_FALSE, &scene.matrix.mvp[0][0]);

// bind texture in texture unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, scene.object.textureID);
// tell sampler to use texture unit 0
glUniform1i(scene.samplerID, 0);

// open attribute position
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, scene.vertexBufferID);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

/* /* open attribute color
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, scene.colorBufferID);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);*/

// open attribute uv
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, scene.uvBufferID);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);

// draw object
glDrawArrays(GL_TRIANGLES, 0, 3*12);

// close attributes
glDisableVertexAttribArray(0);
//glDisableVertexAttribArray(1);
glDisableVertexAttribArray(1);

glfwSwapBuffers(scene.window);
glfwPollEvents();
}
while (!glfwWindowShouldClose(scene.window));

cleanUp(scene);

return 0;
}


setup.h


#pragma once
#include <gl/glfw3.h>
#include <Windows.h>
#include <vector>
#include "shader.h"
#include "import.h"
#include "texture.h"

#define OGL_MAJOR_VERSION 4
#define OGL_MINOR_VERSION 5
#define AA_VALUE 4
#define MAINWINDOW_NAME "MeshViewer 2.0 pre-alpha"
#define VERTEX_SHADER "VertexTextureShader.mv2shdr"
#define FRAGMENT_SHADER "FragmentTextureShader.mv2shdr"
#define TEXTURE_NAME "dice.tga"


struct oglVariables {
GLFWwindow* window; // window
GLuint vertexArrayID; // vertex array
GLuint vertexBufferID; // vertex buffer
GLuint colorBufferID; // color buffer
GLuint samplerID; // sampler handler
GLuint uvBufferID; // uv buffer
GLuint shaderPrgmID; // shader
struct {
GLuint id; // matrix ID
glm::mat4 projection; // projection
glm::mat4 view; // view
glm::mat4 model; // model
glm::mat4 mvp; // mvp
} matrix;
struct {
std::vector<GLfloat> data; // obj data
std::vector<GLfloat> color; // obj color
std::vector<GLfloat> uv; // obj uv
GLuint textureID; // texture data
} object;
};

struct {
float fov = 45.f;
float minView = 0.1f;
float maxView = 100.0f;
int witdh = 640;
int heigh = 480;
float rotX = 0;
float rotY = 0;
float rotZ = 0;
double transX = 0.0;
double transY = 0.0;
double transZ = 5.0;
} monitor;

void setupGLFW()
{
if (!glfwInit())
{
MessageBox(NULL, "Failed to initialize GLFW", "MeshViewer 2.0 Error", MB_OK | MB_ICONERROR);
exit(0);
}

glfwWindowHint(GLFW_SAMPLES, AA_VALUE); // antialiasing level
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, OGL_MAJOR_VERSION); // OpenGL major version number
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, OGL_MINOR_VERSION); // OpenGL minor verison number
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // something we need for new OGL
}

GLFWwindow* createWindow()
{
GLFWwindow* window = glfwCreateWindow(monitor.witdh, monitor.heigh, MAINWINDOW_NAME, NULL, NULL);

if (window == NULL)
{
char tempMajor[10], tempMinor[10];
_itoa_s(OGL_MAJOR_VERSION, tempMajor, 10, 10);
_itoa_s(OGL_MINOR_VERSION, tempMinor, 10, 10);

MessageBox(NULL,
(std::string("Your GPU does not support OpenGL ") += std::string(tempMajor) += std::string(".") += std::string(tempMinor)).c_str(),
"MeshViewer 2.0 Error", MB_OK | MB_ICONERROR);

glfwTerminate();
exit(0);
}

glfwMakeContextCurrent(window);

return window;
}

void setupGLEW()
{
glewExperimental = true;

if (glewInit() != GLEW_OK)
{
MessageBox(NULL, "Failed to initialize GLEW!", "MeshViewer 2.0 Error", MB_OK | MB_ICONERROR);
glfwTerminate();
exit(0);
}
}

void calcMatrices(oglVariables &scene)
{
scene.matrix.projection = glm::perspective(monitor.fov, float(monitor.witdh) / float(monitor.heigh), monitor.minView, monitor.maxView);
scene.matrix.view = glm::lookAt(
glm::vec3(monitor.transX, monitor.transY, monitor.transZ),
glm::vec3(monitor.transX, monitor.transY, monitor.transZ - 1),
glm::vec3(0, 1, 0)
);
scene.matrix.model = glm::mat4(1.0f);
scene.matrix.model = glm::rotate(scene.matrix.model, monitor.rotX, glm::vec3(1, 0, 0));
scene.matrix.model = glm::rotate(scene.matrix.model, monitor.rotY, glm::vec3(0, 1, 0));
scene.matrix.model = glm::rotate(scene.matrix.model, monitor.rotZ, glm::vec3(0, 0, 1));

scene.matrix.mvp = scene.matrix.projection * scene.matrix.view * scene.matrix.model;
}

void initVariables(oglVariables &temp)
{
glGenVertexArrays(1, &(temp.vertexArrayID));
glGenBuffers(1, &temp.vertexBufferID);
glGenBuffers(1, &temp.colorBufferID);
glGenBuffers(1, &temp.uvBufferID);
temp.shaderPrgmID = LoadShaders(VERTEX_SHADER, FRAGMENT_SHADER);

temp.matrix.id = glGetUniformLocation(temp.shaderPrgmID, "MVP");
calcMatrices(temp);

temp.samplerID = glGetUniformLocation(temp.shaderPrgmID, "textureSampler");

temp.object.data = loadData();
temp.object.color = loadColor();
temp.object.uv = loadUV();

glGenTextures(1, &temp.object.textureID);
glBindTexture(GL_TEXTURE_2D, temp.object.textureID);
TextureTGA tempTex(TEXTURE_NAME);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tempTex.getWidth(), tempTex.getHeight(), 0, GL_BGR, GL_UNSIGNED_BYTE, tempTex.getData().data());
}

void cleanUp(oglVariables &scene)
{
glDeleteBuffers(1, &scene.uvBufferID);
glDeleteBuffers(1, &scene.colorBufferID);
glDeleteBuffers(1, &scene.vertexBufferID);
glDeleteVertexArrays(1, &scene.vertexArrayID);
glDeleteProgram(scene.shaderPrgmID);
glDeleteTextures(1, &scene.samplerID);
glfwTerminate();
}


import.h


#pragma once
#include <vector>
#include <fstream>
#include <Windows.h>
#include <gl\glew.h>

std::vector<GLfloat> loadData()
{
return std::vector<GLfloat>(
{
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f
}
);
}

std::vector<GLfloat> loadColor()
{
return std::vector<GLfloat>(
{
0.583f, 0.771f, 0.014f,
0.609f, 0.115f, 0.436f,
0.327f, 0.483f, 0.844f,
0.822f, 0.569f, 0.201f,
0.435f, 0.602f, 0.223f,
0.310f, 0.747f, 0.185f,
0.597f, 0.770f, 0.761f,
0.559f, 0.436f, 0.730f,
0.359f, 0.583f, 0.152f,
0.483f, 0.596f, 0.789f,
0.559f, 0.861f, 0.639f,
0.195f, 0.548f, 0.859f,
0.014f, 0.184f, 0.576f,
0.771f, 0.328f, 0.970f,
0.406f, 0.615f, 0.116f,
0.676f, 0.977f, 0.133f,
0.971f, 0.572f, 0.833f,
0.140f, 0.616f, 0.489f,
0.997f, 0.513f, 0.064f,
0.945f, 0.719f, 0.592f,
0.543f, 0.021f, 0.978f,
0.279f, 0.317f, 0.505f,
0.167f, 0.620f, 0.077f,
0.347f, 0.857f, 0.137f,
0.055f, 0.953f, 0.042f,
0.714f, 0.505f, 0.345f,
0.783f, 0.290f, 0.734f,
0.722f, 0.645f, 0.174f,
0.302f, 0.455f, 0.848f,
0.225f, 0.587f, 0.040f,
0.517f, 0.713f, 0.338f,
0.053f, 0.959f, 0.120f,
0.393f, 0.621f, 0.362f,
0.673f, 0.211f, 0.457f,
0.820f, 0.883f, 0.371f,
0.982f, 0.099f, 0.879f
}
);
}

std::vector<GLfloat> loadUV()
{
return std::vector<float>(
{
0.000059f, 1.0f - 0.000004f,
0.000103f, 1.0f - 0.336048f,
0.335973f, 1.0f - 0.335903f,
1.000023f, 1.0f - 0.000013f,
0.667979f, 1.0f - 0.335851f,
0.999958f, 1.0f - 0.336064f,
0.667979f, 1.0f - 0.335851f,
0.336024f, 1.0f - 0.671877f,
0.667969f, 1.0f - 0.671889f,
1.000023f, 1.0f - 0.000013f,
0.668104f, 1.0f - 0.000013f,
0.667979f, 1.0f - 0.335851f,
0.000059f, 1.0f - 0.000004f,
0.335973f, 1.0f - 0.335903f,
0.336098f, 1.0f - 0.000071f,
0.667979f, 1.0f - 0.335851f,
0.335973f, 1.0f - 0.335903f,
0.336024f, 1.0f - 0.671877f,
1.000004f, 1.0f - 0.671847f,
0.999958f, 1.0f - 0.336064f,
0.667979f, 1.0f - 0.335851f,
0.668104f, 1.0f - 0.000013f,
0.335973f, 1.0f - 0.335903f,
0.667979f, 1.0f - 0.335851f,
0.335973f, 1.0f - 0.335903f,
0.668104f, 1.0f - 0.000013f,
0.336098f, 1.0f - 0.000071f,
0.000103f, 1.0f - 0.336048f,
0.000004f, 1.0f - 0.671870f,
0.336024f, 1.0f - 0.671877f,
0.000103f, 1.0f - 0.336048f,
0.336024f, 1.0f - 0.671877f,
0.335973f, 1.0f - 0.335903f,
0.667969f, 1.0f - 0.671889f,
1.000004f, 1.0f - 0.671847f,
0.667979f, 1.0f - 0.335851f
}
);
}


texture.cpp


#include "texture.h"
#include <iostream>
#include <fstream>
#include <Windows.h>

TextureTGA::TextureTGA(const char * filePath)
{
// open the file
std::fstream fsPicture(filePath, std::ios::in | std::ios::binary);

if (!fsPicture.is_open())
throw std::invalid_argument(std::string("file not found: ") += filePath);

// read in the header
std::uint8_t ui8x18Header[18] = { 0 };
fsPicture.read(reinterpret_cast<char*>(&ui8x18Header), sizeof(ui8x18Header));

// extract all information from header
ui32IDLength = ui8x18Header[0];
bColorTabel = ui8x18Header[1] == 1;
ui32PicType = ui8x18Header[2];
ui32PaletteBegin = ui8x18Header[4] * 0x100 + ui8x18Header[3];
ui32PaletteLength = ui8x18Header[6] * 0x100 + ui8x18Header[5];
ui32PaletteBpP = ui8x18Header[7];
ui32Width = ui8x18Header[13] * 0x100 + ui8x18Header[12];
ui32Height = ui8x18Header[15] * 0x100 + ui8x18Header[14];
ui32BpP = ui8x18Header[16];
ui32Attribut = ui8x18Header[17];

// calculate some more information
ui32Size = ui32Width * ui32Height * ui32BpP/8;
bCompressed = ui32PicType == 9 || ui32PicType == 10;
vui8Pixels.resize(ui32Size);

/* consol output of the header
std::cout << "Header\n"
<< "ID länge: " << ui32IDLength << std::endl
<< "Farbtabelle: " << (int)bColorTabel << std::endl
<< "Bildtype: " << ui32PicType << std::endl
<< "Palletenbegin: " << ui32PaletteBegin << std::endl
<< "Palletenlängen: " << ui32PaletteLength << std::endl
<< "Bits pro Palleteneintrag: " << ui32PaletteBpP << std::endl
<< "Breite: " << ui32Width << std::endl
<< "Höhe: " << ui32Height << std::endl
<< "Bit pro Pixel: " << ui32BpP << std::endl
<< "Bild Attribute: " << ui32Attribut << std::endl;*/

// jump to the data block
fsPicture.seekg(ui32IDLength + ui32PaletteLength, std::ios_base::cur);

// If not compressed 24 or 32 bit
if (ui32PicType == 2 && (ui32BpP == 24 || ui32BpP == 32))
{
fsPicture.read(reinterpret_cast<char*>(vui8Pixels.data()), ui32Size);
}
// else if compressed 24 or 32 bit
else if (ui32PicType == 10 && (ui32BpP == 24 || ui32BpP == 32)) // compressed
{
throw std::invalid_argument("Invaild File Format! Don't compress the image.");
}
// not useable format
else
{
fsPicture.close();
throw std::invalid_argument("Invaild File Format! Required 24 or 31 Bit Image.");
}


//fix color mix
std::uint8_t temp;
std::uint32_t it = 0;

while (it + 2 < ui32Size)
{
temp = vui8Pixels[it];
vui8Pixels[it] = vui8Pixels[it + 2];
vui8Pixels[it + 2] = temp;
ui32BpP == 32 ? it += 4 : it += 3;
}

fsPicture.close();
}

TextureTGA::~TextureTGA()
{
}

std::vector<std::uint8_t> TextureTGA::getData() const
{
return vui8Pixels;
}

bool TextureTGA::hasAlpha() const
{
return ui32BpP == 32;
}

std::uint32_t TextureTGA::getWidth() const
{
return ui32Width;
}

std::uint32_t TextureTGA::getHeight() const
{
return ui32Height;
}



fragment shader


#version 450 core

// Input
in vec2 UV;

// Ouput data
out vec3 color;

uniform sampler2D textureSampler;

void main()
{
color = texture(textureSampler, UV).rgb;
}


vertex shader


#version 450 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;

// Output
out vec2 UV;

// Values that stay constant for the whole mesh.
uniform mat4 MVP;

void main(){

// Output position of the vertex, in clip space : MVP * position
gl_Position = MVP * vec4(vertexPosition_modelspace,1);

UV = vertexUV;

}


The texture read should work. I checked the data values with different tga files and the values change. And with the old glut it worked, too. But my cube is completely solid black -.-