I've successfully got some triangles to show up on screen together with some textures and a couple of event listeners. However, my texture is not rendering properly, it seems like pixels between 0 and 255 in brightness gets disorted while completely black/white pixels are rendering as they should. <- This might not be the best description but I will provide an example below.
This is the texture I'm trying to map onto my two triangles at the moment:
Here is the result after compiling and running the program:
What I think is that it may have something to do with the shaders, at the moment I do not have any shaders activated, neither vertex nor fragment shaders. I don't know if this is the problem but it might be a clue to it all.
Below is my main.cpp:
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysymdef.h>
#include <GL/glx.h>
#include <GL/gl.h>
// #include <GL/glut.h>
// #include <GL/glu.h>
#include <sys/time.h>
#include <unistd.h>
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 800
#define FPS 30
uint8_t shutdown = 0;
#define SKIP_TICKS ( 1000 / FPS )
// macros
void Render( void );
void HandleEvents( XEvent ev );
void Resize( int w, int h );
void Shutdown( void );
void fill_triangle_buffer( void );
struct triangle {
float color[ 3 ];
float p1[ 3 ];
float p2[ 3 ];
float p3[ 3 ];
};
struct triangle triangles[ 12 ];
static double GetMilliseconds() {
static timeval s_tTimeVal;
gettimeofday(&s_tTimeVal, NULL);
double time = s_tTimeVal.tv_sec * 1000.0; // sec to ms
time += s_tTimeVal.tv_usec / 1000.0; // us to ms
return time;
}
GLuint loadBMP_custom( const char * imagepath ) {
// Data read from the header of the BMP file
unsigned char header[54]; // Each BMP file begins by a 54-bytes header
unsigned int dataPos; // Position in the file where the actual data begins
unsigned int width, height;
unsigned int imageSize; // = width*height*3
// Actual RGB data
unsigned char * data;
// Open the file
FILE * file = fopen(imagepath,"rb");
if (!file) {
printf("Image could not be opened\n");
return 0;
}
if ( fread(header, 1, 54, file)!=54 ){ // If not 54 bytes read : problem
printf("Not a correct BMP file\n");
return false;
}
if ( header[0]!='B' || header[1]!='M' ){
printf("Not a correct BMP file\n");
return 0;
}
// Read ints from the byte array
dataPos = *(int*)&(header[0x0A]);
imageSize = *(int*)&(header[0x22]);
width = *(int*)&(header[0x12]);
height = *(int*)&(header[0x16]);
// Some BMP files are misformatted, guess missing information
if (imageSize==0)
imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component
if (dataPos==0)
dataPos=54; // The BMP header is done that way
// Create a buffer
data = new unsigned char [imageSize];
// Read the actual data from the file into the buffer
fread(data,1,imageSize,file);
//Everything is in memory now, the file can be closed
fclose(file);
// Create one OpenGL texture
GLuint textureID;
glGenTextures(1, &textureID);
// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, textureID);
// Give the image to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// return GLuint
return textureID;
}
int main (int argc, char ** argv){
Display *dpy = XOpenDisplay(0);
Window win;
XEvent ev;
int nelements;
GLXFBConfig *fbc = glXChooseFBConfig(dpy, DefaultScreen(dpy), 0, &nelements);
static int attributeList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None };
XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy),attributeList);
// Set Window attributes
XSetWindowAttributes swa;
swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;
win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
// Select window inputs to be triggered in the eventlistener
XSelectInput( dpy, win, PointerMotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask );
XMapWindow (dpy, win);
//oldstyle context:
// GLXContext ctx = glXCreateContext(dpy, vi, 0, GL_TRUE);
std::cout << "glXCreateContextAttribsARB " << (void*) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB") << std::endl;
GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
int attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
0};
// Redirect Close
Atom atomWmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
XSetWMProtocols(dpy, win, &atomWmDeleteWindow, 1);
// Create GLX OpenGL context
GLXContext ctx = glXCreateContextAttribsARB(dpy, *fbc, 0, true, attribs);
glXMakeCurrent( dpy, win, ctx );
glMatrixMode( GL_PROJECTION );
glEnable( GL_CULL_FACE );
glCullFace( GL_FRONT );
glFrustum( -1, 1, 1, -1, -1, 1 );
glClearColor (0, 0.5, 1, 1);
glClear (GL_COLOR_BUFFER_BIT);
glXSwapBuffers (dpy, win);
fill_triangle_buffer();
// Load and bind texture
glEnable(GL_TEXTURE_2D);
loadBMP_custom("textures/texture.bmp");
// prepare gameloop
double prevTime = GetMilliseconds();
double currentTime = GetMilliseconds();
double deltaTime = 0.0;
timeval time;
long sleepTime = 0;
gettimeofday(&time, NULL);
long nextGameTick = (time.tv_sec * 1000) + (time.tv_usec / 1000);
while ( shutdown != 1 ) {
// Get events if there is any
if (XPending(dpy) > 0) {
XNextEvent(dpy, &ev);
if (ev.type == Expose) {
XWindowAttributes attribs;
XGetWindowAttributes(dpy, win, &attribs);
Resize(attribs.width, attribs.height);
}
if (ev.type == ClientMessage) {
if (ev.xclient.data.l[0] == atomWmDeleteWindow) {
break;
}
}
else if (ev.type == DestroyNotify) {
break;
}
}
// Framelimit calculations, before heavy load
currentTime = GetMilliseconds();
deltaTime = double( currentTime - prevTime ) * 0.001;
prevTime = currentTime;
// Do work
HandleEvents( ev );
//Render();
glClear( GL_COLOR_BUFFER_BIT );
glBegin(GL_TRIANGLES);
glColor3f( 255, 255, 255 );
/*
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -0.5f, 0.5f, 0.0f );
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 0.5f, 0.5f, 0.0f );
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -0.5f, -0.5f, 0.0f );
glVertex3f( 0.5f, 0.5f, 0.0f );
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 0.5f, -0.5f, 0.0f );
glVertex3f( -0.5f, -0.5f, 0.0f );
*/
// first triangle, bottom left half
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -0.5f, -0.5f, 0 );
glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -0.5f, 0.5f, 0 );
glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 0.5f, -0.5f, 0 );
// second triangle, top right half
glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 0.5f, -0.5f, 0 );
glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -0.5f, 0.5f, 0 );
glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 0.5f, 0.5f, 0 );
glEnd();
glFlush();
glXSwapBuffers( dpy, win );
// Limit Framerate
gettimeofday( &time, NULL );
nextGameTick += SKIP_TICKS;
sleepTime = nextGameTick - ( (time.tv_sec * 1000) + (time.tv_usec / 1000) );
usleep((unsigned int)(sleepTime/1000));
}
ctx = glXGetCurrentContext();
glXDestroyContext(dpy, ctx);
}
void fill_triangle_buffer( void ){
triangles[ 0 ] = {
{ 1.0f, 0.0f, 0.0f },
{ -0.5f, -0.5f, -0.5f },
{ 0.5f, 0.5f, -0.5f },
{ 0.5f, -0.5f, -0.5f } };
triangles[ 1 ] = {
{ 0.0f, 0.0f, 1.0f },
{ -0.5f, -0.5f, -0.5f },
{ -0.5f, 0.5f, -0.5f },
{ 0.5f, 0.5f, -0.5f } };
triangles[ 2 ] = {
{ 0.0f, 0.0f, 1.0f },
{ 0.5f, 0.5f, -0.5f },
{ 0.5f, -0.5f, 0.5f },
{ 0.5f, -0.5f, -0.5f } };
triangles[ 3 ] = {
{ 1.0f, 1.0f, 0.0f },
{ 0.5f, 0.5f, -0.5f },
{ 0.5f, 0.5f, 0.5f },
{ 0.5f, -0.5f, 0.5f } };
triangles[ 4 ] = {
{ 1.0f, 0.0f, 0.0f },
{ -0.5f, -0.5f, 0.5f },
{ 0.5f, -0.5f, 0.5f },
{ -0.5f, 0.5f, 0.5f } };
triangles[ 5 ] = {
{ 0.0f, 0.0f, 1.0f },
{ 0.5f, -0.5f, 0.5f },
{ 0.5f, 0.5f, 0.5f },
{ -0.5f, 0.5f, 0.5f } };
triangles[ 6 ] = {
{ 0.0f, 0.0f, 1.0f },
{ -0.5f, 0.5f, -0.5f },
{ -0.5f, -0.5f, 0.5f },
{ -0.5f, 0.5f, 0.5f } };
triangles[ 7 ] = {
{ 1.0f, 1.0f, 0.0f },
{ -0.5f, 0.5f, -0.5f },
{ -0.5f, -0.5f, -0.5f },
{ -0.5f, -0.5f, 0.5f } };
triangles[ 8 ] = {
{ 1.0f, 0.0f, 0.0f },
{ -0.5f, 0.5f, -0.5f },
{ -0.5f, 0.5f, 0.5f },
{ 0.5f, 0.5f, 0.5f } };
triangles[ 9 ] = {
{ 0.0f, 0.0f, 1.0f },
{ -0.5f, 0.5f, -0.5f },
{ 0.5f, 0.5f, 0.5f },
{ 0.5f, 0.5f, -0.5f } };
triangles[ 10 ] = {
{ 0.0f, 0.0f, 1.0f },
{ 0.5f, -0.5f, -0.5f },
{ 0.5f, -0.5f, 0.5f },
{ -0.5f, -0.5f, 0.5f } };
triangles[ 11 ] = {
{ 1.0f, 1.0f, 0.0f },
{ 0.5f, -0.5f, -0.5f },
{ -0.5f, -0.5f, 0.5f },
{ -0.5f, -0.5f, -0.5f } };
}
void Resize(int w, int h) {
glViewport(0, 0, w, h);
}
void Shutdown() {
shutdown = 1;
}
void Render( void ) {
glClearColor ( 1.0f, 1.0f, 1.0f, 1 );
glClear( GL_COLOR_BUFFER_BIT );
glBegin(GL_TRIANGLES);
/*glColor3f( 0.0f, 1.0f, 0.0f );
glVertex3f( test_cnt, 0.0f, 1.0f );
glVertex3f( 1.0f, 0.0f, 1.0f );
glVertex3f( 0.0f, -1.0f, 1.0f );
*/
int numTriangles = sizeof(triangles)/sizeof(triangles[0]);
for ( int i = 0; i < numTriangles; i++ ) {
glClear( GL_COLOR_BUFFER_BIT );
glBegin(GL_TRIANGLES);
struct triangle tr = triangles[ i ];
glColor3f( tr.color[ 0 ], tr.color[ 1 ], tr.color[ 2 ] );
glVertex3f( tr.p1[ 0 ], tr.p1[ 1 ], tr.p1[ 2 ] );
glVertex3f( tr.p2[ 0 ], tr.p2[ 1 ], tr.p2[ 2 ] );
glVertex3f( tr.p3[ 0 ], tr.p3[ 1 ], tr.p3[ 2 ] );
}
glEnd();
glFlush();
}
float dx, dy;
float prevx, prevy;
uint8_t prev_defined = 0;
uint8_t key_down = 0;
void HandleEvents( XEvent ev ) {
int x, y;
switch ( ev.type ) {
case ButtonPress:
if ( ev.xbutton.button == 1 ) {
std::cout << "Left mouse down \n";
// glRotatef( 0.01, 0.0, 0.0, 1.0 );
if ( key_down == 0 )
prev_defined = 0;
key_down = 1;
}
break;
case ButtonRelease:
if ( ev.xbutton.button == 1 ) {
std::cout << "Left mouse up \n";
key_down = 0;
}
break;
case KeyPress:
if ( ev.xkey.keycode == 9 ) { // ESC
Shutdown();
}
break;
case MotionNotify:
x = ev.xmotion.x;
y = ev.xmotion.y;
if ( key_down == 0 )
break;
if ( !prev_defined ) {
prevx = x;
prevy = y;
prev_defined = 1;
break;
}
dx = x - prevx;
dy = y - prevy;
prevx = x;
prevy = y;
glRotatef( -dy/10, 1.0f, 0.0f, 0.0f );
glRotatef( -dx/10, 0.0f, 1.0f, 0.0f );
//std::cout << "Mouse X:" << x << ", Y: " << y << "\n";
break;
}
}
I compile with:
g++ -g -Wall -o _build/main main.cpp -I/opt/x11/include -L/usr/x11/lib -lglfw -lGLEW -lGL -lX11
OS:
Linux kali 5.9.0-kali4-amd64 #1 SMP Debian 5.9.11-1kali1 (2020-12-01) x86_64 GNU/Linux
Do anyone know how to resolve this issue in order to completely show above texture on my triangles?
Related
I am trying to run some code that should render multiple cubes using matrix transformations to translate one cubes coordinates to other locations. However im pretty sure the matricies arent working because all that renders is the original cube without being transformed.
I had a look online at what the problem could be and found that I should initialize my matricies as identity matricies initially which I have already done yet I still see no affect. Here is my code:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "GLCALL.h"
#include <stb_image.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <shader.h>
#include <iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "CurrentProject1", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (glewInit() != GLEW_OK)
std::cout << "error not goeerrd\n";
GLCall(glEnable(GL_DEPTH_TEST));
float vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f };
glm::vec3 cubePositions[] = { glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(2.0f, 5.0f, -15.0f),
glm::vec3(-1.5f, -2.2f, -2.5f),
glm::vec3(-3.8f, -2.0f, -12.3f),
glm::vec3(2.4f, -0.4f, -3.5f),
glm::vec3(-1.7f, 3.0f, -7.5f),
glm::vec3(1.3f, -2.0f, -2.5f),
glm::vec3(1.5f, 2.0f, -2.5f),
glm::vec3(1.5f, 0.2f, -1.5f),
glm::vec3(-1.3f, 1.0f, -1.5f) };
unsigned int VBO, VAO;
GLCall(glGenVertexArrays(1, &VAO));
GLCall(glGenBuffers(1, &VBO));
GLCall(glBindVertexArray(VAO));
GLCall(glBindBuffer(GL_ARRAY_BUFFER, VBO));
GLCall(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));
GLCall(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0));
GLCall(glEnableVertexAttribArray(0));
GLCall(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))));
GLCall(glEnableVertexAttribArray(1));
GLCall(unsigned int s_ID = glCreateProgram());
GLCall(unsigned int vs_ID = glCreateShader(GL_VERTEX_SHADER));
GLCall(unsigned int fs_ID = glCreateShader(GL_FRAGMENT_SHADER));
const std::string vs_string = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"\n"
"void main()\n"
"{\n"
"gl_Position = projection * view * model * vec4(position, 1.0f);\n"
"}\n";
const std::string fs_string = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f)\n;"
"}\n";
const char* vs_char = vs_string.c_str();
const char* fs_char = fs_string.c_str();
std::cout << *vs_char;
GLCall(glShaderSource(vs_ID, 1, &vs_char, NULL));
GLCall(glShaderSource(fs_ID, 1, &fs_char, NULL));
GLCall(glCompileShader(vs_ID));
int result;
GLCall(glGetShaderiv(vs_ID, GL_COMPILE_STATUS, &result));
if (result == GL_FALSE)
{
int length;
GLCall(glGetShaderiv(vs_ID, GL_INFO_LOG_LENGTH, &length));
char * message = (char*)alloca(length * sizeof(char));
GLCall(glGetShaderInfoLog(vs_ID, length, &length, message));
std::cout << "failed to compile vertexing shader" << std::endl;
std::cout << message << std::endl;
GLCall(glDeleteShader(vs_ID));
}
GLCall(glCompileShader(fs_ID));
int result1;
GLCall(glGetShaderiv(fs_ID, GL_COMPILE_STATUS, &result1));
if (result1 == GL_FALSE)
{
int length1;
GLCall(glGetShaderiv(fs_ID, GL_INFO_LOG_LENGTH, &length1));
char * message = (char*)alloca(length1 * sizeof(char));
GLCall(glGetShaderInfoLog(fs_ID, length1, &length1, message));
std::cout << "failed to compile fragmenting shader" << std::endl;
std::cout << message << std::endl;
GLCall(glDeleteShader(fs_ID));
}
GLCall((s_ID, vs_ID));
GLCall(glAttachShader(s_ID, fs_ID));
GLCall(glLinkProgram(s_ID));
GLCall(glDeleteShader(vs_ID));
GLCall(glDeleteShader(fs_ID));
GLCall(glUseProgram(s_ID));
while (!glfwWindowShouldClose(window))
{
processInput(window);
GLCall(glClearColor(0.2f, 0.3f, 0.3f, 1.0f));
GLCall(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);
projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
const std::string temp1 = "projection";
const std::string temp2 = "view";
const std::string temp3 = "model";
GLCall(glUniformMatrix4fv(glGetUniformLocation(s_ID, temp1.c_str()), 1, GL_FALSE, &projection[0][0]));
GLCall(glUniformMatrix4fv(glGetUniformLocation(s_ID, temp2.c_str()), 1, GL_FALSE, &view[0][0]));
GLCall(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE));
GLCall(glBindVertexArray(VAO));
for (unsigned int i = 0; i < 10; i++)
{
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, cubePositions[i]);
float angle = 20.0f * i;
model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
GLCall(glUniformMatrix4fv(glGetUniformLocation(s_ID, temp3.c_str()), 1, GL_FALSE, &model[0][0]));
GLCall(glDrawArrays(GL_TRIANGLES, 0, 36));
}
glfwSwapBuffers(window);
glfwPollEvents();
}
GLCall(glDeleteVertexArrays(1, &VAO));
GLCall(glDeleteBuffers(1, &VBO));
glfwTerminate();
return 0;
}
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
GLCall(glViewport(0, 0, width, height));
}
I expect multiple cubes to render in different positions in a perspective projection however instead I see what would be seen if the matrix hadn't been included at all, just a single cube with the coordinates of the original cube. What could be stopping the matricies from working?
Kinda weird you only have a single glAttachShader() call.
I can see multiple cubes with GLM 0.9.9.2 and a known-good shader loader:
Code:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <iostream>
#include <cstdarg>
struct Program
{
static GLuint Load( const char* shader, ... )
{
GLuint prog = glCreateProgram();
va_list args;
va_start( args, shader );
while( shader )
{
const GLenum type = va_arg( args, GLenum );
AttachShader( prog, type, shader );
shader = va_arg( args, const char* );
}
va_end( args );
glLinkProgram( prog );
CheckStatus( prog );
return prog;
}
private:
static void CheckStatus( GLuint obj )
{
GLint status = GL_FALSE;
if( glIsShader( obj ) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
if( glIsProgram( obj ) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
if( status == GL_TRUE ) return;
GLchar log[ 1 << 15 ] = { 0 };
if( glIsShader( obj ) ) glGetShaderInfoLog( obj, sizeof( log ), NULL, log );
if( glIsProgram( obj ) ) glGetProgramInfoLog( obj, sizeof( log ), NULL, log );
std::cerr << log << std::endl;
std::exit( EXIT_FAILURE );
}
static void AttachShader( GLuint program, GLenum type, const char* src )
{
GLuint shader = glCreateShader( type );
glShaderSource( shader, 1, &src, NULL );
glCompileShader( shader );
CheckStatus( shader );
glAttachShader( program, shader );
glDeleteShader( shader );
}
};
const char* vert = 1 + R"GLSL(
#version 330 core
layout (location = 0) in vec3 position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
};
)GLSL";
const char* frag = 1 + R"GLSL(
#version 330 core
out vec4 color;
void main()
{
color = vec4(1.0f, 0.5f, 0.2f, 1.0f);
};
)GLSL";
void framebuffer_size_callback( GLFWwindow* window, int width, int height );
void processInput( GLFWwindow *window );
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
int main()
{
glfwInit();
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
GLFWwindow* window = glfwCreateWindow( SCR_WIDTH, SCR_HEIGHT, "CurrentProject1", NULL, NULL );
if( window == NULL )
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent( window );
glfwSetFramebufferSizeCallback( window, framebuffer_size_callback );
if( glewInit() != GLEW_OK )
std::cout << "error not goeerrd\n";
glEnable( GL_DEPTH_TEST );
float vertices[] =
{
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
};
glm::vec3 cubePositions[] =
{
glm::vec3( 0.0f, 0.0f, 0.0f ),
glm::vec3( 2.0f, 5.0f, -15.0f ),
glm::vec3( -1.5f, -2.2f, -2.5f ),
glm::vec3( -3.8f, -2.0f, -12.3f ),
glm::vec3( 2.4f, -0.4f, -3.5f ),
glm::vec3( -1.7f, 3.0f, -7.5f ),
glm::vec3( 1.3f, -2.0f, -2.5f ),
glm::vec3( 1.5f, 2.0f, -2.5f ),
glm::vec3( 1.5f, 0.2f, -1.5f ),
glm::vec3( -1.3f, 1.0f, -1.5f ),
};
unsigned int VBO, VAO;
glGenVertexArrays( 1, &VAO );
glGenBuffers( 1, &VBO );
glBindVertexArray( VAO );
glBindBuffer( GL_ARRAY_BUFFER, VBO );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof( float ), (void*)0 );
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof( float ), (void*)( 3 * sizeof( float ) ) );
glEnableVertexAttribArray( 1 );
GLuint s_ID = Program::Load( vert, GL_VERTEX_SHADER, frag, GL_FRAGMENT_SHADER, NULL );
glUseProgram( s_ID );
while( !glfwWindowShouldClose( window ) )
{
processInput( window );
glClearColor( 0.2f, 0.3f, 0.3f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glm::mat4 view = glm::mat4( 1.0f );
glm::mat4 projection = glm::mat4( 1.0f );
projection = glm::perspective( glm::radians( 45.0f ), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f );
view = glm::translate( view, glm::vec3( 0.0f, 0.0f, -3.0f ) );
const std::string temp1 = "projection";
const std::string temp2 = "view";
const std::string temp3 = "model";
glUniformMatrix4fv( glGetUniformLocation( s_ID, temp1.c_str() ), 1, GL_FALSE, &projection[ 0 ][ 0 ] );
glUniformMatrix4fv( glGetUniformLocation( s_ID, temp2.c_str() ), 1, GL_FALSE, &view[ 0 ][ 0 ] );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glBindVertexArray( VAO );
for( unsigned int i = 0; i < 10; i++ )
{
glm::mat4 model = glm::mat4( 1.0f );
model = glm::translate( model, cubePositions[ i ] );
float angle = 20.0f * i;
model = glm::rotate( model, glm::radians( angle ), glm::vec3( 1.0f, 0.3f, 0.5f ) );
glUniformMatrix4fv( glGetUniformLocation( s_ID, temp3.c_str() ), 1, GL_FALSE, &model[ 0 ][ 0 ] );
glDrawArrays( GL_TRIANGLES, 0, 36 );
}
glfwSwapBuffers( window );
glfwPollEvents();
}
glDeleteVertexArrays( 1, &VAO );
glDeleteBuffers( 1, &VBO );
glfwTerminate();
return 0;
}
void processInput( GLFWwindow *window )
{
if( glfwGetKey( window, GLFW_KEY_ESCAPE ) == GLFW_PRESS )
glfwSetWindowShouldClose( window, true );
}
void framebuffer_size_callback( GLFWwindow* window, int width, int height )
{
glViewport( 0, 0, width, height );
}
I have an issue updating the old matrix with the new one, as I am transitioning from WebGL to OpenGL, it started to get daunting when I wanted to translate the object with keys actions, the issue is that when I want to do the new translation, the new matrix should be updated and the data supplied to the vertex shader(uniform u_matrix) should be changed too, but it doesn't.
To showcase the problem, I made it simpler, I'm drawing once with a translation matrix and after sleep(2), I'm drawing once again but with a different translation matrix and sleep another 2 seconds to see the result, the problem is that the matrix is not updated at all at the second phase and there is no change at all.
The matC.translate(nb1, nb2, nb2) works well by returning a pointer to the first value of 16' value 1D array stored on stack.
#include <GL/glew.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <assert.h>
#include <unistd.h>
#include "./../Matrix/main.cpp";
using namespace std;
GLuint prog_hdlr;
GLint a_position;
const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 1024;
// float * translation = matC.translation(0.2, 0, 0);
// float * rotationX;
// float * rotationY;
// float * rotationZ;
// float translate = 0.01;
// float * tab4 = matC.multiplyMatrices(tab1, tab2);
static unsigned int CompileShader(unsigned int type, const string& source) {
unsigned int id = glCreateShader(type);
cout << source.c_str() << endl;
const char * src = source.c_str();
glShaderSource(id, 1, &src, NULL);
glCompileShader(id);
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if(result == GL_FALSE) {
std::cout << "failed to compile shader" << std::endl;
GLint maxLength = 0;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength);
vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(id, maxLength, &maxLength, &errorLog[0]);
int iter;
for (vector<GLchar>::const_iterator iter = errorLog.begin(); iter != errorLog.end(); ++iter)
cout << *iter;
glDeleteShader(id);
}
return id;
}
static int CreateProgram(const string& vertexShader, const string& fragmentShader) {
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDetachShader(program,vs);
glDetachShader(program,fs);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
void input(GLFWwindow * window, int key, int action, int u, int i) {
// switch(key) {
// case GLFW_KEY_W : {
// translate += 0.1;
// translation = matC.translation(translate, 0, 0);
// };
// case GLFW_KEY_A : {
// };
// case GLFW_KEY_S : {
// translate -= 0.1;
// translation = matC.translation(translate, 0, 0);
// };
// case GLFW_KEY_D : {
// };
// };
}
int main(int argc, char * argv) {
glutInit(&argc, &argv);
GLFWwindow * window;
cout << glGetString(GL_VERSION) << endl;
if(!glfwInit())
return -1;
window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Triangle rendering", NULL, NULL);
if(!window) {
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if(glewInit() != GLEW_OK) {
std::cout << "error..!!" << std::endl;
}
float positions[108] = {
-0.5f, -0.5f, 0.0f, 0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, -1.0f, -0.5f, 0.5f, -1.0f, 0.5f, 0.5f, -1.0f,
0.5f, 0.5f, -1.0f, 0.5f, -0.5f, -1.0f, -0.5f, -0.5f, -1.0f,
-0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, -0.5f, 0.5f, -1.0f,
-0.5f, 0.5f, -1.0f, -0.5f, -0.5f, -1.0f, -0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f, 0.5f, 0.5f, -1.0f, 0.5f, 0.5f, 0.0f,
0.5f, 0.5f, -1.0f, 0.5f, -0.5f, 0.0f, 0.5f, -0.5f, -1.0f,
-0.5f, 0.5f, 0.0f, 0.5f, 0.5f, -1.0f, -0.5f, 0.5f, -1.0f,
0.5f, 0.5f, -1.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 1.0f,
-0.5f, -0.5f, 0.0f, -0.5f, -0.5f, -1.0f, 0.5f, -0.5f, -1.0f,
0.5f, -0.5f, -1.0f, 0.5f, -0.5f, 1.0f, -0.5f, -0.5f, 0.0f
};
float colors[108] = {
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
};
string vertexShader = R"(
#version 130
attribute vec4 a_position;
attribute vec3 a_color;
varying vec3 v_color;
uniform mat4 u_matrix;
void main() {
mat4 a_matrix;
a_matrix = mat4(1.0f);
vec4 pos = u_matrix*a_position;
gl_Position = vec4(pos.xyz, 1.0);
v_color = a_color;
}
)";
string fragmentShader = R"(
#version 130
varying vec3 v_color;
void main() {
gl_FragColor = vec4(v_color, 1.0);
}
)";
unsigned int program = CreateProgram(vertexShader, fragmentShader);
glUseProgram(program);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
GLint attributePositionLocation = glGetAttribLocation(program, "a_position");
GLint uniformMatrixLocation = glGetUniformLocation(program, "u_matrix");
GLint attributeColorLocation = glGetAttribLocation(program, "a_color");
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 108*sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(attributePositionLocation);
glVertexAttribPointer(attributePositionLocation, 3, GL_FLOAT, GL_FALSE, 0, NULL);
unsigned int bufferColor;
glGenBuffers(1, &bufferColor);
glBindBuffer(GL_ARRAY_BUFFER, bufferColor);
glBufferData(GL_ARRAY_BUFFER, 108*sizeof(float), colors, GL_STATIC_DRAW);
glEnableVertexAttribArray(attributeColorLocation);
glVertexAttribPointer(attributeColorLocation, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glfwSetKeyCallback(window, input);
// while(!glfwWindowShouldClose(window)) {
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glUniformMatrix4fv(uniformMatrixLocation, 1, GL_FALSE, translation);
// glDrawArrays(GL_TRIANGLES, 0, 36);
// glfwSwapBuffers(window);
// glfwPollEvents();
// }
Matrix matC = Matrix();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(uniformMatrixLocation, 1, GL_FALSE, matC.translation(0.5, 0.5, 0));
glDrawArrays(GL_TRIANGLES, 0, 36);
glfwSwapBuffers(window);
glfwPollEvents();
sleep(2);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(uniformMatrixLocation, 1, GL_FALSE, matC.translation(-0.5, -0.5, 0));
glDrawArrays(GL_TRIANGLES, 0, 36);
glfwSwapBuffers(window);
glfwPollEvents();
sleep(2);
glfwTerminate();
return 0;
}
In WebGL it works perfectly:
function drawScene(gl) {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.uniformMatrix4fv(whateverMatrixLocation, false, whateverMatrix);
gl.drawArrays(gl.TRIANGLES, 0, whateverNumber);
requestAnimationFrame(drawScene.bind(this, gl));
}
What I am doing wrong? I'm using GLSL version 1.3...?
EDIT:
class Matrix {
public:
Matrix() {};
static float * translation(float x, float y, float z) {
static float tab[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, z, 1
};
return tab;
}
}
The static initializer only runs once, not each time through the function. You can switch to std::array & assign new values each time through:
class Matrix
{
public:
float* translation( float x, float y, float z )
{
static std::array< float, 16 > tab;
tab =
{
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, z, 1
};
return tab.data();
}
};
Or use GLM :)
I am having a bit of an issue where i want to make a triangle list display 2 triangles. I am not sure what I have done wrong but it only displays the first triangle and not the second.
Please help
static const Vertex s_vertexData[6]
{
{ { 0.0f, 0.5f, 0.5f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // Top / Red
{ { 0.5f, -0.5f, 0.5f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // Right / Green
{ { -0.5f, -0.5f, 0.5f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // Left / Blue
{ { 1.0f, 0.5f, 0.5f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // Top / Red
{ { 1.5f, -0.5f, 0.5f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // Right / Green
{ { 0.5f, -0.5f, 0.5f },{ 1.0f, 0.0f, 0.0f, 1.0f } } // Left / Blue
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( Vertex ) * 4;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = s_vertexData;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
if( FAILED( hr ) )
return hr;
// Set vertex buffer
UINT stride = sizeof( Vertex);
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );
// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
I cannot get Depth testing working with GLFW using codeblocks in any project, even using the default template provided by codeblocks when you start a new project, as below.
Any help is much appreciated as I know I must be doing something wrong but I haven't been able to find it.
#include <GL/glfw.h>
int main()
{
int width, height;
int frame = 0;
bool running = true;
glfwInit();
if( !glfwOpenWindow( 512, 512, 0, 0, 0, 0, 0, 0, GLFW_WINDOW ) )
{
glfwTerminate();
return 0;
}
glfwSetWindowTitle("GLFW Application");
glEnable(GL_DEPTH_TEST);
while(running)
{
frame++;
glfwGetWindowSize( &width, &height );
height = height > 0 ? height : 1;
glViewport( 0, 0, width, height );
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 65.0f, (GLfloat)width/(GLfloat)height, 1.0f, 100.0f );
// Draw some rotating garbage
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt(0.0f, -10.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f );
//glTranslatef( 1.0f, 1.0f, 0.0f );
glRotatef(frame, 0.25f, 1.0f, 0.75f);
glBegin( GL_TRIANGLES );
glColor3f(0.1f, 0.0f, 0.0f );
glVertex3f(0.0f, 3.0f, -4.0f);
glColor3f(0.0f, 1.0f, 0.0f );
glVertex3f(3.0f, -2.0f, -4.0f);
glColor3f(0.0f, 0.0f, 1.0f );
glVertex3f(-3.0f, -2.0f, -4.0f);
glEnd();
glBegin( GL_TRIANGLES );
glColor3f(0.0f, 0.1f, 0.0f );
glVertex3f(0.0f, 3.0f, -3.0f);
glColor3f(0.0f, 0.0f, 1.0f );
glVertex3f(3.0f, -2.0f, -2.0f);
glColor3f(1.0f, 0.0f, 0.0f );
glVertex3f(-3.0f, -2.0f, 2.0f);
glEnd();
glfwSwapBuffers();
// exit if ESC was pressed or window was closed
running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam( GLFW_OPENED);
}
glfwTerminate();
return 0;
}
From the GLFW2 documentation (emphasis mine):
int glfwOpenWindow
(
int width, int height,
int redbits, int greenbits, int bluebits,
int alphabits,
int depthbits,
int stencilbits,
int mode
)
depthbits: The number of bits to use for the depth buffer (0 means no depth buffer).
And your code:
glfwOpenWindow( 512, 512, 0, 0, 0, 0, 0, 0, GLFW_WINDOW )
^ no depth bits
You can't (usefully) use the depth buffer without any depth bits.
I am creating a game that will have 2d pictures inside a 3d world.
I originally started off by not caring about my images been stretched to a square while I learnt more about how game mechanics work... but it's now time to get my textures to display in the correct ratio and... size.
Just a side note, I have played with orthographic left hand projections but I noticed that you cannot do 3d in that... (I guess that makes sense... but I could be wrong, I tried it and when I rotated my image, it went all stretchy and weirdosss).
the nature of my game is as follows:
In the image it says -1.0 to 1.0... i'm not fussed if the coordinates are:
topleft = 0,0,0
bottom right = 1920, 1200, 0
But if that's the solution, then whatever... (p.s the game is not currently set up so that -1.0 and 1.0 is left and right of screen. infact i'm not sure how i'm going to make the screen edges the boundaries (but that's a question for another day)
Question:
The issue I am having is that my image for my player (2d) is 128 x 64 pixels. After world matrix multiplication (I think that's what it is) the vertices I put in scale my texture hugely... which makes sense but it looks butt ugly and I don't want to just whack a massive scaling matrix into the mix because it'll be difficult to work out how to make the texture 1:1 to my screen pixels (although maybe you will tell me it's actually how you do it but you need to do a clever formula to work out what the scaling should be).
But basically, I want the vertices to hold a 1:1 pixel size of my image, unstretched...
So I assume I need to convert my world coords to screen coords before outputting my textures and vertices??? I'm not sure how it works...
Anyways, here are my vertices.. you may notice what I've done:
struct VERTEX
{
float X, Y, Z;
//float R, G, B, A;
float NX, NY, NZ;
float U, V; // texture coordinates
};
const unsigned short SquareVertices::indices[ 6 ] = {
0, 1, 2, // side 1
2, 1, 3
};
const VERTEX SquareVertices::vertices[ 4 ] = {
//{ -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 1
//{ 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
//{ -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
//{ 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }
{ -64.0f, -32.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 1
{ 64.0f, -32.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
{ -64.0f, 32.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
{ 64.0f, 64.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }
};
(128 pixels / 2 = 64 ), ( 64 / 2 = 32 ) because the centre is 0.0... but what do I need to do to projections, world transdoobifications and what nots to get the worlds to screens?
My current setups look like this:
// called 1st
void Game::SetUpViewTransformations( )
{
XMVECTOR vecCamPosition = XMVectorSet( 0.0f, 0.0f, -20.0f, 0 );
XMVECTOR vecCamLookAt = XMVectorSet( 0, 0, 0, 0 );
XMVECTOR vecCamUp = XMVectorSet( 0, 1, 0, 0 );
matView = XMMatrixLookAtLH( vecCamPosition, vecCamLookAt, vecCamUp );
}
// called 2nd
void Game::SetUpMatProjection( )
{
matProjection = XMMatrixPerspectiveFovLH(
XMConvertToRadians( 45 ), // the field of view
windowWidth / windowHeight, // aspect ratio
1, // the near view-plane
100 ); // the far view-plan
}
and here is a sneaky look at my update and render methods:
// called 3rd
void Game::Update( )
{
world->Update();
worldRotation = XMMatrixRotationY( world->rotation );
player->Update( );
XMMATRIX matTranslate = XMMatrixTranslation( player->x, player->y, 0.0f );
//XMMATRIX matTranslate = XMMatrixTranslation( 0.0f, 0.0f, 1.0f );
matWorld[ 0 ] = matTranslate;
}
// called 4th
void Game::Render( )
{
// set our new render target object as the active render target
d3dDeviceContext->OMSetRenderTargets( 1, rendertarget.GetAddressOf( ), zbuffer.Get( ) );
// clear the back buffer to a deep blue
float color[ 4 ] = { 0.0f, 0.2f, 0.4f, 1.0f };
d3dDeviceContext->ClearRenderTargetView( rendertarget.Get( ), color );
d3dDeviceContext->ClearDepthStencilView( zbuffer.Get( ), D3D11_CLEAR_DEPTH, 1.0f, 0 ); // clear the depth buffer
CBUFFER cBuffer;
cBuffer.DiffuseVector = XMVectorSet( 0.0f, 0.0f, 1.0f, 0.0f );
cBuffer.DiffuseColor = XMVectorSet( 0.5f, 0.5f, 0.5f, 1.0f );
cBuffer.AmbientColor = XMVectorSet( 0.2f, 0.2f, 0.2f, 1.0f );
//cBuffer.Final = worldRotation * matWorld[ 0 ] * matView * matProjection;
cBuffer.Final = worldRotation * matWorld[ 0 ] * matView * matProjection;
cBuffer.Rotation = XMMatrixRotationY( world->rotation );
// calculate the view transformation
SetUpViewTransformations();
SetUpMatProjection( );
//matFinal[ 0 ] = matWorld[0] * matView * matProjection;
UINT stride = sizeof( VERTEX );
UINT offset = 0;
d3dDeviceContext->PSSetShaderResources( 0, 1, player->texture.GetAddressOf( ) ); // Set up texture
d3dDeviceContext->IASetVertexBuffers( 0, 1, player->vertexbuffer.GetAddressOf( ), &stride, &offset ); // Set up vertex buffer
d3dDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); // How the vertices be drawn
d3dDeviceContext->IASetIndexBuffer( player->indexbuffer.Get( ), DXGI_FORMAT_R16_UINT, 0 ); // Set up index buffer
d3dDeviceContext->UpdateSubresource( constantbuffer.Get( ), 0, 0, &cBuffer, 0, 0 ); // set the new values for the constant buffer
d3dDeviceContext->OMSetBlendState( blendstate.Get( ), 0, 0xffffffff ); // DONT FORGET IF YOU DISABLE THIS AND YOU WANT COLOUR, * BY Color.a!!!
d3dDeviceContext->DrawIndexed( ARRAYSIZE( player->indices ), 0, 0 ); // draw
swapchain->Present( 1, 0 );
}
Just to clarify, if I make my vertices use 2 and 1 respective of the fact my image is 128 x 64.. I get a normal looking size image.. and yet at 0,0,0 it's not at 1:1 size... wadduuuppp buddyyyy
{ -2.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 1
{ 2.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
{ -2.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
{ 2.0f, 2.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }
Desired outcome 2 teh max:
Cool picture isn't it :D ?
Comment help:
I'm not familliar with direct-x but as far as I can see the thing with your image that is screen coordinates are [-1...+1] on x and y. So total length on both axis equals 2 and your image is scaled times 2. Try consider this scale in camera matrix.