I am developing a Embree based ray tracer (currently very early in development). If you are not familiar with Embree you can read more at their webpage.
The issue:
Currently if you start the renderer to use 1 ray per pixel and per iteration (referred to 1 ray mode from now on), it renderers just fine. If you set it trace 4 rays in a packet (raypacket4) it renders the mesh fine, util you move some distace away from it, then some black lines appear.
Issue Screenshots
Screenshot camera parameters are (all in ray packet mode):
position 0, 1, 0, rotation 20, 0, 0
position 0, 38, 0 rotation 90, 0, 0
position 9.5, 5, 0 rotation 90, 0, 0
position 9.5, 38, 0 rotation 90, 0, 0
Investigation showed that the lines appear only in pakcet mode and when some distance away from mesh.
I am posting screens of the issue (rendered images) in several different camera positions.
Here is the source code of the project (on GitHub) Source Code
My bet is that the problem is in either the packet generation (found at camera.cpp/GetRayPacket4) or in the rendering (renderer.h/RenderBuffer4, Raytrace4).
Switching between the modes is done in main.cpp by just replacing RenderToBuffer4 with RenderToBuffer and RTC_INTERSECT4 to RTC_INTERSECT1.
Any help or ideas are much appreciated.
Edit:
I apologize for the lack of config files, or scene files, it is currently in very early dev stage( 2 days spent) and everything is hardcoded for testing at the moment.
Edit 2:
I have discovered that removid the + i in the ray direction calculation in GetRayPacket4, removes the issue, but then the 4 packed rays are identical. Why would that fix it ?
Solved.
The issue was that the __m128 keeps the data in reverse order, so some pixel swapping had to take place.
Related
How can I programmatically set the white balance of an uEye USB camera (from the IDS manufacturer) to work with no automatic white balance and pre-defined multipliers when is_SetWhiteBalanceMultipliers() function is obsolete?
Some background: I work with a uEye USB2 camera (from IDS) connected to Linux machine. I need to get an RGB image with pre-defined colors (of cause on a pre-defined scene) from the camera. For example, I want to configure the WB to red 1.25 multiplier, green 1.0, and blue 2.0 multiplier.
For this task, I am using the uEye SDK on Linux (header file ueye.h).
The manual (A: Camera basics > Camera parameters) states that the is_SetWhiteBalanceMultipliers() function is obsolete and suggests to use is_SetAutoParameter() function instead. It was easy to disable the auto-white balance (is_SetAutoParameter( hCam, IS_SET_ENABLE_AUTO_WHITEBALANCE, 0, 0), but I struggle to find a way to configure the red/green/blue multipliers. The parameter IS_SET_AUTO_WB_OFFSET and IS_SET_AUTO_WB_GAIN_RANGE work only when the automatic white balance engaged and do nothing when it is disabled. I will be grateful for any suggestions!
I had the same issue. I think you can achieve the old result using the function "is_SetHardwareGain" on which you directly pass the main, red, green and blue gains. In my case I disabled the white balance before doing it just to make sure it works. In this example, I wanted to set the values to RGB gains = [8%, 0%, 32%] and the master gain to 0% (to not confuse with gain factors 0% normally corresponds to 1x gain factor):
double param1, param2; param1=0;
is_SetColorCorrection (hCam, IS_CCOR_DISABLE, ¶m1); //Disables the color fitler correction matrix
flagIDS = is_SetAutoParameter (hCam, IS_SET_ENABLE_AUTO_WHITEBALANCE, ¶m1, ¶m2);
param1=WB_MODE_DISABLE;
flagIDS = is_SetAutoParameter (hCam, IS_SET_ENABLE_AUTO_SENSOR_WHITEBALANCE, ¶m1, ¶m2);
flagIDS = is_SetHardwareGain (hCam, 0, 8, 0, 32);
I'm learning from the example of osgpackeddepthstencil of OSG. This example first renders a mask square into a RTTI camera, affacting the stencil buffer while leaving the color buffer untouched. The stencil test is:
osg::Stencil *stencil = new osg::Stencil;
stencil->setFunction(osg::Stencil::ALWAYS, 1, ~0u);
stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::REPLACE);
osg::StateSet *ss = geode->getOrCreateStateSet();
ss->setAttributeAndModes(stencil, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
ss->setAttribute(new osg::ColorMask(false, false, false, false),osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
Then it renders a larger square into the same RTTI camera, setting the stencil test as not equal to 1. Then use the texture to render a square. The second stencil test codes are below:
osg::Stencil *stencil = new osg::Stencil;
stencil->setFunction(osg::Stencil::NOTEQUAL, 1, ~0u);
stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP);
osg::StateSet *ss = geode->getOrCreateStateSet();
ss->setAttributeAndModes(stencil, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
Everything goes fine, and the result is shown below. The clear color is green. The center of the square is green since the stencil buffer values are 1 in this small square due to the first round of rendering.
However, question comes when I change the second stencil test to be not equal to 0. According to my knowledge of stencil test, the result should be a reversed image of the previous one, which has a green boundary and a grey inner square. Quite confusing, the result is as follows which is a whole green:
What am I missing? How to interpret the second result? Any suggestions would be appreciated. Thanks! My OSG version is 3.4.0. My environment is : NVIDIA GTX 750 TI, Windows 10 64bit, Visual Studio 2013.
I'm trying to get the hang of moving objects (in general) and line strips (in particular) most efficiently in opengl and therefore I'm writing an application where multiple line segments are traveling with a constant speed from right to left. At every time point the left most point will be removed, the entire line will be shifted to the left, and a new point will be added at the very right of the line (this new data point is streamed / received / calculated on the fly, every 10ms or so). To illustrate what I mean, see this image:
Because I want to work with many objects, I decided to use vertex buffer objects in order to minimize the amount of gl* calls. My current code looks something like this:
A) setup initial vertices:
# calculate my_func(x) in range [0, n]
# (could also be random data)
data = my_func(0, n)
# create & bind buffer
vbo_id = GLuint()
glGenBuffers(1, vbo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id)
# allocate memory & transfer data to GPU
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW)
B) update vertices:
draw():
# get new data and update offset
data = my_func(n+dx, n+2*dx)
# update offset 'n' which is the current absolute value of x.
n = n + 2*dx
# upload data
glBindBuffer(GL_ARRAY_BUFFER, vbo_id)
glBufferSubData(GL_ARRAY_BUFFER, n, sizeof(data), data)
# translate scene so it looks like line strip has moved to the left.
glTranslatef(-local_shift, 0.0, 0.0)
# draw all points from offset
glVertexPointer(2, GL_FLOAT, 0, n)
glDrawArrays(GL_LINE_STRIP, 0, points_per_vbo)
where my_func would do something like this:
my_func(start_x, end_x):
# generate the correct x locations.
x_values = range(start_x, end_x, STEP_SIZE)
# generate the y values. We could be getting these values from a sensor.
y_values = []
for j in x_values:
y_values.append(random())
data = []
for i, j in zip(x_values, y_values):
data.extend([i, j])
return data
This works just fine, however if I have let's say 20 of those line strips that span the entire screen, then things slow down considerably.
Therefore my questions:
1) should I use glMapBuffer to bind the buffer on the GPU and fill the data directly (instead of using glBufferSubData)? Or will this make no difference performance wise?
2) should I use a shader for moving objects (here line strip) instead of calling glTranslatef? If so, how would such a shader look like? (I suspect that a shader is the wrong way to go, since my line strip is NOT a period function but rather contains random data).
3) what happens if the window get's resized? how do I keep aspect ratio and scale vertices accordingly? glViewport() only helps scaling in y direction, not in x direction. If the window is rescaled in x-direction, then in my current implementation I would have to recalculate the position of the entire line strip (calling my_func to get the new x coordinates) and upload it to the GPU. I guess this could be done more elegantly? How would I do that?
4) I noticed that when I use glTranslatef with a non integral value, the screen starts to flicker if the line strip consists of thousands of points. This is most probably because the fine resolution that I use to calculate the line strip does not match the pixel resolution of the screen and therefore sometimes some points appear in front and sometimes behind other points (this is particularly annoying when you don't render a sine wave but some 'random' data). How can I prevent this from happening (besides the obvious solution of translating by a integer multiple of 1 pixel)? If a window get re-sized from let's say originally 800x800 pixels to 100x100 pixels and I still want to visualize a line strip of 20 seconds, then shifting in x direction must work flicker free somehow with sub pixel precision, right?
5) as you can see I always call glTranslatef(-local_shift, 0.0, 0.0) - without ever doing the opposite. Therefore I keep shifting the entire view to the right. And that's why I need to keep track of the absolute x position (in order to place new data at the correct location). This problem will eventually lead to an artifact, where the line is overlapping with the edges of the window. I guess there must be a better way for doing this, right? Like keeping the x values fixed and just moving & updating the y values?
EDIT I've removed the sine wave example and replaced it with a better example. My question is generally about how to move line strips in space most efficiently (while adding new values to them). Therefore any suggestions like "precompute the values for t -> infinity" don't help here (I could also just be drawing the current temperature measured in front of my house).
EDIT2
Consider this toy example where after each time step, the first point is removed and a new one is added to the end:
t = 0
*
* * *
* **** *
1234567890
t = 1
*
* * * *
**** *
2345678901
t = 2
* *
* * *
**** *
3456789012
I don't think I can use a shader here, can I?
EDIT 3: example with two line strips.
EDIT 4: based on Tim's answer I'm using now the following code, which works nicely, but breaks the line into two (since I have two calls of glDrawArrays), see also the following two screenshots.
# calculate the difference
diff_first = x[1] - x[0]
''' first part of the line '''
# push the matrix
glPushMatrix()
move_to = -(diff_first * c)
print 'going to %d ' % (move_to)
glTranslatef(move_to, 0, 0)
# format of glVertexPointer: nbr points per vertex, data type, stride, byte offset
# calculate the offset into the Vertex
offset_bytes = c * BYTES_PER_POINT
stride = 0
glVertexPointer(2, GL_FLOAT, stride, offset_bytes)
# format of glDrawArrays: mode, Specifies the starting index in the enabled arrays, nbr of points
nbr_points_to_render = (nbr_points - c)
starting_point_in_above_selected_Vertex = 0
glDrawArrays(GL_POINTS, starting_point_in_above_selected_Vertex, nbr_points_to_render)
# pop the matrix
glPopMatrix()
''' second part of the line '''
# push the matrix
glPushMatrix()
move_to = (nbr_points - c) * diff_first
print 'moving to %d ' %(move_to)
glTranslatef(move_to, 0, 0)
# select the vertex
offset_bytes = 0
stride = 0
glVertexPointer(2, GL_FLOAT, stride, offset_bytes)
# draw the line
nbr_points_to_render = c
starting_point_in_above_selected_Vertex = 0
glDrawArrays(GL_POINTS, starting_point_in_above_selected_Vertex, nbr_points_to_render)
# pop the matrix
glPopMatrix()
# update counter
c += 1
if c == nbr_points:
c = 0
EDIT5 the resulting solution must obviously render one line across the screen - and no two lines that are missing a connection. The circular buffer solution by Tim provides a solution on how to move the plot, but I end up with two lines, instead of one.
Here's my thoughts to the revised question:
1) should I use glMapBuffer to bind the buffer on the GPU and fill the
data directly (instead of using glBufferSubData)? Or will this make no
difference performance wise?
I'm not aware that there is any significant performance between the two, though I would probably prefer glBufferSubData.
What I might suggest in your case is to create a VBO with N floats, and then use it similar to a circular buffer. Keep an index locally to where the 'end' of the buffer is, then every update replace the value under 'end' with the new value, and increment the pointer. This way you only have to update a single float each cycle.
Having done that, you can draw this buffer using 2x translates and 2x glDrawArrays/Elements:
Imagine that you've got an array of 10 elements, and the buffer end pointer is at element 4. Your array will contain the following 10 values, where x is a constant value, and f(n-d) is the random sample from d cycles ago:
0: (0, f(n-4) )
1: (1, f(n-3) )
2: (2, f(n-2) )
3: (3, f(n-1) )
4: (4, f(n) ) <-- end of buffer
5: (5, f(n-9) ) <-- start of buffer
6: (6, f(n-8) )
7: (7, f(n-7) )
8: (8, f(n-6) )
9: (9, f(n-5) )
To draw this (pseudo-guess code, might not be exactly correct):
glTranslatef( -end, 0, 0);
glDrawArrays( LINE_STRIP, end+1, (10-end)); //draw elems 5-9 shifted left by 4
glPopMatrix();
glTranslatef( end+1, 0, 0);
glDrawArrays(LINE_STRIP, 0, end); // draw elems 0-4 shifted right by 5
Then in the next cycle, replace the oldest value with the new random value,and shift the circular buffer pointer forward.
2) should I use a shader for moving objects (here line strip) instead
of calling glTranslatef? If so, how would such a shader look like? (I
suspect that a shader is the wrong way to go, since my line strip is
NOT a period function but rather contains random data).
Probably optional, if you use the method that I've described in #1. There's not a particular advantage to using one here.
3) what happens if the window get's resized? how do I keep aspect
ratio and scale vertices accordingly? glViewport() only helps scaling
in y direction, not in x direction. If the window is rescaled in
x-direction, then in my current implementation I would have to
recalculate the position of the entire line strip (calling my_func to
get the new x coordinates) and upload it to the GPU. I guess this
could be done more elegantly? How would I do that?
You shouldn't have to recalculate any data. Just define all your data in some fixed coordinate system that makes sense to you, and then use projection matrix to map this range to the window. Without more specifics its hard to answer.
4) I noticed that when I use glTranslatef with a non integral value,
the screen starts to flicker if the line strip consists of thousands
of points. This is most probably because the fine resolution that I
use to calculate the line strip does not match the pixel resolution of
the screen and therefore sometimes some points appear in front and
sometimes behind other points (this is particularly annoying when you
don't render a sine wave but some 'random' data). How can I prevent
this from happening (besides the obvious solution of translating by a
integer multiple of 1 pixel)? If a window get re-sized from let's say
originally 800x800 pixels to 100x100 pixels and I still want to
visualize a line strip of 20 seconds, then shifting in x direction
must work flicker free somehow with sub pixel precision, right?
Your assumption seems correct. I think the thing to do here would either to enable some kind of antialiasing (you can read other posts for how to do that), or make the lines wider.
There are a number of things that could be at work here.
glBindBuffer is one of the slowest OpenGL operations (along with similar call for shaders, textures, etc.)
glTranslate adjusts the modelview matrix, which the vertex unit multiplies all points by. So, it simply changes what matrix you multiply by. If you were to instead use a vertex shader, then you'd have to translate it for each vertex individually. In short: glTranslate is faster. In practice, this shouldn't matter too much, though.
If you're recalculating the sine function on a lot of points every time you draw, you're going to have performance issues (especially since, by looking at your source, it looks like you might be using Python).
You're updating your VBO every time you draw it, so it's not any faster than a vertex array. Vertex arrays are faster than intermediate mode (glVertex, etc.) but nowhere near as fast as display lists or static VBOs.
There could be coding errors or redundant calls somewhere.
My verdict:
You're calculating a sine wave and an offset on the CPU. I strongly suspect that most of your overhead comes from calculating and uploading different data every time you draw it. This is coupled with unnecessary OpenGL calls and possibly unnecessary local calls.
My recommendation:
This is an opportunity for the GPU to shine. Calculating function values on parallel data is (literally) what the GPU does best.
I suggest you make a display list representing your function, but set all the y-coordinates to 0 (so it's a series of points all along the line y=0). Then, draw this exact same display list once for every sine wave you want to draw. Ordinarily, this would just produce a flat graph, but, you write a vertex shader that transforms the points vertically into your sine wave. The shader takes a uniform for the sine wave's offset ("sin(x-offset)"), and just changes each vertex's y.
I estimate this will make your code at least ten times faster. Furthermore, because the vertices' x coordinates are all at integral points (the shader does the "translation" in the function's space by computing "sin(x-offset)"), you won't experience jittering when offsetting with floating point values.
You've got a lot here, so I'll cover what I can. Hopefully this will give you some areas to research.
1) should I use glMapBuffer to bind the buffer on the GPU and fill the data directly (instead of using glBufferSubData)? Or will this make no difference performance wise?
I would expect glBufferSubData to have better performance. If the data is stored on the GPU then mapping it will either
Copy the data back into host memory so you can modify it, and the copy it back when you unmap it.
or, give you a pointer to the GPU's memory directly which the CPU will access over PCI-Express. This isn't anywhere near as slow as it used to be to access GPU memory when we were on AGP or PCI, but it's still slower and not as well cached, etc, as host memory.
glSubBufferData will send the update of the buffer to the GPU and it will modify the buffer. No copying the back and fore. All data transferred in one burst. It should be able to do it as an asynchronous update of the buffer as well.
Once you get into "is this faster than that?" type comparisons you need to start measuring how long things take. A simple frame timer is normally sufficient (but report time per frame, not frames per second - it makes numbers easier to compare). If you go finer-grained than that, just be aware that because of the asynchronous nature of OpenGL, you often see time being consumed away from the call that caused the work. This is because after you give the GPU a load of work, it's only when you have to wait for it to finish something that you notice how long it's taking. That normally only happens when you're waiting for front/back buffers to swap.
2) should I use a shader for moving objects (here line strip) instead of calling glTranslatef? If so, how would such a shader look like?
No difference. glTranslate modifies a matrix (normally the Model-View) which is then applied to all vertices. If you have a shader you'd apply a translation matrix to all your vertices. In fact the driver is probably building a small shader for you already.
Be aware that the older APIs like glTranslate() are depreciated from OpenGL 3.0 onwards, and in modern OpenGL everything is done with shaders.
3) what happens if the window get's resized? how do I keep aspect ratio and scale vertices accordingly? glViewport() only helps scaling in y direction, not in x direction.
glViewport() sets the size and shape of the screen area that is rendered to. Quite often it's called on window resizing to set the viewport to the size and shape of the window. Doing just this will cause any image rendered by OpenGL to change aspect ratio with the window. To keep things looking the same you also have to control the projection matrix to counteract the effect of changing the viewport.
Something along the lines of:
glViewport(0,0, width, height);
glMatrixMode(GL_PROJECTION_MATRIX);
glLoadIdentity();
glScale2f(1.0f, width / height); // Keeps X scale the same, but scales Y to compensate for aspect ratio
That's written from memory, and I might not have the maths right, but hopefully you get the idea.
4) I noticed that when I use glTranslatef with a non integral value, the screen starts to flicker if the line strip consists of thousands of points.
I think you're seeing a form of aliasing which is due to the lines moving under the sampling grid of the pixels. There are various anti-aliasing techniques you can use to reduce the problem. OpenGL has anti-aliased lines (glEnable(GL_SMOOTH_LINE)), but a lot of consumer cards didn't support it, or only did it in software. You can try it, but you may get no effect or run very slowly.
Alternatively you can look into Multi-sample anti-aliasing (MSAA), or other types that your card may support through extensions.
Another option is rendering to a high resolution texture (via Frame Buffer Objects - FBOs) and then filtering it down when you render it to the screen as a textured quad. This would also allow you to do a trick where you move the rendered texture slightly to the left each time, and rendered the new strip on the right each frame.
1 1
1 1 1 Frame 1
11
1
1 1 1 Frame 1 is copied left, and a new line segment is added to make frame 2
11 2
1
1 1 3 Frame 2 is copied left, and a new line segment is added to make frame 3
11 2
It's not a simple change, but it might help you out with your problem (5).
Background:
I want to be able to take a 2d matrix (an image really), and a set of points defining a polygon, and draw that polygon into the matrix.
Before I run off and reinvent the wheel, I thought I'd ask if anyone knew of any existing libraries or code in Octave that does this. So far, my searches through the Octave packages and google have come up empty.
Failing in that, neither is too hard to implement, but I'm unsure how to draw a filled polygon. Is there an easy/efficient way to tell which points are inside a polygon and which are outside? Thanks.
Edit:
My purpose isn't displaying anything. Actually, what I'm specifically looking at doing is some image processing stuff, like plotting a convex hull, finding its area, finding the parts of the convex hull not in the original object, etc.
I don't see that Gnu Plot actually give me back any data I can work with. If I'm wrong, by all means tell me how. Thanks.
For finding points within a polygon, you can try Darren Engwirda's MATLAB function posted on MATLAB Central: http://www.mathworks.com/matlabcentral/fileexchange/10391
I looked briefly through the code and don't see anything that's particularly MATLAB specific, so it may run as-is in Octave.
EDIT: responding to the OP's edit up top to make it easier to find:
There are a variety of ways to make gnuplot render directly to a file (scroll down to "Terminal") which you can then read in for analysis. For example, you can output to portable bitmap format which is strikingly easy to read and write (if not small and elegant). Note that, by definition, PBM will give you an array of blacks and whites.
For example, check out this use of the "set terminal" and "set output" commands to render to a series of Unix pipes that produce a pbm and then a png file.
End EDIT:
Gnu Octave defaults to using gnuplot for plotting and it happens that gnuplot is quite good at producing filled polygons. Here are some helpful demonstrations of exactly that sort of thing. For example, here are some filled polygons:
# set terminal png transparent nocrop enhanced font arial 8 size 420,320
# set output 'fillcrvs.4.png'
set grid nopolar
set grid xtics nomxtics ytics nomytics noztics nomztics \
nox2tics nomx2tics noy2tics nomy2tics nocbtics nomcbtics
set grid front linetype 0 linewidth 1.000, linetype 0 linewidth 1.000
set key outside right top vertical Right noreverse enhanced autotitles nobox
set title "The red bat: abs(x) with filledcurve xy=2,5"
plot abs(x) with filledcurve xy=2,5
Here's another demonstration script that draws the crazy face at the bottom of the filled curves page:
# set terminal png transparent nocrop enhanced font arial 8 size 420,320
# set output 'fillcrvs.6.png'
unset border
set dummy t,y
set grid nopolar
set grid xtics nomxtics ytics nomytics noztics nomztics \
nox2tics nomx2tics noy2tics nomy2tics nocbtics nomcbtics
set grid layerdefault linetype 0 linewidth 1.000, linetype 0 linewidth 1.000
unset key
set label 1 "gnuplot" at 0, 1.2, 0 centre norotate front nopoint offset character 0, 0, 0
set label 2 "gnuplot" at 0.02, -0.6, 0 centre norotate front nopoint offset character 0, 0, 0
set arrow 1 from -0.1, 0.26, 0 to 0.18, -0.17, 0 head front nofilled linetype 5 linewidth 4.000 size first 0.100,40.000,90.000
set parametric
set size ratio 1 1,1
set noxtics
set noytics
set title "Let's smile with parametric filled curves"
set xrange [ -1.00000 : 1.00000 ] noreverse nowriteback
set yrange [ -1.00000 : 1.60000 ] noreverse nowriteback
plot [t=-pi:pi] sin(t),cos(t) with filledcurve xy=0,0 lt 15, sin(t)/8-0.5,cos(t)/8+0.4 with filledcurve lt 3, sin(t)/8+0.5,cos(t)/8+0.4 with filledcurve lt 3, t/5,abs(t/5)-0.8 with filledcurve xy=0.1,-0.5 lt 1, t/3,1.52-abs(t/pi) with filledcurve xy=0,1.8 lt -1
Update: This only seems to be a problem at some computers. The normal, intuitive code seems to work fine one my home computer, but the computer at work has trouble.
Home computer: (no problems)
Windows XP Professional SP3
AMD Athlon 64 X2 3800+ Dual Core 2.0 GHz
NVIDIA GeForce 7800 GT
2 GB RAM
Work computer: (this question applies to this computer)
Windows XP Professional SP3
Intel Pentium 4 2.8 Ghz (dual core, I think)
Intel 82945G Express Chipset Family
1 GB RAM
Original post:
I'm trying to apply a very simple texture to a part of the screen using Psychtoolbox in Matlab with the following code:
win = Screen('OpenWindow', 0, 127); % open window and obtain window pointer
tex = Screen('MakeTexture', win, [255 0;0 255]); % get texture pointer
% draw texture. Args: command, window pointer, texture pointer, source
% (i.e. the entire 2x2 matrix), destination (a 100x100 square), rotation
% (none) and filtering (nearest neighbour)
Screen('DrawTexture', win, tex, [0 0 2 2], [100 100 200 200], 0, 0);
Screen('Flip', win); % flip the buffer so the texture is drawn
KbWait; % wait for keystroke
Screen('Close', win); % close screen
Now I would expect to see this (four equally sized squares):
But instead I get this (right and bottom sides are cut off and top left square is too large):
Obviously the destination rectangle is a lot bigger than the source rectangle, so the texture needs to be magnified. I would expect this to happen symmetrically like in the first picture and this is also what I need. Why is this not happening and what can I do about it?
I have also tried using [128 0 1152 1024] as a destination rectangle (as it's the square in the center of my screen). In this case, all sides are 1024, which makes each involved rectangle a power of 2. This does not help.
Increasing the size of the checkerboard results in a similar situation where the right- and bottommost sides are not showed correctly.
Like I said, I use Psychtoolbox, but I know that it uses OpenGL under the hood. I don't know much about OpenGL either, but maybe someone who does can help without knowing Matlab. I don't know.
Thanks for your time!
While I don't know much (read: any) Matlab, I do know that textures are very picky in openGL. Last I checked, openGL requires texture files to be square and of a power of two (i.e. 128 x 128, 256 x 256, 512 x 512).
If they aren't, openGL is supposed to pad the file with appropriate white pixels where they're needed to meet this condition, although it could be a crapshoot depending on which system you are running it on.
I suggest making sure that your checkerboard texture fits these requirements.
Also, I can't quite make sure from your code posted, but openGL expects you to map the corners of your texture to the corners of the object you are intending to texture.
Another bit of advice, maybe try a linear filter instead of nearest neighbor. It's heavier computationally, but results in a better image. This probably won't matter in the end.
While this help is not Matlab specific, hope it is useful.
Without knowing a lot about the Psychtoolbox, but having dealt with graphics and user interfaces a lot in MATLAB, the first thing I would try would be to fiddle with the fourth input to Screen (the "source" input). Try shifting each corner by half-pixel and whole-pixel values. For example, the first thing I would try would be:
Screen('DrawTexture', win, tex, [0 0 2.5 2.5], [100 100 200 200], 0, 0);
And if that didn't seem to do anything, I would next try:
Screen('DrawTexture', win, tex, [0 0 3 3], [100 100 200 200], 0, 0);
My reasoning for this advice: I've noticed sometimes that images or GUI controls in my figures can appear to be off by a pixel, which I can only speculate is some kind of round-off error when scaling or positioning them.
That's the best advice I can give. Hope it helps!